summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore')
-rw-r--r--JavaScriptCore/API/APICast.h23
-rw-r--r--JavaScriptCore/API/JSBase.cpp12
-rw-r--r--JavaScriptCore/API/JSCallbackConstructor.cpp2
-rw-r--r--JavaScriptCore/API/JSCallbackConstructor.h6
-rw-r--r--JavaScriptCore/API/JSCallbackFunction.cpp4
-rw-r--r--JavaScriptCore/API/JSCallbackFunction.h6
-rw-r--r--JavaScriptCore/API/JSCallbackObject.cpp2
-rw-r--r--JavaScriptCore/API/JSCallbackObject.h21
-rw-r--r--JavaScriptCore/API/JSCallbackObjectFunctions.h39
-rw-r--r--JavaScriptCore/API/JSClassRef.cpp4
-rw-r--r--JavaScriptCore/API/JSClassRef.h4
-rw-r--r--JavaScriptCore/API/JSContextRef.cpp30
-rw-r--r--JavaScriptCore/API/JSContextRef.h7
-rw-r--r--JavaScriptCore/API/JSObjectRef.cpp18
-rw-r--r--JavaScriptCore/API/JSStringRef.cpp3
-rw-r--r--JavaScriptCore/API/JSStringRefCF.cpp6
-rw-r--r--JavaScriptCore/API/JSValueRef.cpp84
-rw-r--r--JavaScriptCore/API/OpaqueJSString.cpp4
-rw-r--r--JavaScriptCore/API/OpaqueJSString.h2
-rw-r--r--JavaScriptCore/API/WebKitAvailability.h4
-rw-r--r--JavaScriptCore/AllInOneFile.cpp29
-rw-r--r--JavaScriptCore/Android.mk92
-rw-r--r--JavaScriptCore/ChangeLog13536
-rw-r--r--JavaScriptCore/Configurations/Base.xcconfig7
-rw-r--r--JavaScriptCore/Configurations/DebugRelease.xcconfig4
-rw-r--r--JavaScriptCore/Configurations/JavaScriptCore.xcconfig9
-rw-r--r--JavaScriptCore/Configurations/Version.xcconfig2
-rw-r--r--JavaScriptCore/DerivedSources.make32
-rw-r--r--JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSLock.h1
-rw-r--r--JavaScriptCore/GNUmakefile.am381
-rw-r--r--JavaScriptCore/Info.plist2
-rw-r--r--JavaScriptCore/JavaScriptCore.exp124
-rw-r--r--JavaScriptCore/JavaScriptCore.order3126
-rw-r--r--JavaScriptCore/JavaScriptCore.pri117
-rw-r--r--JavaScriptCore/JavaScriptCore.pro3
-rw-r--r--JavaScriptCore/JavaScriptCore.scons307
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj320
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj62
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj8
-rw-r--r--JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj851
-rw-r--r--JavaScriptCore/JavaScriptCoreSources.bkl63
-rw-r--r--JavaScriptCore/SConstruct1
-rw-r--r--JavaScriptCore/VM/CTI.cpp3532
-rw-r--r--JavaScriptCore/VM/CTI.h475
-rw-r--r--JavaScriptCore/VM/CodeBlock.cpp1184
-rw-r--r--JavaScriptCore/VM/CodeBlock.h399
-rw-r--r--JavaScriptCore/VM/Machine.h374
-rw-r--r--JavaScriptCore/VM/Opcode.h219
-rw-r--r--JavaScriptCore/assembler/AssemblerBuffer.h160
-rw-r--r--JavaScriptCore/assembler/MacroAssembler.h2019
-rw-r--r--JavaScriptCore/assembler/X86Assembler.h1704
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.cpp1686
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.h584
-rw-r--r--JavaScriptCore/bytecode/EvalCodeCache.h87
-rw-r--r--JavaScriptCore/bytecode/Instruction.h155
-rw-r--r--JavaScriptCore/bytecode/JumpTable.cpp (renamed from JavaScriptCore/VM/Instruction.h)53
-rw-r--r--JavaScriptCore/bytecode/JumpTable.h102
-rw-r--r--JavaScriptCore/bytecode/Opcode.cpp (renamed from JavaScriptCore/VM/Opcode.cpp)2
-rw-r--r--JavaScriptCore/bytecode/Opcode.h231
-rw-r--r--JavaScriptCore/bytecode/SamplingTool.cpp (renamed from JavaScriptCore/VM/SamplingTool.cpp)30
-rw-r--r--JavaScriptCore/bytecode/SamplingTool.h (renamed from JavaScriptCore/VM/SamplingTool.h)14
-rw-r--r--JavaScriptCore/bytecode/StructureStubInfo.cpp80
-rw-r--r--JavaScriptCore/bytecode/StructureStubInfo.h156
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (renamed from JavaScriptCore/VM/CodeGenerator.cpp)622
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.h (renamed from JavaScriptCore/VM/CodeGenerator.h)151
-rw-r--r--JavaScriptCore/bytecompiler/Label.h (renamed from JavaScriptCore/VM/LabelID.h)44
-rw-r--r--JavaScriptCore/bytecompiler/LabelScope.h (renamed from JavaScriptCore/kjs/LabelScope.h)25
-rw-r--r--JavaScriptCore/bytecompiler/RegisterID.h (renamed from JavaScriptCore/VM/RegisterID.h)2
-rw-r--r--JavaScriptCore/bytecompiler/SegmentedVector.h (renamed from JavaScriptCore/VM/SegmentedVector.h)0
-rw-r--r--JavaScriptCore/config.h (renamed from JavaScriptCore/kjs/config.h)8
-rwxr-xr-xJavaScriptCore/create_hash_table (renamed from JavaScriptCore/kjs/create_hash_table)66
-rw-r--r--JavaScriptCore/debugger/Debugger.cpp16
-rw-r--r--JavaScriptCore/debugger/Debugger.h6
-rw-r--r--JavaScriptCore/debugger/DebuggerActivation.cpp103
-rw-r--r--JavaScriptCore/debugger/DebuggerActivation.h63
-rw-r--r--JavaScriptCore/debugger/DebuggerCallFrame.cpp7
-rw-r--r--JavaScriptCore/debugger/DebuggerCallFrame.h10
-rwxr-xr-xJavaScriptCore/docs/make-bytecode-docs.pl4
-rw-r--r--JavaScriptCore/interpreter/CallFrame.cpp (renamed from JavaScriptCore/runtime/ExecState.cpp)6
-rw-r--r--JavaScriptCore/interpreter/CallFrame.h (renamed from JavaScriptCore/runtime/ExecState.h)27
-rw-r--r--JavaScriptCore/interpreter/Interpreter.cpp (renamed from JavaScriptCore/VM/Machine.cpp)4106
-rw-r--r--JavaScriptCore/interpreter/Interpreter.h389
-rw-r--r--JavaScriptCore/interpreter/Register.h (renamed from JavaScriptCore/VM/Register.h)32
-rw-r--r--JavaScriptCore/interpreter/RegisterFile.cpp (renamed from JavaScriptCore/VM/RegisterFile.cpp)3
-rw-r--r--JavaScriptCore/interpreter/RegisterFile.h (renamed from JavaScriptCore/VM/RegisterFile.h)47
-rw-r--r--JavaScriptCore/jit/ExecutableAllocator.cpp38
-rw-r--r--JavaScriptCore/jit/ExecutableAllocator.h179
-rw-r--r--JavaScriptCore/jit/ExecutableAllocatorPosix.cpp56
-rw-r--r--JavaScriptCore/jit/ExecutableAllocatorWin.cpp56
-rw-r--r--JavaScriptCore/jit/JIT.cpp1944
-rw-r--r--JavaScriptCore/jit/JIT.h577
-rw-r--r--JavaScriptCore/jit/JITArithmetic.cpp974
-rw-r--r--JavaScriptCore/jit/JITCall.cpp345
-rw-r--r--JavaScriptCore/jit/JITInlineMethods.h434
-rw-r--r--JavaScriptCore/jit/JITPropertyAccess.cpp704
-rw-r--r--JavaScriptCore/jsc.cpp (renamed from JavaScriptCore/kjs/Shell.cpp)146
-rw-r--r--JavaScriptCore/jsc.pro (renamed from JavaScriptCore/kjs/jsc.pro)26
-rw-r--r--JavaScriptCore/jscore.bkl30
-rw-r--r--JavaScriptCore/kjs/interpreter.h68
-rw-r--r--JavaScriptCore/kjs/nodes2string.cpp936
-rw-r--r--JavaScriptCore/kjs/operations.h137
-rw-r--r--JavaScriptCore/kjs/protect.h154
-rwxr-xr-xJavaScriptCore/make-generated-sources.sh2
-rw-r--r--JavaScriptCore/masm/X86Assembler.h1262
-rw-r--r--JavaScriptCore/parser/Grammar.y (renamed from JavaScriptCore/kjs/grammar.y)649
-rw-r--r--JavaScriptCore/parser/Keywords.table (renamed from JavaScriptCore/kjs/keywords.table)0
-rw-r--r--JavaScriptCore/parser/Lexer.cpp (renamed from JavaScriptCore/kjs/lexer.cpp)80
-rw-r--r--JavaScriptCore/parser/Lexer.h (renamed from JavaScriptCore/kjs/lexer.h)29
-rw-r--r--JavaScriptCore/parser/NodeInfo.h (renamed from JavaScriptCore/kjs/NodeInfo.h)2
-rw-r--r--JavaScriptCore/parser/Nodes.cpp (renamed from JavaScriptCore/kjs/nodes.cpp)1464
-rw-r--r--JavaScriptCore/parser/Nodes.h (renamed from JavaScriptCore/kjs/nodes.h)997
-rw-r--r--JavaScriptCore/parser/Parser.cpp (renamed from JavaScriptCore/kjs/Parser.cpp)37
-rw-r--r--JavaScriptCore/parser/Parser.h (renamed from JavaScriptCore/kjs/Parser.h)30
-rw-r--r--JavaScriptCore/parser/ResultType.h (renamed from JavaScriptCore/kjs/ResultType.h)76
-rw-r--r--JavaScriptCore/parser/SourceCode.h (renamed from JavaScriptCore/kjs/SourceCode.h)1
-rw-r--r--JavaScriptCore/parser/SourceProvider.h (renamed from JavaScriptCore/kjs/SourceProvider.h)2
-rwxr-xr-xJavaScriptCore/pcre/dftables4
-rw-r--r--JavaScriptCore/pcre/pcre.pri2
-rw-r--r--JavaScriptCore/pcre/pcre_compile.cpp59
-rw-r--r--JavaScriptCore/pcre/pcre_exec.cpp22
-rw-r--r--JavaScriptCore/pcre/pcre_internal.h26
-rw-r--r--JavaScriptCore/pcre/pcre_tables.cpp10
-rw-r--r--JavaScriptCore/pcre/pcre_ucp_searchfuncs.cpp4
-rw-r--r--JavaScriptCore/pcre/pcre_xclass.cpp8
-rw-r--r--JavaScriptCore/profiler/CallIdentifier.h2
-rw-r--r--JavaScriptCore/profiler/Profile.h2
-rw-r--r--JavaScriptCore/profiler/ProfileGenerator.cpp10
-rw-r--r--JavaScriptCore/profiler/Profiler.cpp12
-rw-r--r--JavaScriptCore/profiler/Profiler.h7
-rw-r--r--JavaScriptCore/runtime/ArgList.cpp2
-rw-r--r--JavaScriptCore/runtime/ArgList.h6
-rw-r--r--JavaScriptCore/runtime/Arguments.cpp12
-rw-r--r--JavaScriptCore/runtime/Arguments.h26
-rw-r--r--JavaScriptCore/runtime/ArrayConstructor.cpp12
-rw-r--r--JavaScriptCore/runtime/ArrayConstructor.h2
-rw-r--r--JavaScriptCore/runtime/ArrayPrototype.cpp329
-rw-r--r--JavaScriptCore/runtime/ArrayPrototype.h4
-rw-r--r--JavaScriptCore/runtime/BatchedTransitionOptimizer.h6
-rw-r--r--JavaScriptCore/runtime/BooleanConstructor.cpp10
-rw-r--r--JavaScriptCore/runtime/BooleanConstructor.h4
-rw-r--r--JavaScriptCore/runtime/BooleanObject.cpp2
-rw-r--r--JavaScriptCore/runtime/BooleanObject.h6
-rw-r--r--JavaScriptCore/runtime/BooleanPrototype.cpp16
-rw-r--r--JavaScriptCore/runtime/BooleanPrototype.h2
-rw-r--r--JavaScriptCore/runtime/CallData.cpp2
-rw-r--r--JavaScriptCore/runtime/CallData.h7
-rw-r--r--JavaScriptCore/runtime/ClassInfo.h2
-rw-r--r--JavaScriptCore/runtime/Collector.cpp (renamed from JavaScriptCore/kjs/collector.cpp)143
-rw-r--r--JavaScriptCore/runtime/Collector.h (renamed from JavaScriptCore/kjs/collector.h)26
-rw-r--r--JavaScriptCore/runtime/CollectorHeapIterator.h9
-rw-r--r--JavaScriptCore/runtime/CommonIdentifiers.h2
-rw-r--r--JavaScriptCore/runtime/Completion.cpp (renamed from JavaScriptCore/kjs/interpreter.cpp)19
-rw-r--r--JavaScriptCore/runtime/Completion.h (renamed from JavaScriptCore/kjs/completion.h)23
-rw-r--r--JavaScriptCore/runtime/ConstructData.cpp2
-rw-r--r--JavaScriptCore/runtime/ConstructData.h5
-rw-r--r--JavaScriptCore/runtime/DateConstructor.cpp84
-rw-r--r--JavaScriptCore/runtime/DateConstructor.h2
-rw-r--r--JavaScriptCore/runtime/DateInstance.cpp2
-rw-r--r--JavaScriptCore/runtime/DateInstance.h8
-rw-r--r--JavaScriptCore/runtime/DateMath.cpp173
-rw-r--r--JavaScriptCore/runtime/DateMath.h4
-rw-r--r--JavaScriptCore/runtime/DatePrototype.cpp386
-rw-r--r--JavaScriptCore/runtime/DatePrototype.h6
-rw-r--r--JavaScriptCore/runtime/ErrorConstructor.cpp8
-rw-r--r--JavaScriptCore/runtime/ErrorConstructor.h2
-rw-r--r--JavaScriptCore/runtime/ErrorInstance.cpp2
-rw-r--r--JavaScriptCore/runtime/ErrorInstance.h2
-rw-r--r--JavaScriptCore/runtime/ErrorPrototype.cpp20
-rw-r--r--JavaScriptCore/runtime/ErrorPrototype.h2
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.cpp (renamed from JavaScriptCore/VM/ExceptionHelpers.cpp)105
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.h (renamed from JavaScriptCore/VM/ExceptionHelpers.h)15
-rw-r--r--JavaScriptCore/runtime/FunctionConstructor.cpp102
-rw-r--r--JavaScriptCore/runtime/FunctionConstructor.h6
-rw-r--r--JavaScriptCore/runtime/FunctionPrototype.cpp54
-rw-r--r--JavaScriptCore/runtime/FunctionPrototype.h8
-rw-r--r--JavaScriptCore/runtime/GetterSetter.cpp6
-rw-r--r--JavaScriptCore/runtime/GetterSetter.h8
-rw-r--r--JavaScriptCore/runtime/GlobalEvalFunction.cpp2
-rw-r--r--JavaScriptCore/runtime/GlobalEvalFunction.h2
-rw-r--r--JavaScriptCore/runtime/Identifier.cpp (renamed from JavaScriptCore/kjs/identifier.cpp)45
-rw-r--r--JavaScriptCore/runtime/Identifier.h (renamed from JavaScriptCore/kjs/identifier.h)20
-rw-r--r--JavaScriptCore/runtime/InitializeThreading.cpp11
-rw-r--r--JavaScriptCore/runtime/InternalFunction.cpp2
-rw-r--r--JavaScriptCore/runtime/InternalFunction.h14
-rw-r--r--JavaScriptCore/runtime/JSActivation.cpp18
-rw-r--r--JavaScriptCore/runtime/JSActivation.h18
-rw-r--r--JavaScriptCore/runtime/JSArray.cpp164
-rw-r--r--JavaScriptCore/runtime/JSArray.h39
-rw-r--r--JavaScriptCore/runtime/JSByteArray.cpp97
-rw-r--r--JavaScriptCore/runtime/JSByteArray.h110
-rw-r--r--JavaScriptCore/runtime/JSCell.cpp19
-rw-r--r--JavaScriptCore/runtime/JSCell.h119
-rw-r--r--JavaScriptCore/runtime/JSFunction.cpp66
-rw-r--r--JavaScriptCore/runtime/JSFunction.h48
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp62
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h52
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.cpp125
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.h109
-rw-r--r--JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp91
-rw-r--r--JavaScriptCore/runtime/JSGlobalObjectFunctions.h30
-rw-r--r--JavaScriptCore/runtime/JSImmediate.cpp48
-rw-r--r--JavaScriptCore/runtime/JSImmediate.h781
-rw-r--r--JavaScriptCore/runtime/JSLock.cpp58
-rw-r--r--JavaScriptCore/runtime/JSLock.h8
-rw-r--r--JavaScriptCore/runtime/JSNotAnObject.cpp47
-rw-r--r--JavaScriptCore/runtime/JSNotAnObject.h14
-rw-r--r--JavaScriptCore/runtime/JSNumberCell.cpp28
-rw-r--r--JavaScriptCore/runtime/JSNumberCell.h372
-rw-r--r--JavaScriptCore/runtime/JSObject.cpp186
-rw-r--r--JavaScriptCore/runtime/JSObject.h258
-rw-r--r--JavaScriptCore/runtime/JSPropertyNameIterator.cpp4
-rw-r--r--JavaScriptCore/runtime/JSPropertyNameIterator.h18
-rw-r--r--JavaScriptCore/runtime/JSStaticScopeObject.cpp4
-rw-r--r--JavaScriptCore/runtime/JSStaticScopeObject.h10
-rw-r--r--JavaScriptCore/runtime/JSString.cpp6
-rw-r--r--JavaScriptCore/runtime/JSString.h26
-rw-r--r--JavaScriptCore/runtime/JSType.h7
-rw-r--r--JavaScriptCore/runtime/JSValue.cpp29
-rw-r--r--JavaScriptCore/runtime/JSValue.h237
-rw-r--r--JavaScriptCore/runtime/JSVariableObject.h32
-rw-r--r--JavaScriptCore/runtime/JSWrapperObject.cpp4
-rw-r--r--JavaScriptCore/runtime/JSWrapperObject.h22
-rw-r--r--JavaScriptCore/runtime/Lookup.cpp (renamed from JavaScriptCore/kjs/lookup.cpp)36
-rw-r--r--JavaScriptCore/runtime/Lookup.h (renamed from JavaScriptCore/kjs/lookup.h)58
-rw-r--r--JavaScriptCore/runtime/MathObject.cpp125
-rw-r--r--JavaScriptCore/runtime/MathObject.h6
-rw-r--r--JavaScriptCore/runtime/NativeErrorConstructor.cpp13
-rw-r--r--JavaScriptCore/runtime/NativeErrorConstructor.h4
-rw-r--r--JavaScriptCore/runtime/NativeErrorPrototype.cpp4
-rw-r--r--JavaScriptCore/runtime/NativeErrorPrototype.h2
-rw-r--r--JavaScriptCore/runtime/NumberConstructor.cpp36
-rw-r--r--JavaScriptCore/runtime/NumberConstructor.h8
-rw-r--r--JavaScriptCore/runtime/NumberObject.cpp13
-rw-r--r--JavaScriptCore/runtime/NumberObject.h9
-rw-r--r--JavaScriptCore/runtime/NumberPrototype.cpp80
-rw-r--r--JavaScriptCore/runtime/NumberPrototype.h2
-rw-r--r--JavaScriptCore/runtime/ObjectConstructor.cpp10
-rw-r--r--JavaScriptCore/runtime/ObjectConstructor.h2
-rw-r--r--JavaScriptCore/runtime/ObjectPrototype.cpp74
-rw-r--r--JavaScriptCore/runtime/ObjectPrototype.h4
-rw-r--r--JavaScriptCore/runtime/Operations.cpp (renamed from JavaScriptCore/kjs/operations.cpp)28
-rw-r--r--JavaScriptCore/runtime/Operations.h135
-rw-r--r--JavaScriptCore/runtime/PropertyMapHashTable.h18
-rw-r--r--JavaScriptCore/runtime/PropertyNameArray.cpp2
-rw-r--r--JavaScriptCore/runtime/PropertyNameArray.h20
-rw-r--r--JavaScriptCore/runtime/PropertySlot.cpp2
-rw-r--r--JavaScriptCore/runtime/PropertySlot.h43
-rw-r--r--JavaScriptCore/runtime/Protect.h215
-rw-r--r--JavaScriptCore/runtime/PrototypeFunction.cpp2
-rw-r--r--JavaScriptCore/runtime/PrototypeFunction.h2
-rw-r--r--JavaScriptCore/runtime/RegExp.cpp (renamed from JavaScriptCore/kjs/regexp.cpp)36
-rw-r--r--JavaScriptCore/runtime/RegExp.h (renamed from JavaScriptCore/kjs/regexp.h)26
-rw-r--r--JavaScriptCore/runtime/RegExpConstructor.cpp102
-rw-r--r--JavaScriptCore/runtime/RegExpConstructor.h20
-rw-r--r--JavaScriptCore/runtime/RegExpMatchesArray.h4
-rw-r--r--JavaScriptCore/runtime/RegExpObject.cpp108
-rw-r--r--JavaScriptCore/runtime/RegExpObject.h18
-rw-r--r--JavaScriptCore/runtime/RegExpPrototype.cpp50
-rw-r--r--JavaScriptCore/runtime/RegExpPrototype.h2
-rw-r--r--JavaScriptCore/runtime/ScopeChain.cpp15
-rw-r--r--JavaScriptCore/runtime/ScopeChain.h13
-rw-r--r--JavaScriptCore/runtime/SmallStrings.cpp74
-rw-r--r--JavaScriptCore/runtime/SmallStrings.h14
-rw-r--r--JavaScriptCore/runtime/StringConstructor.cpp16
-rw-r--r--JavaScriptCore/runtime/StringConstructor.h2
-rw-r--r--JavaScriptCore/runtime/StringObject.cpp8
-rw-r--r--JavaScriptCore/runtime/StringObject.h16
-rw-r--r--JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h10
-rw-r--r--JavaScriptCore/runtime/StringPrototype.cpp432
-rw-r--r--JavaScriptCore/runtime/StringPrototype.h2
-rw-r--r--JavaScriptCore/runtime/Structure.cpp (renamed from JavaScriptCore/runtime/StructureID.cpp)453
-rw-r--r--JavaScriptCore/runtime/Structure.h (renamed from JavaScriptCore/runtime/StructureID.h)120
-rw-r--r--JavaScriptCore/runtime/StructureChain.cpp (renamed from JavaScriptCore/runtime/StructureIDChain.cpp)26
-rw-r--r--JavaScriptCore/runtime/StructureChain.h (renamed from JavaScriptCore/runtime/StructureIDChain.h)20
-rw-r--r--JavaScriptCore/runtime/StructureTransitionTable.h (renamed from JavaScriptCore/runtime/StructureIDTransitionTable.h)16
-rw-r--r--JavaScriptCore/runtime/SymbolTable.h2
-rw-r--r--JavaScriptCore/runtime/TypeInfo.h (renamed from JavaScriptCore/kjs/TypeInfo.h)2
-rw-r--r--JavaScriptCore/runtime/UString.cpp (renamed from JavaScriptCore/kjs/ustring.cpp)266
-rw-r--r--JavaScriptCore/runtime/UString.h (renamed from JavaScriptCore/kjs/ustring.h)117
-rw-r--r--JavaScriptCore/tests/mozilla/js1_5/Array/regress-157652.js2
-rw-r--r--JavaScriptCore/wrec/CharacterClass.cpp140
-rw-r--r--JavaScriptCore/wrec/CharacterClass.h68
-rw-r--r--JavaScriptCore/wrec/CharacterClassConstructor.cpp127
-rw-r--r--JavaScriptCore/wrec/CharacterClassConstructor.h46
-rw-r--r--JavaScriptCore/wrec/Escapes.h150
-rw-r--r--JavaScriptCore/wrec/Quantifier.h66
-rw-r--r--JavaScriptCore/wrec/WREC.cpp1309
-rw-r--r--JavaScriptCore/wrec/WREC.h224
-rw-r--r--JavaScriptCore/wrec/WRECFunctors.cpp80
-rw-r--r--JavaScriptCore/wrec/WRECFunctors.h109
-rw-r--r--JavaScriptCore/wrec/WRECGenerator.cpp665
-rw-r--r--JavaScriptCore/wrec/WRECGenerator.h112
-rw-r--r--JavaScriptCore/wrec/WRECParser.cpp643
-rw-r--r--JavaScriptCore/wrec/WRECParser.h214
-rw-r--r--JavaScriptCore/wtf/ASCIICType.h7
-rw-r--r--JavaScriptCore/wtf/AVLTree.h33
-rw-r--r--JavaScriptCore/wtf/AlwaysInline.h12
-rw-r--r--JavaScriptCore/wtf/Assertions.cpp4
-rw-r--r--JavaScriptCore/wtf/Assertions.h16
-rw-r--r--JavaScriptCore/wtf/ByteArray.cpp38
-rw-r--r--JavaScriptCore/wtf/ByteArray.h81
-rw-r--r--JavaScriptCore/wtf/CONTRIBUTORS.pthreads-win32137
-rw-r--r--JavaScriptCore/wtf/CurrentTime.cpp246
-rw-r--r--JavaScriptCore/wtf/CurrentTime.h51
-rw-r--r--JavaScriptCore/wtf/FastMalloc.cpp153
-rw-r--r--JavaScriptCore/wtf/FastMalloc.h13
-rw-r--r--JavaScriptCore/wtf/HashCountedSet.h3
-rw-r--r--JavaScriptCore/wtf/HashFunctions.h3
-rw-r--r--JavaScriptCore/wtf/HashTable.cpp11
-rw-r--r--JavaScriptCore/wtf/HashTable.h35
-rw-r--r--JavaScriptCore/wtf/ListHashSet.h6
-rw-r--r--JavaScriptCore/wtf/MainThread.cpp7
-rw-r--r--JavaScriptCore/wtf/MathExtras.h56
-rw-r--r--JavaScriptCore/wtf/MessageQueue.h35
-rw-r--r--JavaScriptCore/wtf/OwnPtr.h6
-rw-r--r--JavaScriptCore/wtf/PassRefPtr.h5
-rw-r--r--JavaScriptCore/wtf/Platform.h146
-rw-r--r--JavaScriptCore/wtf/PtrAndFlags.h53
-rw-r--r--JavaScriptCore/wtf/RandomNumber.cpp94
-rw-r--r--JavaScriptCore/wtf/RandomNumber.h42
-rw-r--r--JavaScriptCore/wtf/RandomNumberSeed.h71
-rw-r--r--JavaScriptCore/wtf/RefCounted.h2
-rw-r--r--JavaScriptCore/wtf/RefPtr.h4
-rw-r--r--JavaScriptCore/wtf/RetainPtr.h3
-rw-r--r--JavaScriptCore/wtf/StdLibExtras.h63
-rw-r--r--JavaScriptCore/wtf/TCSpinLock.h9
-rw-r--r--JavaScriptCore/wtf/TCSystemAlloc.cpp22
-rw-r--r--JavaScriptCore/wtf/ThreadSpecific.h115
-rw-r--r--JavaScriptCore/wtf/ThreadSpecificWin.cpp45
-rw-r--r--JavaScriptCore/wtf/Threading.cpp83
-rw-r--r--JavaScriptCore/wtf/Threading.h35
-rw-r--r--JavaScriptCore/wtf/ThreadingGtk.cpp72
-rw-r--r--JavaScriptCore/wtf/ThreadingNone.cpp32
-rw-r--r--JavaScriptCore/wtf/ThreadingPthreads.cpp89
-rw-r--r--JavaScriptCore/wtf/ThreadingQt.cpp72
-rw-r--r--JavaScriptCore/wtf/ThreadingWin.cpp366
-rw-r--r--JavaScriptCore/wtf/Vector.h25
-rw-r--r--JavaScriptCore/wtf/VectorTraits.h3
-rw-r--r--JavaScriptCore/wtf/dtoa.cpp (renamed from JavaScriptCore/kjs/dtoa.cpp)15
-rw-r--r--JavaScriptCore/wtf/dtoa.h (renamed from JavaScriptCore/kjs/dtoa.h)10
-rw-r--r--JavaScriptCore/wtf/unicode/Unicode.h13
-rw-r--r--JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp2
-rw-r--r--JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h8
-rw-r--r--JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h9
-rw-r--r--JavaScriptCore/wtf/win/MainThreadWin.cpp2
345 files changed, 44122 insertions, 20329 deletions
diff --git a/JavaScriptCore/API/APICast.h b/JavaScriptCore/API/APICast.h
index ecd524c..1344a16 100644
--- a/JavaScriptCore/API/APICast.h
+++ b/JavaScriptCore/API/APICast.h
@@ -26,8 +26,15 @@
#ifndef APICast_h
#define APICast_h
-#include "ustring.h"
-#include "ExecState.h"
+#include "JSValue.h"
+
+namespace JSC {
+ class ExecState;
+ class PropertyNameArray;
+ class JSGlobalData;
+ class JSObject;
+ class JSValuePtr;
+}
typedef const struct OpaqueJSContextGroup* JSContextGroupRef;
typedef const struct OpaqueJSContext* JSContextRef;
@@ -48,9 +55,9 @@ inline JSC::ExecState* toJS(JSGlobalContextRef c)
return reinterpret_cast<JSC::ExecState*>(c);
}
-inline JSC::JSValue* toJS(JSValueRef v)
+inline JSC::JSValuePtr toJS(JSValueRef v)
{
- return reinterpret_cast<JSC::JSValue*>(const_cast<OpaqueJSValue*>(v));
+ return JSC::JSValuePtr::decode(reinterpret_cast<JSC::JSValueEncodedAsPointer*>(const_cast<OpaqueJSValue*>(v)));
}
inline JSC::JSObject* toJS(JSObjectRef o)
@@ -68,14 +75,14 @@ inline JSC::JSGlobalData* toJS(JSContextGroupRef g)
return reinterpret_cast<JSC::JSGlobalData*>(const_cast<OpaqueJSContextGroup*>(g));
}
-inline JSValueRef toRef(JSC::JSValue* v)
+inline JSValueRef toRef(JSC::JSValuePtr v)
{
- return reinterpret_cast<JSValueRef>(v);
+ return reinterpret_cast<JSValueRef>(JSC::JSValuePtr::encode(v));
}
-inline JSValueRef* toRef(JSC::JSValue** v)
+inline JSValueRef* toRef(JSC::JSValuePtr* v)
{
- return reinterpret_cast<JSValueRef*>(const_cast<const JSC::JSValue**>(v));
+ return reinterpret_cast<JSValueRef*>(v);
}
inline JSObjectRef toRef(JSC::JSObject* o)
diff --git a/JavaScriptCore/API/JSBase.cpp b/JavaScriptCore/API/JSBase.cpp
index bd2935c..2ffe345 100644
--- a/JavaScriptCore/API/JSBase.cpp
+++ b/JavaScriptCore/API/JSBase.cpp
@@ -28,12 +28,12 @@
#include "JSBasePrivate.h"
#include "APICast.h"
-#include "completion.h"
+#include "Completion.h"
#include "OpaqueJSString.h"
#include "SourceCode.h"
-#include <runtime/ExecState.h>
+#include <interpreter/CallFrame.h>
#include <runtime/InitializeThreading.h>
-#include <kjs/interpreter.h>
+#include <runtime/Completion.h>
#include <runtime/JSGlobalObject.h>
#include <runtime/JSLock.h>
#include <runtime/JSObject.h>
@@ -48,10 +48,10 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
JSObject* jsThisObject = toJS(thisObject);
- // Interpreter::evaluate sets "this" to the global object if it is NULL
+ // evaluate sets "this" to the global object if it is NULL
JSGlobalObject* globalObject = exec->dynamicGlobalObject();
SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), startingLineNumber);
- Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), source, jsThisObject);
+ Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), source, jsThisObject);
if (completion.complType() == Throw) {
if (exception)
@@ -73,7 +73,7 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
JSLock lock(exec);
SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), startingLineNumber);
- Completion completion = Interpreter::checkSyntax(exec->dynamicGlobalObject()->globalExec(), source);
+ Completion completion = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source);
if (completion.complType() == Throw) {
if (exception)
*exception = toRef(completion.value());
diff --git a/JavaScriptCore/API/JSCallbackConstructor.cpp b/JavaScriptCore/API/JSCallbackConstructor.cpp
index 29c26ea..e10733e 100644
--- a/JavaScriptCore/API/JSCallbackConstructor.cpp
+++ b/JavaScriptCore/API/JSCallbackConstructor.cpp
@@ -36,7 +36,7 @@ namespace JSC {
const ClassInfo JSCallbackConstructor::info = { "CallbackConstructor", 0, 0, 0 };
-JSCallbackConstructor::JSCallbackConstructor(PassRefPtr<StructureID> structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback)
+JSCallbackConstructor::JSCallbackConstructor(PassRefPtr<Structure> structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback)
: JSObject(structure)
, m_class(jsClass)
, m_callback(callback)
diff --git a/JavaScriptCore/API/JSCallbackConstructor.h b/JavaScriptCore/API/JSCallbackConstructor.h
index 01f15a8..cb8307f 100644
--- a/JavaScriptCore/API/JSCallbackConstructor.h
+++ b/JavaScriptCore/API/JSCallbackConstructor.h
@@ -33,15 +33,15 @@ namespace JSC {
class JSCallbackConstructor : public JSObject {
public:
- JSCallbackConstructor(PassRefPtr<StructureID>, JSClassRef, JSObjectCallAsConstructorCallback);
+ JSCallbackConstructor(PassRefPtr<Structure>, JSClassRef, JSObjectCallAsConstructorCallback);
virtual ~JSCallbackConstructor();
JSClassRef classRef() const { return m_class; }
JSObjectCallAsConstructorCallback callback() const { return m_callback; }
static const ClassInfo info;
- static PassRefPtr<StructureID> createStructureID(JSValue* proto)
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto)
{
- return StructureID::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot));
+ return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot));
}
private:
diff --git a/JavaScriptCore/API/JSCallbackFunction.cpp b/JavaScriptCore/API/JSCallbackFunction.cpp
index 45d726a..86a2ebc 100644
--- a/JavaScriptCore/API/JSCallbackFunction.cpp
+++ b/JavaScriptCore/API/JSCallbackFunction.cpp
@@ -46,11 +46,11 @@ JSCallbackFunction::JSCallbackFunction(ExecState* exec, JSObjectCallAsFunctionCa
{
}
-JSValue* JSCallbackFunction::call(ExecState* exec, JSObject* functionObject, JSValue* thisValue, const ArgList& args)
+JSValuePtr JSCallbackFunction::call(ExecState* exec, JSObject* functionObject, JSValuePtr thisValue, const ArgList& args)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(functionObject);
- JSObjectRef thisObjRef = toRef(thisValue->toThisObject(exec));
+ JSObjectRef thisObjRef = toRef(thisValue.toThisObject(exec));
int argumentCount = static_cast<int>(args.size());
Vector<JSValueRef, 16> arguments(argumentCount);
diff --git a/JavaScriptCore/API/JSCallbackFunction.h b/JavaScriptCore/API/JSCallbackFunction.h
index 806a992..46f6fcc 100644
--- a/JavaScriptCore/API/JSCallbackFunction.h
+++ b/JavaScriptCore/API/JSCallbackFunction.h
@@ -39,16 +39,16 @@ public:
// InternalFunction mish-mashes constructor and function behavior -- we should
// refactor the code so this override isn't necessary
- static PassRefPtr<StructureID> createStructureID(JSValue* proto)
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto)
{
- return StructureID::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
+ return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
}
private:
virtual CallType getCallData(CallData&);
virtual const ClassInfo* classInfo() const { return &info; }
- static JSValue* call(ExecState*, JSObject*, JSValue*, const ArgList&);
+ static JSValuePtr call(ExecState*, JSObject*, JSValuePtr, const ArgList&);
JSObjectCallAsFunctionCallback m_callback;
};
diff --git a/JavaScriptCore/API/JSCallbackObject.cpp b/JavaScriptCore/API/JSCallbackObject.cpp
index 4be35bd..2fde0f8 100644
--- a/JavaScriptCore/API/JSCallbackObject.cpp
+++ b/JavaScriptCore/API/JSCallbackObject.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "JSCallbackObject.h"
-#include "collector.h"
+#include "Collector.h"
namespace JSC {
diff --git a/JavaScriptCore/API/JSCallbackObject.h b/JavaScriptCore/API/JSCallbackObject.h
index 7543e17..9001c43 100644
--- a/JavaScriptCore/API/JSCallbackObject.h
+++ b/JavaScriptCore/API/JSCallbackObject.h
@@ -36,7 +36,7 @@ namespace JSC {
template <class Base>
class JSCallbackObject : public Base {
public:
- JSCallbackObject(ExecState*, PassRefPtr<StructureID>, JSClassRef, void* data);
+ JSCallbackObject(ExecState*, PassRefPtr<Structure>, JSClassRef, void* data);
JSCallbackObject(JSClassRef);
virtual ~JSCallbackObject();
@@ -48,9 +48,9 @@ public:
JSClassRef classRef() const { return m_callbackObjectData->jsClass; }
bool inherits(JSClassRef) const;
- static PassRefPtr<StructureID> createStructureID(JSValue* proto)
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto)
{
- return StructureID::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | OverridesHasInstance));
+ return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | OverridesHasInstance));
}
private:
@@ -59,12 +59,12 @@ private:
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&);
- virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier&);
virtual bool deleteProperty(ExecState*, unsigned);
- virtual bool hasInstance(ExecState* exec, JSValue* value, JSValue* proto);
+ virtual bool hasInstance(ExecState* exec, JSValuePtr value, JSValuePtr proto);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
@@ -77,15 +77,14 @@ private:
void init(ExecState*);
- static JSCallbackObject* asCallbackObject(JSValue*);
+ static JSCallbackObject* asCallbackObject(JSValuePtr);
- static JSValue* call(ExecState*, JSObject* functionObject, JSValue* thisValue, const ArgList&);
+ static JSValuePtr call(ExecState*, JSObject* functionObject, JSValuePtr thisValue, const ArgList&);
static JSObject* construct(ExecState*, JSObject* constructor, const ArgList&);
- static JSValue* cachedValueGetter(ExecState*, const Identifier&, const PropertySlot&);
- static JSValue* staticValueGetter(ExecState*, const Identifier&, const PropertySlot&);
- static JSValue* staticFunctionGetter(ExecState*, const Identifier&, const PropertySlot&);
- static JSValue* callbackGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValuePtr staticValueGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValuePtr staticFunctionGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValuePtr callbackGetter(ExecState*, const Identifier&, const PropertySlot&);
struct JSCallbackObjectData {
JSCallbackObjectData(void* privateData, JSClassRef jsClass)
diff --git a/JavaScriptCore/API/JSCallbackObjectFunctions.h b/JavaScriptCore/API/JSCallbackObjectFunctions.h
index f008987..23f941d 100644
--- a/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ b/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -40,14 +40,14 @@
namespace JSC {
template <class Base>
-inline JSCallbackObject<Base>* JSCallbackObject<Base>::asCallbackObject(JSValue* value)
+inline JSCallbackObject<Base>* JSCallbackObject<Base>::asCallbackObject(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&info));
return static_cast<JSCallbackObject*>(asObject(value));
}
template <class Base>
-JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, PassRefPtr<StructureID> structure, JSClassRef jsClass, void* data)
+JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, PassRefPtr<Structure> structure, JSClassRef jsClass, void* data)
: Base(structure)
, m_callbackObjectData(new JSCallbackObjectData(data, jsClass))
{
@@ -127,10 +127,7 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie
propertyNameRef = OpaqueJSString::create(propertyName.ustring());
JSLock::DropAllLocks dropAllLocks(exec);
if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot()))) {
- // cache the value so we don't have to compute it again
- // FIXME: This violates the PropertySlot design a little bit.
- // We should either use this optimization everywhere, or nowhere.
- slot.setCustom(asObject(toJS(value)), cachedValueGetter);
+ slot.setValue(toJS(value));
return true;
}
}
@@ -160,7 +157,7 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, unsigned proper
}
template <class Base>
-void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
JSContextRef ctx = toRef(exec);
JSObjectRef thisRef = toRef(this);
@@ -280,7 +277,7 @@ JSObject* JSCallbackObject<Base>::construct(ExecState* exec, JSObject* construct
}
template <class Base>
-bool JSCallbackObject<Base>::hasInstance(ExecState* exec, JSValue* value, JSValue*)
+bool JSCallbackObject<Base>::hasInstance(ExecState* exec, JSValuePtr value, JSValuePtr)
{
JSContextRef execRef = toRef(exec);
JSObjectRef thisRef = toRef(this);
@@ -307,11 +304,11 @@ CallType JSCallbackObject<Base>::getCallData(CallData& callData)
}
template <class Base>
-JSValue* JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject, JSValue* thisValue, const ArgList& args)
+JSValuePtr JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject, JSValuePtr thisValue, const ArgList& args)
{
JSContextRef execRef = toRef(exec);
JSObjectRef functionRef = toRef(functionObject);
- JSObjectRef thisObjRef = toRef(thisValue->toThisObject(exec));
+ JSObjectRef thisObjRef = toRef(thisValue.toThisObject(exec));
for (JSClassRef jsClass = static_cast<JSCallbackObject<Base>*>(functionObject)->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
@@ -380,8 +377,10 @@ double JSCallbackObject<Base>::toNumber(ExecState* exec) const
for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
JSLock::DropAllLocks dropAllLocks(exec);
- if (JSValueRef value = convertToType(ctx, thisRef, kJSTypeNumber, toRef(exec->exceptionSlot())))
- return toJS(value)->getNumber();
+ if (JSValueRef value = convertToType(ctx, thisRef, kJSTypeNumber, toRef(exec->exceptionSlot()))) {
+ double dValue;
+ return toJS(value).getNumber(dValue) ? dValue : NaN;
+ }
}
return Base::toNumber(exec);
@@ -401,7 +400,7 @@ UString JSCallbackObject<Base>::toString(ExecState* exec) const
value = convertToType(ctx, thisRef, kJSTypeString, toRef(exec->exceptionSlot()));
}
if (value)
- return toJS(value)->getString();
+ return toJS(value).getString();
}
return Base::toString(exec);
@@ -430,15 +429,7 @@ bool JSCallbackObject<Base>::inherits(JSClassRef c) const
}
template <class Base>
-JSValue* JSCallbackObject<Base>::cachedValueGetter(ExecState*, const Identifier&, const PropertySlot& slot)
-{
- JSValue* v = slot.slotBase();
- ASSERT(v);
- return v;
-}
-
-template <class Base>
-JSValue* JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValuePtr JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
@@ -460,7 +451,7 @@ JSValue* JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identi
}
template <class Base>
-JSValue* JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValuePtr JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
@@ -485,7 +476,7 @@ JSValue* JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Ide
}
template <class Base>
-JSValue* JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValuePtr JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
diff --git a/JavaScriptCore/API/JSClassRef.cpp b/JavaScriptCore/API/JSClassRef.cpp
index 88fd70d..afde7ce 100644
--- a/JavaScriptCore/API/JSClassRef.cpp
+++ b/JavaScriptCore/API/JSClassRef.cpp
@@ -32,7 +32,7 @@
#include <runtime/InitializeThreading.h>
#include <runtime/JSGlobalObject.h>
#include <runtime/ObjectPrototype.h>
-#include <kjs/identifier.h>
+#include <runtime/Identifier.h>
using namespace JSC;
@@ -111,7 +111,7 @@ PassRefPtr<OpaqueJSClass> OpaqueJSClass::createNoAutomaticPrototype(const JSClas
return adoptRef(new OpaqueJSClass(definition, 0));
}
-void clearReferenceToPrototype(JSObjectRef prototype)
+static void clearReferenceToPrototype(JSObjectRef prototype)
{
OpaqueJSClassContextData* jsClassData = static_cast<OpaqueJSClassContextData*>(JSObjectGetPrivate(prototype));
ASSERT(jsClassData);
diff --git a/JavaScriptCore/API/JSClassRef.h b/JavaScriptCore/API/JSClassRef.h
index 71fae18..4f67618 100644
--- a/JavaScriptCore/API/JSClassRef.h
+++ b/JavaScriptCore/API/JSClassRef.h
@@ -29,8 +29,8 @@
#include "JSObjectRef.h"
#include <runtime/JSObject.h>
-#include <kjs/protect.h>
-#include <kjs/ustring.h>
+#include <runtime/Protect.h>
+#include <runtime/UString.h>
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
diff --git a/JavaScriptCore/API/JSContextRef.cpp b/JavaScriptCore/API/JSContextRef.cpp
index ee7286d..c331179 100644
--- a/JavaScriptCore/API/JSContextRef.cpp
+++ b/JavaScriptCore/API/JSContextRef.cpp
@@ -34,10 +34,17 @@
#include "JSObject.h"
#include <wtf/Platform.h>
+#if PLATFORM(DARWIN)
+#include <mach-o/dyld.h>
+
+static const int32_t webkitFirstVersionWithConcurrentGlobalContexts = 0x2100500; // 528.5.0
+#endif
+
using namespace JSC;
JSContextGroupRef JSContextGroupCreate()
{
+ initializeThreading();
return toRef(JSGlobalData::create().releaseRef());
}
@@ -54,8 +61,21 @@ void JSContextGroupRelease(JSContextGroupRef group)
JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
{
- JSLock lock(true);
- return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass);
+ initializeThreading();
+#if PLATFORM(DARWIN)
+ // When running on Tiger or Leopard, or if the application was linked before JSGlobalContextCreate was changed
+ // to use a unique JSGlobalData, we use a shared one for compatibility.
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ if (NSVersionOfLinkTimeLibrary("JavaScriptCore") <= webkitFirstVersionWithConcurrentGlobalContexts) {
+#else
+ {
+#endif
+ JSLock lock(true);
+ return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass);
+ }
+#endif // PLATFORM(DARWIN)
+
+ return JSGlobalContextCreateInGroup(0, globalObjectClass);
}
JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass)
@@ -66,6 +86,10 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::create();
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ globalData->makeUsableFromMultipleThreads();
+#endif
+
if (!globalObjectClass) {
JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject;
return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
@@ -73,7 +97,7 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject<JSGlobalObject>(globalObjectClass);
ExecState* exec = globalObject->globalExec();
- JSValue* prototype = globalObjectClass->prototype(exec);
+ JSValuePtr prototype = globalObjectClass->prototype(exec);
if (!prototype)
prototype = jsNull();
globalObject->resetPrototype(prototype);
diff --git a/JavaScriptCore/API/JSContextRef.h b/JavaScriptCore/API/JSContextRef.h
index bb6ea6e..bc89511 100644
--- a/JavaScriptCore/API/JSContextRef.h
+++ b/JavaScriptCore/API/JSContextRef.h
@@ -71,13 +71,14 @@ JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) AVAILABLE_AFTER_WE
@discussion JSGlobalContextCreate allocates a global object and populates it with all the
built-in JavaScript objects, such as Object, Function, String, and Array.
- The created context can only be used on the main thread. JavaScript values cannot be
- shared or exchanged between contexts.
+ In WebKit version 4.0 and later, the context is created in a unique context group.
+ Therefore, scripts may execute in it concurrently with scripts executing in other contexts.
+ However, you may not use values created in the context in other contexts.
@param globalObjectClass The class to use when creating the global object. Pass
NULL to use the default object class.
@result A JSGlobalContext with a global object of class globalObjectClass.
*/
-JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER;
/*!
@function
diff --git a/JavaScriptCore/API/JSObjectRef.cpp b/JavaScriptCore/API/JSObjectRef.cpp
index a4f32ba..67bb2a5 100644
--- a/JavaScriptCore/API/JSObjectRef.cpp
+++ b/JavaScriptCore/API/JSObjectRef.cpp
@@ -31,6 +31,8 @@
#include "DateConstructor.h"
#include "ErrorConstructor.h"
#include "FunctionConstructor.h"
+#include "Identifier.h"
+#include "InitializeThreading.h"
#include "JSArray.h"
#include "JSCallbackConstructor.h"
#include "JSCallbackFunction.h"
@@ -45,13 +47,13 @@
#include "ObjectPrototype.h"
#include "PropertyNameArray.h"
#include "RegExpConstructor.h"
-#include "identifier.h"
#include <wtf/Platform.h>
using namespace JSC;
JSClassRef JSClassCreate(const JSClassDefinition* definition)
{
+ initializeThreading();
RefPtr<OpaqueJSClass> jsClass = (definition->attributes & kJSClassAttributeNoAutomaticPrototype)
? OpaqueJSClass::createNoAutomaticPrototype(definition)
: OpaqueJSClass::create(definition);
@@ -103,7 +105,7 @@ JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObje
exec->globalData().heap.registerThread();
JSLock lock(exec);
- JSValue* jsPrototype = jsClass
+ JSValuePtr jsPrototype = jsClass
? jsClass->prototype(exec)
: exec->lexicalGlobalObject()->objectPrototype();
@@ -233,9 +235,9 @@ JSValueRef JSObjectGetPrototype(JSContextRef, JSObjectRef object)
void JSObjectSetPrototype(JSContextRef, JSObjectRef object, JSValueRef value)
{
JSObject* jsObject = toJS(object);
- JSValue* jsValue = toJS(value);
+ JSValuePtr jsValue = toJS(value);
- jsObject->setPrototype(jsValue->isObject() ? jsValue : jsNull());
+ jsObject->setPrototype(jsValue.isObject() ? jsValue : jsNull());
}
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
@@ -257,7 +259,7 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
JSObject* jsObject = toJS(object);
- JSValue* jsValue = jsObject->get(exec, propertyName->identifier(&exec->globalData()));
+ JSValuePtr jsValue = jsObject->get(exec, propertyName->identifier(&exec->globalData()));
if (exec->hadException()) {
if (exception)
*exception = toRef(exec->exception());
@@ -274,7 +276,7 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
JSObject* jsObject = toJS(object);
Identifier name(propertyName->identifier(&exec->globalData()));
- JSValue* jsValue = toJS(value);
+ JSValuePtr jsValue = toJS(value);
if (attributes && !jsObject->hasProperty(exec, name))
jsObject->putWithAttributes(exec, name, jsValue, attributes);
@@ -298,7 +300,7 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsi
JSObject* jsObject = toJS(object);
- JSValue* jsValue = jsObject->get(exec, propertyIndex);
+ JSValuePtr jsValue = jsObject->get(exec, propertyIndex);
if (exec->hadException()) {
if (exception)
*exception = toRef(exec->exception());
@@ -315,7 +317,7 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
JSLock lock(exec);
JSObject* jsObject = toJS(object);
- JSValue* jsValue = toJS(value);
+ JSValuePtr jsValue = toJS(value);
jsObject->put(exec, propertyIndex, jsValue);
if (exec->hadException()) {
diff --git a/JavaScriptCore/API/JSStringRef.cpp b/JavaScriptCore/API/JSStringRef.cpp
index 6452ffc..8e236e4 100644
--- a/JavaScriptCore/API/JSStringRef.cpp
+++ b/JavaScriptCore/API/JSStringRef.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "JSStringRef.h"
+#include "InitializeThreading.h"
#include "OpaqueJSString.h"
#include <wtf/unicode/UTF8.h>
@@ -34,11 +35,13 @@ using namespace WTF::Unicode;
JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars)
{
+ initializeThreading();
return OpaqueJSString::create(chars, numChars).releaseRef();
}
JSStringRef JSStringCreateWithUTF8CString(const char* string)
{
+ initializeThreading();
if (string) {
size_t length = strlen(string);
Vector<UChar, 1024> buffer(length);
diff --git a/JavaScriptCore/API/JSStringRefCF.cpp b/JavaScriptCore/API/JSStringRefCF.cpp
index 3a37866..2b8fd9e 100644
--- a/JavaScriptCore/API/JSStringRefCF.cpp
+++ b/JavaScriptCore/API/JSStringRefCF.cpp
@@ -27,14 +27,16 @@
#include "JSStringRefCF.h"
#include "APICast.h"
+#include "InitializeThreading.h"
#include "JSStringRef.h"
#include "OpaqueJSString.h"
-#include <kjs/ustring.h>
+#include <runtime/UString.h>
#include <runtime/JSValue.h>
#include <wtf/OwnArrayPtr.h>
JSStringRef JSStringCreateWithCFString(CFStringRef string)
{
+ JSC::initializeThreading();
CFIndex length = CFStringGetLength(string);
if (length) {
OwnArrayPtr<UniChar> buffer(new UniChar[length]);
@@ -44,7 +46,7 @@ JSStringRef JSStringCreateWithCFString(CFStringRef string)
} else {
return OpaqueJSString::create(0, 0).releaseRef();
}
- }
+}
CFStringRef JSStringCopyCFString(CFAllocatorRef alloc, JSStringRef string)
{
diff --git a/JavaScriptCore/API/JSValueRef.cpp b/JavaScriptCore/API/JSValueRef.cpp
index 15dd633..7080952 100644
--- a/JavaScriptCore/API/JSValueRef.cpp
+++ b/JavaScriptCore/API/JSValueRef.cpp
@@ -32,9 +32,9 @@
#include <runtime/JSGlobalObject.h>
#include <runtime/JSString.h>
-#include <kjs/operations.h>
-#include <kjs/protect.h>
-#include <kjs/ustring.h>
+#include <runtime/Operations.h>
+#include <runtime/Protect.h>
+#include <runtime/UString.h>
#include <runtime/JSValue.h>
#include <wtf/Assertions.h>
@@ -43,18 +43,18 @@
JSType JSValueGetType(JSContextRef, JSValueRef value)
{
- JSC::JSValue* jsValue = toJS(value);
- if (jsValue->isUndefined())
+ JSC::JSValuePtr jsValue = toJS(value);
+ if (jsValue.isUndefined())
return kJSTypeUndefined;
- if (jsValue->isNull())
+ if (jsValue.isNull())
return kJSTypeNull;
- if (jsValue->isBoolean())
+ if (jsValue.isBoolean())
return kJSTypeBoolean;
- if (jsValue->isNumber())
+ if (jsValue.isNumber())
return kJSTypeNumber;
- if (jsValue->isString())
+ if (jsValue.isString())
return kJSTypeString;
- ASSERT(jsValue->isObject());
+ ASSERT(jsValue.isObject());
return kJSTypeObject;
}
@@ -62,45 +62,45 @@ using namespace JSC; // placed here to avoid conflict between JSC::JSType and JS
bool JSValueIsUndefined(JSContextRef, JSValueRef value)
{
- JSValue* jsValue = toJS(value);
- return jsValue->isUndefined();
+ JSValuePtr jsValue = toJS(value);
+ return jsValue.isUndefined();
}
bool JSValueIsNull(JSContextRef, JSValueRef value)
{
- JSValue* jsValue = toJS(value);
- return jsValue->isNull();
+ JSValuePtr jsValue = toJS(value);
+ return jsValue.isNull();
}
bool JSValueIsBoolean(JSContextRef, JSValueRef value)
{
- JSValue* jsValue = toJS(value);
- return jsValue->isBoolean();
+ JSValuePtr jsValue = toJS(value);
+ return jsValue.isBoolean();
}
bool JSValueIsNumber(JSContextRef, JSValueRef value)
{
- JSValue* jsValue = toJS(value);
- return jsValue->isNumber();
+ JSValuePtr jsValue = toJS(value);
+ return jsValue.isNumber();
}
bool JSValueIsString(JSContextRef, JSValueRef value)
{
- JSValue* jsValue = toJS(value);
- return jsValue->isString();
+ JSValuePtr jsValue = toJS(value);
+ return jsValue.isString();
}
bool JSValueIsObject(JSContextRef, JSValueRef value)
{
- JSValue* jsValue = toJS(value);
- return jsValue->isObject();
+ JSValuePtr jsValue = toJS(value);
+ return jsValue.isObject();
}
bool JSValueIsObjectOfClass(JSContextRef, JSValueRef value, JSClassRef jsClass)
{
- JSValue* jsValue = toJS(value);
+ JSValuePtr jsValue = toJS(value);
- if (JSObject* o = jsValue->getObject()) {
+ if (JSObject* o = jsValue.getObject()) {
if (o->inherits(&JSCallbackObject<JSGlobalObject>::info))
return static_cast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
else if (o->inherits(&JSCallbackObject<JSObject>::info))
@@ -115,10 +115,10 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex
exec->globalData().heap.registerThread();
JSLock lock(exec);
- JSValue* jsA = toJS(a);
- JSValue* jsB = toJS(b);
+ JSValuePtr jsA = toJS(a);
+ JSValuePtr jsB = toJS(b);
- bool result = equal(exec, jsA, jsB); // false if an exception is thrown
+ bool result = JSValuePtr::equal(exec, jsA, jsB); // false if an exception is thrown
if (exec->hadException()) {
if (exception)
*exception = toRef(exec->exception());
@@ -129,10 +129,10 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex
bool JSValueIsStrictEqual(JSContextRef, JSValueRef a, JSValueRef b)
{
- JSValue* jsA = toJS(a);
- JSValue* jsB = toJS(b);
+ JSValuePtr jsA = toJS(a);
+ JSValuePtr jsB = toJS(b);
- bool result = strictEqual(jsA, jsB);
+ bool result = JSValuePtr::strictEqual(jsA, jsB);
return result;
}
@@ -142,9 +142,9 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject
exec->globalData().heap.registerThread();
JSLock lock(exec);
- JSValue* jsValue = toJS(value);
+ JSValuePtr jsValue = toJS(value);
JSObject* jsConstructor = toJS(constructor);
- if (!jsConstructor->structureID()->typeInfo().implementsHasInstance())
+ if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
return false;
bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
if (exec->hadException()) {
@@ -191,8 +191,8 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- JSValue* jsValue = toJS(value);
- return jsValue->toBoolean(exec);
+ JSValuePtr jsValue = toJS(value);
+ return jsValue.toBoolean(exec);
}
double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
@@ -201,9 +201,9 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception
exec->globalData().heap.registerThread();
JSLock lock(exec);
- JSValue* jsValue = toJS(value);
+ JSValuePtr jsValue = toJS(value);
- double number = jsValue->toNumber(exec);
+ double number = jsValue.toNumber(exec);
if (exec->hadException()) {
if (exception)
*exception = toRef(exec->exception());
@@ -219,9 +219,9 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef*
exec->globalData().heap.registerThread();
JSLock lock(exec);
- JSValue* jsValue = toJS(value);
+ JSValuePtr jsValue = toJS(value);
- RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue->toString(exec)));
+ RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)));
if (exec->hadException()) {
if (exception)
*exception = toRef(exec->exception());
@@ -237,9 +237,9 @@ JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exce
exec->globalData().heap.registerThread();
JSLock lock(exec);
- JSValue* jsValue = toJS(value);
+ JSValuePtr jsValue = toJS(value);
- JSObjectRef objectRef = toRef(jsValue->toObject(exec));
+ JSObjectRef objectRef = toRef(jsValue.toObject(exec));
if (exec->hadException()) {
if (exception)
*exception = toRef(exec->exception());
@@ -255,7 +255,7 @@ void JSValueProtect(JSContextRef ctx, JSValueRef value)
exec->globalData().heap.registerThread();
JSLock lock(exec);
- JSValue* jsValue = toJS(value);
+ JSValuePtr jsValue = toJS(value);
gcProtect(jsValue);
}
@@ -265,6 +265,6 @@ void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
exec->globalData().heap.registerThread();
JSLock lock(exec);
- JSValue* jsValue = toJS(value);
+ JSValuePtr jsValue = toJS(value);
gcUnprotect(jsValue);
}
diff --git a/JavaScriptCore/API/OpaqueJSString.cpp b/JavaScriptCore/API/OpaqueJSString.cpp
index 0819141..7c7b1af 100644
--- a/JavaScriptCore/API/OpaqueJSString.cpp
+++ b/JavaScriptCore/API/OpaqueJSString.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "OpaqueJSString.h"
-#include <runtime/ExecState.h>
+#include <interpreter/CallFrame.h>
#include <runtime/JSGlobalObject.h>
-#include <kjs/identifier.h>
+#include <runtime/Identifier.h>
using namespace JSC;
diff --git a/JavaScriptCore/API/OpaqueJSString.h b/JavaScriptCore/API/OpaqueJSString.h
index da05b06..473c815 100644
--- a/JavaScriptCore/API/OpaqueJSString.h
+++ b/JavaScriptCore/API/OpaqueJSString.h
@@ -26,7 +26,7 @@
#ifndef OpaqueJSString_h
#define OpaqueJSString_h
-#include <kjs/ustring.h>
+#include <runtime/UString.h>
namespace JSC {
class Identifier;
diff --git a/JavaScriptCore/API/WebKitAvailability.h b/JavaScriptCore/API/WebKitAvailability.h
index fae3904..1273360 100644
--- a/JavaScriptCore/API/WebKitAvailability.h
+++ b/JavaScriptCore/API/WebKitAvailability.h
@@ -43,7 +43,9 @@
#ifdef __APPLE__
#import <AvailabilityMacros.h>
#else
-// For non-Mac platforms, require the newest version.
+/*
+ * For non-Mac platforms, require the newest version.
+ */
#define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_LATEST
/*
* only certain compilers support __attribute__((deprecated))
diff --git a/JavaScriptCore/AllInOneFile.cpp b/JavaScriptCore/AllInOneFile.cpp
index ffee367..904734f 100644
--- a/JavaScriptCore/AllInOneFile.cpp
+++ b/JavaScriptCore/AllInOneFile.cpp
@@ -44,49 +44,48 @@
#include "runtime/BooleanConstructor.cpp"
#include "runtime/BooleanObject.cpp"
#include "runtime/BooleanPrototype.cpp"
-#include "kjs/collector.cpp"
+#include "runtime/Collector.cpp"
#include "runtime/CommonIdentifiers.cpp"
#include "runtime/DateConstructor.cpp"
#include "runtime/DateMath.cpp"
#include "runtime/DatePrototype.cpp"
#include "runtime/DateInstance.cpp"
-#include "kjs/dtoa.cpp"
+#include "wtf/dtoa.cpp"
#include "runtime/ErrorInstance.cpp"
#include "runtime/ErrorPrototype.cpp"
#include "runtime/ErrorConstructor.cpp"
#include "runtime/FunctionConstructor.cpp"
#include "runtime/FunctionPrototype.cpp"
-#include "grammar.cpp"
-#include "kjs/identifier.cpp"
+#include "Grammar.cpp"
+#include "runtime/Identifier.cpp"
#include "runtime/JSString.cpp"
#include "runtime/JSNumberCell.cpp"
#include "runtime/GetterSetter.cpp"
#include "runtime/InternalFunction.cpp"
-#include "kjs/interpreter.cpp"
+#include "runtime/Completion.cpp"
#include "runtime/JSImmediate.cpp"
#include "runtime/JSLock.cpp"
#include "runtime/JSWrapperObject.cpp"
-#include "kjs/lexer.cpp"
+#include "parser/Lexer.cpp"
#include "runtime/ArgList.cpp"
-#include "kjs/lookup.cpp"
+#include "runtime/Lookup.cpp"
#include "runtime/MathObject.cpp"
#include "runtime/NativeErrorConstructor.cpp"
#include "runtime/NativeErrorPrototype.cpp"
#include "runtime/NumberConstructor.cpp"
#include "runtime/NumberObject.cpp"
#include "runtime/NumberPrototype.cpp"
-#include "kjs/nodes.cpp"
-#include "kjs/nodes2string.cpp"
+#include "parser/Nodes.cpp"
#include "runtime/JSObject.cpp"
#include "runtime/Error.cpp"
#include "runtime/JSGlobalObject.cpp"
#include "runtime/ObjectConstructor.cpp"
#include "runtime/ObjectPrototype.cpp"
-#include "kjs/operations.cpp"
-#include "kjs/Parser.cpp"
+#include "runtime/Operations.cpp"
+#include "parser/Parser.cpp"
#include "runtime/PropertySlot.cpp"
#include "runtime/PropertyNameArray.cpp"
-#include "kjs/regexp.cpp"
+#include "runtime/RegExp.cpp"
#include "runtime/RegExpConstructor.cpp"
#include "runtime/RegExpObject.cpp"
#include "runtime/RegExpPrototype.cpp"
@@ -94,7 +93,7 @@
#include "runtime/StringConstructor.cpp"
#include "runtime/StringObject.cpp"
#include "runtime/StringPrototype.cpp"
-#include "kjs/ustring.cpp"
+#include "runtime/UString.cpp"
#include "runtime/JSValue.cpp"
#include "runtime/CallData.cpp"
#include "runtime/ConstructData.cpp"
@@ -102,5 +101,5 @@
#include "runtime/JSVariableObject.cpp"
#include "wtf/FastMalloc.cpp"
#include "wtf/TCSystemAlloc.cpp"
-#include "VM/CodeGenerator.cpp"
-#include "VM/RegisterFile.cpp"
+#include "bytecompiler/BytecodeGenerator.cpp"
+#include "interpreter/RegisterFile.cpp"
diff --git a/JavaScriptCore/Android.mk b/JavaScriptCore/Android.mk
index 98f87c1..f8b568b 100644
--- a/JavaScriptCore/Android.mk
+++ b/JavaScriptCore/Android.mk
@@ -23,10 +23,10 @@
#
# The following files are intentionally not included
# LOCAL_SRC_FILES_EXCLUDED := \
-# kjs/AllInOneFile.cpp \
-# kjs/CollectorHeapIntrospector.cpp \
-# kjs/grammar.y \
-# kjs/testkjs.cpp \
+# JSC/AllInOneFile.cpp \
+# JSC/CollectorHeapIntrospector.cpp \
+# JSC/grammar.y \
+# JSC/testJSC.cpp \
# pcre/dftables.c \
# pcre/pcre_maketables.c \
# pcre/ucptable.cpp \
@@ -51,32 +51,25 @@
LOCAL_SRC_FILES := \
\
- VM/CTI.cpp \
- VM/CodeBlock.cpp \
- VM/CodeGenerator.cpp \
- VM/ExceptionHelpers.cpp \
- VM/Machine.cpp \
- VM/Opcode.cpp \
- VM/RegisterFile.cpp \
- VM/SamplingTool.cpp \
+ \
+ bytecode/CodeBlock.cpp \
+ bytecode/JumpTable.cpp \
+ bytecode/Opcode.cpp \
+ bytecode/SamplingTool.cpp \
+ bytecode/StructureStubInfo.cpp \
+ bytecompiler/BytecodeGenerator.cpp \
\
debugger/Debugger.cpp \
+ debugger/DebuggerActivation.cpp \
debugger/DebuggerCallFrame.cpp \
\
- kjs/Parser.cpp \
- kjs/Shell.cpp \
- kjs/collector.cpp \
- kjs/dtoa.cpp \
- kjs/identifier.cpp \
- kjs/interpreter.cpp \
- kjs/lexer.cpp \
- kjs/lookup.cpp \
- kjs/nodes.cpp \
- kjs/nodes2string.cpp \
- kjs/operations.cpp \
- kjs/regexp.cpp \
- kjs/ustring.cpp \
+ interpreter/CallFrame.cpp \
+ interpreter/Interpreter.cpp \
+ interpreter/RegisterFile.cpp \
\
+ parser/Lexer.cpp \
+ parser/Nodes.cpp \
+ parser/Parser.cpp \
pcre/pcre_compile.cpp \
pcre/pcre_exec.cpp \
pcre/pcre_tables.cpp \
@@ -98,7 +91,9 @@ LOCAL_SRC_FILES := \
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/DateInstance.cpp \
@@ -108,15 +103,17 @@ LOCAL_SRC_FILES := \
runtime/ErrorConstructor.cpp \
runtime/ErrorInstance.cpp \
runtime/ErrorPrototype.cpp \
- runtime/ExecState.cpp \
+ runtime/ExceptionHelpers.cpp \
runtime/FunctionConstructor.cpp \
runtime/FunctionPrototype.cpp \
runtime/GetterSetter.cpp \
runtime/GlobalEvalFunction.cpp \
+ runtime/Identifier.cpp \
runtime/InitializeThreading.cpp \
runtime/InternalFunction.cpp \
runtime/JSActivation.cpp \
runtime/JSArray.cpp \
+ runtime/JSByteArray.cpp \
runtime/JSCell.cpp \
runtime/JSFunction.cpp \
runtime/JSGlobalData.cpp \
@@ -133,6 +130,7 @@ LOCAL_SRC_FILES := \
runtime/JSValue.cpp \
runtime/JSVariableObject.cpp \
runtime/JSWrapperObject.cpp \
+ runtime/Lookup.cpp \
runtime/MathObject.cpp \
runtime/NativeErrorConstructor.cpp \
runtime/NativeErrorPrototype.cpp \
@@ -141,9 +139,11 @@ LOCAL_SRC_FILES := \
runtime/NumberPrototype.cpp \
runtime/ObjectConstructor.cpp \
runtime/ObjectPrototype.cpp \
+ runtime/Operations.cpp \
runtime/PropertyNameArray.cpp \
runtime/PropertySlot.cpp \
runtime/PrototypeFunction.cpp \
+ runtime/RegExp.cpp \
runtime/RegExpConstructor.cpp \
runtime/RegExpObject.cpp \
runtime/RegExpPrototype.cpp \
@@ -152,34 +152,44 @@ LOCAL_SRC_FILES := \
runtime/StringConstructor.cpp \
runtime/StringObject.cpp \
runtime/StringPrototype.cpp \
- runtime/StructureID.cpp \
- runtime/StructureIDChain.cpp \
+ runtime/Structure.cpp \
+ runtime/StructureChain.cpp \
+ runtime/UString.cpp \
\
+ wrec/CharacterClass.cpp \
wrec/CharacterClassConstructor.cpp \
wrec/WREC.cpp \
+ wrec/WRECFunctors.cpp \
+ wrec/WRECGenerator.cpp \
+ wrec/WRECParser.cpp \
\
wtf/android/MainThreadAndroid.cpp \
wtf/Assertions.cpp \
+ wtf/ByteArray.cpp \
+ wtf/CurrentTime.cpp \
+ wtf/dtoa.cpp \
wtf/FastMalloc.cpp \
wtf/HashTable.cpp \
wtf/MainThread.cpp \
+ wtf/RandomNumber.cpp \
wtf/RefCountedLeakCounter.cpp \
wtf/TCSystemAlloc.cpp \
+ wtf/Threading.cpp \
wtf/ThreadingPthreads.cpp \
wtf/unicode/CollatorDefault.cpp \
wtf/unicode/UTF8.cpp \
wtf/unicode/icu/CollatorICU.cpp
# Rule to build grammar.y with our custom bison.
-GEN := $(intermediates)/kjs/grammar.cpp
-$(GEN) : PRIVATE_YACCFLAGS := -p kjsyy
-$(GEN) : $(LOCAL_PATH)/kjs/grammar.y
+GEN := $(intermediates)/parser/Grammar.cpp
+$(GEN) : PRIVATE_YACCFLAGS := -p jscyy
+$(GEN) : $(LOCAL_PATH)/parser/Grammar.y
$(call local-transform-y-to-cpp,.cpp)
$(GEN) : $(LOCAL_BISON)
LOCAL_GENERATED_SOURCES += $(GEN)
# generated headers
-KJS_OBJECTS := $(addprefix $(intermediates)/runtime/, \
+JSC_OBJECTS := $(addprefix $(intermediates)/runtime/, \
ArrayPrototype.lut.h \
DatePrototype.lut.h \
MathObject.lut.h \
@@ -188,18 +198,18 @@ KJS_OBJECTS := $(addprefix $(intermediates)/runtime/, \
RegExpObject.lut.h \
StringPrototype.lut.h \
)
-$(KJS_OBJECTS): PRIVATE_PATH := $(LOCAL_PATH)
-$(KJS_OBJECTS): PRIVATE_CUSTOM_TOOL = perl $(PRIVATE_PATH)/kjs/create_hash_table $< -i > $@
-$(KJS_OBJECTS): $(LOCAL_PATH)/kjs/create_hash_table
-$(KJS_OBJECTS): $(intermediates)/%.lut.h : $(LOCAL_PATH)/%.cpp
+$(JSC_OBJECTS): PRIVATE_PATH := $(LOCAL_PATH)
+$(JSC_OBJECTS): PRIVATE_CUSTOM_TOOL = perl $(PRIVATE_PATH)/create_hash_table $< -i > $@
+$(JSC_OBJECTS): $(LOCAL_PATH)/create_hash_table
+$(JSC_OBJECTS): $(intermediates)/%.lut.h : $(LOCAL_PATH)/%.cpp
$(transform-generated-source)
-LEXER_HEADER := $(intermediates)/lexer.lut.h
+LEXER_HEADER := $(intermediates)/Lexer.lut.h
$(LEXER_HEADER): PRIVATE_PATH := $(LOCAL_PATH)
-$(LEXER_HEADER): PRIVATE_CUSTOM_TOOL = perl $(PRIVATE_PATH)/kjs/create_hash_table $< -i > $@
-$(LEXER_HEADER): $(LOCAL_PATH)/kjs/create_hash_table
-$(LEXER_HEADER): $(intermediates)/%.lut.h : $(LOCAL_PATH)/kjs/keywords.table
+$(LEXER_HEADER): PRIVATE_CUSTOM_TOOL = perl $(PRIVATE_PATH)/create_hash_table $< -i > $@
+$(LEXER_HEADER): $(LOCAL_PATH)/create_hash_table
+$(LEXER_HEADER): $(intermediates)/%.lut.h : $(LOCAL_PATH)/parser/Keywords.table
$(transform-generated-source)
CHARTABLES := $(intermediates)/chartables.c
@@ -211,4 +221,4 @@ $(CHARTABLES): $(LOCAL_PATH)/pcre/pcre_internal.h
$(intermediates)/pcre/pcre_tables.o : $(CHARTABLES)
-LOCAL_GENERATED_SOURCES += $(KJS_OBJECTS) $(LEXER_HEADER) $(CHARTABLES)
+LOCAL_GENERATED_SOURCES += $(JSC_OBJECTS) $(LEXER_HEADER) $(CHARTABLES)
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index ea47411..5b9cc4b 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,13537 @@
+2009-02-13 Mark Rowe <mrowe@apple.com>
+
+ Merge r40975.
+
+ 2009-02-12 Darin Adler <darin@apple.com>
+
+ Reviewed by Oliver Hunt and Alexey Proskuryakov.
+
+ Speed up a couple string functions.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncIndexOf): Added a fast path for cases where the second
+ argument is either missing or an integer.
+ (JSC::stringProtoFuncBig): Use jsNontrivialString since the string is guaranteed
+ to be 2 or more characters long.
+ (JSC::stringProtoFuncSmall): Ditto.
+ (JSC::stringProtoFuncBlink): Ditto.
+ (JSC::stringProtoFuncBold): Ditto.
+ (JSC::stringProtoFuncItalics): Ditto.
+ (JSC::stringProtoFuncStrike): Ditto.
+ (JSC::stringProtoFuncSub): Ditto.
+ (JSC::stringProtoFuncSup): Ditto.
+ (JSC::stringProtoFuncFontcolor): Ditto.
+ (JSC::stringProtoFuncFontsize): Make the fast path Sam recently added even faster
+ by avoiding all but the minimum memory allocation.
+ (JSC::stringProtoFuncAnchor): Use jsNontrivialString.
+ (JSC::stringProtoFuncLink): Added a fast path.
+
+ * runtime/UString.cpp:
+ (JSC::UString::find): Added a fast path for single-character search strings.
+
+2009-02-13 Mark Rowe <mrowe@apple.com>
+
+ Merge r40945.
+
+ 2009-02-12 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Speed up String.prototype.fontsize.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncFontsize): Specialize for defined/commonly used values.
+
+2009-02-13 Mark Rowe <mrowe@apple.com>
+
+ Merge r41000.
+
+ 2009-02-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Some data in the instruction stream is potentially uninitialized - fix this.
+
+ Change the OperandTypes constructor so that uninitialized memory in the int
+ is zeroed, and modify the Instruction constructor taking an Opcode so that
+ if !HAVE(COMPUTED_GOTO) (i.e. when Opcode is an enum, and is potentially only
+ a byte) it zeros the Instruction first before writing the opcode.
+
+ * bytecode/Instruction.h:
+ (JSC::Instruction::Instruction):
+ * parser/ResultType.h:
+ (JSC::OperandTypes::OperandTypes):
+
+2009-02-13 Mark Rowe <mrowe@apple.com>
+
+ Merge r40995.
+
+ 2009-02-13 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix for non_JIT platforms.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::setIsNumericCompareFunction):
+ (JSC::CodeBlock::isNumericCompareFunction):
+
+2009-02-13 Mark Rowe <mrowe@apple.com>
+
+ Merge r40993.
+
+ 2009-02-13 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Fixed <rdar://problem/6584057> Optimize sort by JS numeric comparison
+ function not to run the comparison function
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::setIsNumericCompareFunction):
+ (JSC::CodeBlock::isNumericCompareFunction): Added the ability to track
+ whether a CodeBlock performs a sort-like numeric comparison.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate): Set the isNumericCompareFunction bit
+ after compiling.
+
+ * parser/Nodes.cpp:
+ (JSC::FunctionBodyNode::emitBytecode): Fixed a bug that caused us to
+ codegen an extra return at the end of all functions (eek!), since this
+ made it harder / weirder to detect the numeric comparison pattern in
+ bytecode.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncSort): Use the isNumericCompareFunction bit to do
+ a faster sort if we can.
+
+ * runtime/FunctionConstructor.cpp:
+ (JSC::extractFunctionBody):
+ (JSC::constructFunction):
+ * runtime/FunctionConstructor.h: Renamed and exported extractFunctionBody for
+ use in initializing lazyNumericCompareFunction.
+
+ * runtime/JSArray.cpp:
+ (JSC::compareNumbersForQSort):
+ (JSC::compareByStringPairForQSort):
+ (JSC::JSArray::sortNumeric):
+ (JSC::JSArray::sort):
+ * runtime/JSArray.h: Added a fast numeric sort. Renamed ArrayQSortPair
+ to be more specific since we do different kinds of qsort now.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::numericCompareFunction):
+ (JSC::JSGlobalData::ClientData::~ClientData):
+ * runtime/JSGlobalData.h: Added helper data for computing the
+ isNumericCompareFunction bit.
+
+2009-02-13 Mark Rowe <mrowe@apple.com>
+
+ Merge r40968.
+
+ 2009-02-13 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Jon Honeycutt.
+
+ Math.random is really slow on windows.
+
+ Math.random calls WTF::randomNumber which is implemented as
+ the secure rand_s on windows. Unfortunately rand_s is an order
+ of magnitude slower than arc4random. For this reason I've
+ added "weakRandomNumber" for use by JavaScript's Math Object.
+ In the long term we should look at using our own secure PRNG
+ in place of the system, but this will do for now.
+
+ 30% win on SunSpider on Windows, resolving most of the remaining
+ disparity vs. Mac.
+
+ * runtime/MathObject.cpp:
+ (JSC::MathObject::MathObject):
+ (JSC::mathProtoFuncRandom):
+ * wtf/RandomNumber.cpp:
+ (WTF::weakRandomNumber):
+ (WTF::randomNumber):
+ * wtf/RandomNumber.h:
+ * wtf/RandomNumberSeed.h:
+ (WTF::initializeWeakRandomNumberGenerator):
+
+2009-02-13 Mark Rowe <mrowe@apple.com>
+
+ Merge r40967.
+
+ 2009-02-12 Mark Rowe <mrowe@apple.com>
+
+ Fix the build for other platforms.
+
+ * wtf/RandomNumber.cpp:
+ (WTF::randomNumber):
+
+2009-02-13 Mark Rowe <mrowe@apple.com>
+
+ Merge r40937.
+
+ 2009-02-12 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Correctness fix.
+
+ * wtf/RandomNumber.cpp:
+ (WTF::randomNumber): Divide by the maximum representable value, which
+ is different on each platform now, to get values between 0 and 1.
+
+2009-02-13 Mark Rowe <mrowe@apple.com>
+
+ Merge r40935.
+
+ 2009-02-12 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix.
+
+ * wtf/RandomNumber.cpp:
+ (WTF::randomNumber):
+
+2009-02-13 Mark Rowe <mrowe@apple.com>
+
+ Merge r40932.
+
+ 2009-02-12 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixed <rdar://problem/6582048>.
+
+ * wtf/RandomNumber.cpp:
+ (WTF::randomNumber): Make only one call to the random number generator
+ on platforms where the generator is cryptographically secure. The value
+ of randomness over and above cryptographically secure randomness is not
+ clear, and it caused some performance problems.
+
+2009-02-03 Mark Rowe <mrowe@apple.com>
+
+ Merge r40522.
+
+ 2009-02-02 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ <https://bugs.webkit.org/show_bug.cgi?id=21414> REGRESSION: Regular Expressions and character classes, shorthands and ranges
+ <rdar://problem/6543487>
+
+ In certain circumstances when WREC::Generator::generateCharacterClassInvertedRange invokes
+ itself recursively, it will incorrectly emit (and thus consume) the next single character
+ match in the current character class. As WREC uses a binary search this out of sequence
+ codegen could result in a character match being missed and so cause the regex to produce
+ incorrect results.
+
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateCharacterClassInvertedRange):
+
+2009-02-03 Mark Rowe <mrowe@apple.com>
+
+ Merge r40397.
+
+ 2009-01-29 Stephanie Lewis <slewis@apple.com>
+
+ RS by Oliver Hunt.
+
+ Update the order files.
+
+ * JavaScriptCore.order:
+
+2009-02-03 Mark Rowe <mrowe@apple.com>
+
+ Merge r40396.
+
+ 2009-01-29 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 23551: Crash on page load with profiler enabled and running
+ <https://bugs.webkit.org/show_bug.cgi?id=23551>
+ <rdar://problem/6529521>
+
+ Interpreter::execute(FunctionBodyNode*, ...) calls Profiler::didExecute()
+ with a stale CallFrame. If some part of the scope chain has already been
+ freed, Profiler::didExecute() will crash when attempting to get the lexical
+ global object. The fix is to make the didExecute() call use the caller's
+ CallFrame, not the one made for the function call. In this case, the
+ willExecute() call should also be changed to match.
+
+ Since this occurs in the actual inspector JS, it is difficult to reduce.
+ I couldn't make a layout test.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+
+2009-02-03 Mark Rowe <mrowe@apple.com>
+
+ Merge r40345.
+
+ 2009-01-28 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Fix for <rdar://problem/6525537>
+ Hang occurs when closing Installer window (iTunes, Aperture)
+
+ * JavaScriptCore.exp: Export JSGlobalData::sharedInstance.
+
+2009-02-03 Mark Rowe <mrowe@apple.com>
+
+ Merge r40339.
+
+ 2009-01-28 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoff Garen.
+
+ Initial patch by Mark Rowe.
+
+ <rdar://problem/6519356>
+ REGRESSION (r36006): "out of memory" alert running dromaeo on Windows
+
+ Report the cost of the ArrayStorage vector more accurately/often.
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::JSArray): Report the extra cost even for a filled array
+ because JSString using the single character optimization and immediates
+ wont increase the cost themselves.
+ (JSC::JSArray::putSlowCase): Update the cost when increasing the size of
+ the array.
+ (JSC::JSArray::increaseVectorLength): Ditto.
+
+2009-02-03 Mark Rowe <mrowe@apple.com>
+
+ Merge r40332.
+
+ 2009-01-28 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoff Garen.
+
+ Fix for <rdar://problem/6129678>
+ REGRESSION (Safari 3-4): Local variable not accessible from Dashcode console or variables view
+
+ Iterating the properties of activation objects accessed through the WebKit debugging
+ APIs was broken by forced conversion of JSActivation to the global object. To fix this,
+ we use a proxy activation object that acts more like a normal JSObject.
+
+ * debugger/DebuggerActivation.cpp: Added.
+ (JSC::DebuggerActivation::DebuggerActivation):
+ (JSC::DebuggerActivation::mark):
+ (JSC::DebuggerActivation::className):
+ (JSC::DebuggerActivation::getOwnPropertySlot):
+ (JSC::DebuggerActivation::put):
+ (JSC::DebuggerActivation::putWithAttributes):
+ (JSC::DebuggerActivation::deleteProperty):
+ (JSC::DebuggerActivation::getPropertyNames):
+ (JSC::DebuggerActivation::getPropertyAttributes):
+ (JSC::DebuggerActivation::defineGetter):
+ (JSC::DebuggerActivation::defineSetter):
+ (JSC::DebuggerActivation::lookupGetter):
+ (JSC::DebuggerActivation::lookupSetter):
+ * debugger/DebuggerActivation.h: Added.
+ Proxy JSActivation object for Debugging.
+
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::isActivationObject): Added.
+ * runtime/JSObject.h:
+ (JSC::JSObject::isActivationObject): Added.
+
+2009-01-26 Adele Peterson <adele@apple.com>
+
+ Build fix.
+
+ * debugger/Debugger.cpp:
+
+2009-01-26 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Fixes for eq null & neq null, on 64-bit JIT.
+ https://bugs.webkit.org/show_bug.cgi?id=23559
+
+ This patch degrades 64-bit JIT performance on some benchmarks,
+ due to the whole not-being-incorrect thing.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+
+2009-01-26 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Gavin Barraclough.
+
+ Bug 23552: Dashcode evaluator no longer works after making ExecStates actual call frames
+ <https://bugs.webkit.org/show_bug.cgi?id=23552>
+ <rdar://problem/6398839>
+
+ * JavaScriptCore.exp:
+ * debugger/Debugger.cpp:
+ (JSC::evaluateInGlobalCallFrame): Added so that WebScriptCallFrame can
+ evaluate JS starting from a global call frame.
+ * debugger/Debugger.h:
+
+2009-01-25 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Dan Bernstein.
+
+ Improve the consistency of settings in our .xcconfig files.
+
+ * Configurations/Base.xcconfig: Enable GCC_OBJC_CALL_CXX_CDTORS to match other projects.
+
+2009-01-25 Darin Adler <darin@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Bug 23352: Turn on more compiler warnings in the Mac build
+ https://bugs.webkit.org/show_bug.cgi?id=23352
+
+ Turn on the following warnings:
+
+ -Wcast-qual
+ -Wextra-tokens
+ -Wformat=2
+ -Winit-self
+ -Wmissing-noreturn
+ -Wpacked
+ -Wrendundant-decls
+
+ * Configurations/Base.xcconfig: Added the new warnings. Switched to -Wextra instead of
+ -W for clarity since we don't have to support the older versions of gcc that require the
+ old -W syntax. Since we now use -Wformat=2, removed -Wformat-security. Also removed
+ -Wno-format-y2k since we can have that one on now.
+
+2009-01-25 Judit Jasz <jasy@inf.u-szeged.hu>
+
+ Reviewed by Darin Adler.
+
+ Compilation problem fixing
+ http://bugs.webkit.org/show_bug.cgi?id=23497
+
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall): Use JSValuePtr::encode.
+
+2009-01-25 Darin Adler <darin@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Bug 23352: Turn on more compiler warnings in the Mac build
+ https://bugs.webkit.org/show_bug.cgi?id=23352
+
+ Fourth patch: Deal with the last few stray warnings.
+
+ * parser/Parser.cpp: Only declare jscyyparse if it's not already declared.
+ This makes both separate compilation and all-in-one compilation work with the
+ -Wredundant-decls warning.
+
+2009-01-25 Darin Adler <darin@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Bug 23352: Turn on more compiler warnings in the Mac build
+ https://bugs.webkit.org/show_bug.cgi?id=23352
+
+ Third patch: Use the noreturn attribute on functions that don't
+ return to prepare for the use of the -Wmissing-noreturn warning.
+
+ * jit/JITCall.cpp:
+ (JSC::unreachable): Added NO_RETURN.
+ * jsc.cpp:
+ (functionQuit): Ditto.
+ (printUsageStatement): Ditto.
+ * wtf/AlwaysInline.h: Added definition of NO_RETURN.
+
+2009-01-24 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Force inlining of Lexer::matchPunctuator
+
+ 2.2% win when parsing jQuery, Mootools, Prototype, etc
+
+ * parser/Lexer.h:
+
+2009-01-23 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Fix for <rdar://problem/6126212>
+ Ensure that callbacks out from the JSC interface are only allowed
+ to return in reverse-chronological order to that in which they were
+ made. If we allow earlier callbacks to return first, then this may
+ result in setions of the RegisterFile in use by another thread
+ being trampled.
+
+ See uber-comment in JSLock.h for details.
+
+ * runtime/JSLock.cpp:
+ (JSC::JSLock::DropAllLocks::DropAllLocks):
+ (JSC::JSLock::DropAllLocks::~DropAllLocks):
+
+2009-01-23 Darin Adler <darin@apple.com>
+
+ Try to fix WX build.
+
+ * runtime/JSGlobalObjectFunctions.h: Include <wtf/unicode/Unicode.h>
+ for the definition of UChar.
+
+2009-01-23 Anders Carlsson <andersca@apple.com>
+
+ * Configurations/Base.xcconfig:
+ GCC 4.0 build fix.
+
+ * runtime/JSNumberCell.h:
+ 64-bit build fix.
+
+2009-01-23 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Turn on -Wmissing-prototypes and fix the warnings.
+
+ * API/JSClassRef.cpp:
+ (clearReferenceToPrototype):
+ * Configurations/Base.xcconfig:
+ * runtime/Collector.cpp:
+ (JSC::getPlatformThreadRegisters):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createError):
+ * runtime/JSGlobalObjectFunctions.h:
+ * runtime/JSNumberCell.h:
+ * runtime/UString.cpp:
+ (JSC::initializeStaticBaseString):
+ (JSC::createRep):
+ * wtf/FastMalloc.cpp:
+ * wtf/Threading.cpp:
+
+2009-01-22 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Anders Carlsson.
+
+ Disable GCC_WARN_ABOUT_MISSING_PROTOTYPES temporarily.
+
+ Current versions of Xcode only respect it for C and Objective-C files,
+ and our code doesn't currently compile if it is applied to C++ and
+ Objective-C++ files.
+
+ * Configurations/Base.xcconfig:
+
+2009-01-22 Steve Falkenburg <sfalken@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=23489
+
+ Return currentTime() in correct units for the two early return cases.
+
+ Reviewed by Mark Rowe.
+
+ * wtf/CurrentTime.cpp:
+ (WTF::currentTime):
+
+2009-01-22 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ Fix for <rdar://problem/6439247>
+ FastMalloc allocating an extra 4MB of meta-data on 64-bit
+
+ Rely on the fact that on all known x86-64 platforms only use 48 bits of
+ address space to shrink the initial size of the PageMap from ~4MB to 120K.
+ For 64-bit we still use a 3-level radix tree, but now each level is only 12
+ bits wide.
+
+ No performance change.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::MapSelector): Add specialization for 64 bit that takes into account the
+ 16 bits of unused address space on x86-64.
+
+2009-01-22 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23461 LayoutTests/
+ fast/js/numeric-conversion.html is broken, and corresponding
+ <rdar://problem/6514842>
+
+ The basic problem here is that parseInt(Infinity) should be NaN,
+ but we were returning 0. NaN matches Safari 3.2.1 and Firefox.
+
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncParseInt):
+
+2009-01-22 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ <rdar://problem/6516853> (r39682-r39736) JSFunFuzz: crash on "(function(){({ x2: x }), })()"
+ <https://bugs.webkit.org/show_bug.cgi?id=23479>
+
+ Automatic semicolon insertion was resulting in this being accepted in the initial
+ nodeless parsing, but subsequent reparsing for code generation would fail, leading
+ to a crash. The solution is to ensure that reparsing a function performs parsing
+ in the same state as the initial parse. We do this by modifying the saved source
+ ranges to include rather than exclude the opening and closing braces.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::reparseForExceptionInfoIfNecessary): add an assertion for successful recompile
+ * parser/Lexer.h:
+ (JSC::Lexer::sourceCode): include rather than exclude braces.
+ * parser/Nodes.h:
+ (JSC::FunctionBodyNode::toSourceString): No need to append braces anymore.
+
+2009-01-22 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23373
+
+ Implement ThreadCondition::timedWait().
+ Since we borrow the code for condition variables from other sources,
+ I did the same for timedWait(). See comments in ThreadingWin.cpp for
+ rationale and more info.
+
+ * wtf/CONTRIBUTORS.pthreads-win32:
+ Added. A list of Pthreads-win32 contributors mentioned in their license. The license itself
+ is included into wtf/ThreadingWin32.cpp.
+
+ * wtf/Threading.h:
+ * wtf/ThreadingWin.cpp:
+ Additional info and Pthreads-win32 license at the beginning.
+ (WTF::PlatformCondition::timedWait): new method, derived from Pthreads-win32.
+ (WTF::PlatformCondition::signal): same
+ (WTF::ThreadCondition::ThreadCondition):
+ (WTF::ThreadCondition::~ThreadCondition):
+ (WTF::ThreadCondition::wait): this now calls PlatformCondition::timedWait.
+ (WTF::ThreadCondition::timedWait): same
+ (WTF::ThreadCondition::signal): this now calls PlatformCondition::signal.
+ (WTF::ThreadCondition::broadcast): same
+
+2009-01-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23469.
+
+ We need to check all numbers in integer switches, not just those
+ represented as integer JSImmediates.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::cti_op_switch_imm):
+
+2009-01-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23468.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2009-01-21 Alexey Proskuryakov <ap@webkit.org>
+
+ Suggested by Oliver Hunt. Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23456
+ Function argument names leak
+
+ * parser/Nodes.cpp: (JSC::FunctionBodyNode::~FunctionBodyNode): Destruct parameter names.
+
+2009-01-20 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Windows build fix
+
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+
+2009-01-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Structure property table deleted offset maps are being leaked.
+ Probably shouldn't be doing that.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23442
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::~Structure):
+
+2009-01-20 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ Attempt to fix gtk build
+
+ * GNUmakefile.am:
+
+2009-01-20 Darin Adler <darin@apple.com>
+
+ * runtime/StringPrototype.cpp:
+ (JSC::substituteBackreferences): Add back the initialization to fix the build.
+
+2009-01-20 Darin Adler <darin@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Bug 23352: Turn on more compiler warnings in the Mac build
+ https://bugs.webkit.org/show_bug.cgi?id=23352
+
+ First patch: Fix some simple cases of various warnings.
+
+ * pcre/pcre_compile.cpp:
+ (jsRegExpCompile): Use const_cast to change const-ness.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::substituteBackreferences): Remove unneeded initialization and
+ use UChar instead of unsigned short for UTF-16 values.
+
+ * wtf/dtoa.cpp:
+ (WTF::strtod): Use const_cast to change const-ness.
+
+2009-01-20 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ Whoops, remove runtime/ByteArray references from .pri and .scons builds, update .bkl
+
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCoreSources.bkl:
+
+2009-01-20 Oliver Hunt <oliver@apple.com>
+
+ RS=Dan Bernstein.
+
+ Move runtime/ByteArray to wtf/ByteArray
+
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/JSByteArray.cpp:
+ * runtime/JSByteArray.h:
+ * wtf/ByteArray.cpp: Renamed from JavaScriptCore/runtime/ByteArray.cpp.
+ (WTF::ByteArray::create):
+ * wtf/ByteArray.h: Renamed from JavaScriptCore/runtime/ByteArray.h.
+ (WTF::ByteArray::length):
+ (WTF::ByteArray::set):
+ (WTF::ByteArray::get):
+ (WTF::ByteArray::data):
+ (WTF::ByteArray::deref):
+ (WTF::ByteArray::ByteArray):
+
+2009-01-19 Sam Weinig <sam@webkit.org>
+
+ Rubber-stamped by Gavin Barraclough.
+
+ Remove temporary operator-> from JSValuePtr.
+
+ * API/JSCallbackFunction.cpp:
+ (JSC::JSCallbackFunction::call):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::call):
+ (JSC::::toNumber):
+ (JSC::::toString):
+ * API/JSObjectRef.cpp:
+ (JSObjectSetPrototype):
+ * API/JSValueRef.cpp:
+ (JSValueGetType):
+ (JSValueIsUndefined):
+ (JSValueIsNull):
+ (JSValueIsBoolean):
+ (JSValueIsNumber):
+ (JSValueIsString):
+ (JSValueIsObject):
+ (JSValueIsObjectOfClass):
+ (JSValueToBoolean):
+ (JSValueToNumber):
+ (JSValueToStringCopy):
+ (JSValueToObject):
+ * bytecode/CodeBlock.cpp:
+ (JSC::valueToSourceString):
+ (JSC::CodeBlock::mark):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::isKnownNotImmediate):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitEqualityOp):
+ (JSC::keyForImmediateSwitch):
+ * interpreter/Interpreter.cpp:
+ (JSC::jsLess):
+ (JSC::jsLessEq):
+ (JSC::jsAddSlowCase):
+ (JSC::jsAdd):
+ (JSC::jsTypeStringForValue):
+ (JSC::jsIsObjectType):
+ (JSC::jsIsFunctionType):
+ (JSC::isNotObject):
+ (JSC::Interpreter::callEval):
+ (JSC::Interpreter::throwException):
+ (JSC::cachePrototypeChain):
+ (JSC::Interpreter::tryCachePutByID):
+ (JSC::countPrototypeChainEntriesAndCheckForProxies):
+ (JSC::Interpreter::tryCacheGetByID):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::tryCTICachePutByID):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::Interpreter::cti_op_convert_this):
+ (JSC::Interpreter::cti_op_add):
+ (JSC::Interpreter::cti_op_pre_inc):
+ (JSC::Interpreter::cti_op_put_by_id_generic):
+ (JSC::Interpreter::cti_op_get_by_id_generic):
+ (JSC::Interpreter::cti_op_put_by_id):
+ (JSC::Interpreter::cti_op_put_by_id_second):
+ (JSC::Interpreter::cti_op_put_by_id_fail):
+ (JSC::Interpreter::cti_op_get_by_id):
+ (JSC::Interpreter::cti_op_get_by_id_second):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list_full):
+ (JSC::Interpreter::cti_op_get_by_id_proto_fail):
+ (JSC::Interpreter::cti_op_get_by_id_array_fail):
+ (JSC::Interpreter::cti_op_get_by_id_string_fail):
+ (JSC::Interpreter::cti_op_instanceof):
+ (JSC::Interpreter::cti_op_del_by_id):
+ (JSC::Interpreter::cti_op_mul):
+ (JSC::Interpreter::cti_op_call_JSFunction):
+ (JSC::Interpreter::cti_op_call_NotJSFunction):
+ (JSC::Interpreter::cti_op_construct_JSConstruct):
+ (JSC::Interpreter::cti_op_construct_NotJSConstruct):
+ (JSC::Interpreter::cti_op_get_by_val):
+ (JSC::Interpreter::cti_op_get_by_val_byte_array):
+ (JSC::Interpreter::cti_op_sub):
+ (JSC::Interpreter::cti_op_put_by_val):
+ (JSC::Interpreter::cti_op_put_by_val_array):
+ (JSC::Interpreter::cti_op_put_by_val_byte_array):
+ (JSC::Interpreter::cti_op_loop_if_true):
+ (JSC::Interpreter::cti_op_negate):
+ (JSC::Interpreter::cti_op_div):
+ (JSC::Interpreter::cti_op_pre_dec):
+ (JSC::Interpreter::cti_op_not):
+ (JSC::Interpreter::cti_op_jtrue):
+ (JSC::Interpreter::cti_op_post_inc):
+ (JSC::Interpreter::cti_op_lshift):
+ (JSC::Interpreter::cti_op_bitand):
+ (JSC::Interpreter::cti_op_rshift):
+ (JSC::Interpreter::cti_op_bitnot):
+ (JSC::Interpreter::cti_op_mod):
+ (JSC::Interpreter::cti_op_post_dec):
+ (JSC::Interpreter::cti_op_urshift):
+ (JSC::Interpreter::cti_op_bitxor):
+ (JSC::Interpreter::cti_op_bitor):
+ (JSC::Interpreter::cti_op_push_scope):
+ (JSC::Interpreter::cti_op_is_undefined):
+ (JSC::Interpreter::cti_op_is_boolean):
+ (JSC::Interpreter::cti_op_is_number):
+ (JSC::Interpreter::cti_op_to_jsnumber):
+ (JSC::Interpreter::cti_op_in):
+ (JSC::Interpreter::cti_op_put_by_index):
+ (JSC::Interpreter::cti_op_switch_imm):
+ (JSC::Interpreter::cti_op_switch_char):
+ (JSC::Interpreter::cti_op_switch_string):
+ (JSC::Interpreter::cti_op_del_by_val):
+ (JSC::Interpreter::cti_op_put_getter):
+ (JSC::Interpreter::cti_op_put_setter):
+ (JSC::Interpreter::cti_op_new_error):
+ * interpreter/Interpreter.h:
+ (JSC::Interpreter::isJSArray):
+ (JSC::Interpreter::isJSString):
+ (JSC::Interpreter::isJSByteArray):
+ * interpreter/Register.h:
+ (JSC::Register::marked):
+ (JSC::Register::mark):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::getConstantOperandImmediateInt):
+ (JSC::JIT::isOperandConstantImmediateInt):
+ * jsc.cpp:
+ (functionPrint):
+ (functionDebug):
+ (functionRun):
+ (functionLoad):
+ (runWithScripts):
+ (runInteractive):
+ * parser/Nodes.cpp:
+ (JSC::processClauseList):
+ * profiler/ProfileGenerator.cpp:
+ (JSC::ProfileGenerator::addParentForConsoleStart):
+ * profiler/Profiler.cpp:
+ (JSC::Profiler::createCallIdentifier):
+ * runtime/ArrayConstructor.cpp:
+ (JSC::constructArrayWithSizeQuirk):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToString):
+ (JSC::arrayProtoFuncToLocaleString):
+ (JSC::arrayProtoFuncJoin):
+ (JSC::arrayProtoFuncConcat):
+ (JSC::arrayProtoFuncPop):
+ (JSC::arrayProtoFuncPush):
+ (JSC::arrayProtoFuncReverse):
+ (JSC::arrayProtoFuncShift):
+ (JSC::arrayProtoFuncSlice):
+ (JSC::arrayProtoFuncSort):
+ (JSC::arrayProtoFuncSplice):
+ (JSC::arrayProtoFuncUnShift):
+ (JSC::arrayProtoFuncFilter):
+ (JSC::arrayProtoFuncMap):
+ (JSC::arrayProtoFuncEvery):
+ (JSC::arrayProtoFuncForEach):
+ (JSC::arrayProtoFuncSome):
+ (JSC::arrayProtoFuncIndexOf):
+ (JSC::arrayProtoFuncLastIndexOf):
+ * runtime/BooleanConstructor.cpp:
+ (JSC::constructBoolean):
+ (JSC::callBooleanConstructor):
+ * runtime/BooleanPrototype.cpp:
+ (JSC::booleanProtoFuncToString):
+ (JSC::booleanProtoFuncValueOf):
+ * runtime/Collector.cpp:
+ (JSC::Heap::protect):
+ (JSC::Heap::unprotect):
+ (JSC::Heap::heap):
+ (JSC::Heap::collect):
+ (JSC::typeName):
+ * runtime/Completion.cpp:
+ (JSC::evaluate):
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+ (JSC::dateParse):
+ (JSC::dateUTC):
+ * runtime/DateInstance.h:
+ (JSC::DateInstance::internalNumber):
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+ (JSC::fillStructuresUsingTimeArgs):
+ (JSC::fillStructuresUsingDateArgs):
+ (JSC::dateProtoFuncToString):
+ (JSC::dateProtoFuncToUTCString):
+ (JSC::dateProtoFuncToDateString):
+ (JSC::dateProtoFuncToTimeString):
+ (JSC::dateProtoFuncToLocaleString):
+ (JSC::dateProtoFuncToLocaleDateString):
+ (JSC::dateProtoFuncToLocaleTimeString):
+ (JSC::dateProtoFuncGetTime):
+ (JSC::dateProtoFuncGetFullYear):
+ (JSC::dateProtoFuncGetUTCFullYear):
+ (JSC::dateProtoFuncToGMTString):
+ (JSC::dateProtoFuncGetMonth):
+ (JSC::dateProtoFuncGetUTCMonth):
+ (JSC::dateProtoFuncGetDate):
+ (JSC::dateProtoFuncGetUTCDate):
+ (JSC::dateProtoFuncGetDay):
+ (JSC::dateProtoFuncGetUTCDay):
+ (JSC::dateProtoFuncGetHours):
+ (JSC::dateProtoFuncGetUTCHours):
+ (JSC::dateProtoFuncGetMinutes):
+ (JSC::dateProtoFuncGetUTCMinutes):
+ (JSC::dateProtoFuncGetSeconds):
+ (JSC::dateProtoFuncGetUTCSeconds):
+ (JSC::dateProtoFuncGetMilliSeconds):
+ (JSC::dateProtoFuncGetUTCMilliseconds):
+ (JSC::dateProtoFuncGetTimezoneOffset):
+ (JSC::dateProtoFuncSetTime):
+ (JSC::setNewValueFromTimeArgs):
+ (JSC::setNewValueFromDateArgs):
+ (JSC::dateProtoFuncSetYear):
+ (JSC::dateProtoFuncGetYear):
+ * runtime/ErrorConstructor.cpp:
+ (JSC::constructError):
+ * runtime/ErrorPrototype.cpp:
+ (JSC::errorProtoFuncToString):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createError):
+ (JSC::createErrorMessage):
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncToString):
+ (JSC::functionProtoFuncApply):
+ (JSC::functionProtoFuncCall):
+ * runtime/GetterSetter.cpp:
+ (JSC::GetterSetter::toObject):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::getOwnPropertySlot):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::put):
+ (JSC::JSArray::mark):
+ (JSC::JSArray::sort):
+ (JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):
+ (JSC::JSArray::compactForSorting):
+ * runtime/JSByteArray.h:
+ (JSC::JSByteArray::setIndex):
+ * runtime/JSCell.h:
+ (JSC::asCell):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::call):
+ (JSC::JSFunction::construct):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::markIfNeeded):
+ (JSC::lastInPrototypeChain):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::encode):
+ (JSC::decode):
+ (JSC::globalFuncEval):
+ (JSC::globalFuncParseInt):
+ (JSC::globalFuncParseFloat):
+ (JSC::globalFuncIsNaN):
+ (JSC::globalFuncIsFinite):
+ (JSC::globalFuncEscape):
+ (JSC::globalFuncUnescape):
+ (JSC::globalFuncJSCPrint):
+ * runtime/JSImmediate.cpp:
+ (JSC::JSImmediate::toThisObject):
+ (JSC::JSImmediate::toObject):
+ (JSC::JSImmediate::prototype):
+ (JSC::JSImmediate::toString):
+ * runtime/JSImmediate.h:
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::mark):
+ (JSC::JSObject::put):
+ (JSC::callDefaultValueFunction):
+ (JSC::JSObject::getPrimitiveNumber):
+ (JSC::JSObject::defineGetter):
+ (JSC::JSObject::defineSetter):
+ (JSC::JSObject::lookupGetter):
+ (JSC::JSObject::lookupSetter):
+ (JSC::JSObject::hasInstance):
+ (JSC::JSObject::toNumber):
+ (JSC::JSObject::toString):
+ * runtime/JSObject.h:
+ (JSC::JSObject::JSObject):
+ (JSC::JSObject::inlineGetOwnPropertySlot):
+ (JSC::JSObject::getOwnPropertySlotForWrite):
+ (JSC::JSObject::getPropertySlot):
+ (JSC::JSValuePtr::get):
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::create):
+ * runtime/JSString.cpp:
+ (JSC::JSString::getOwnPropertySlot):
+ * runtime/JSValue.h:
+ * runtime/JSWrapperObject.cpp:
+ (JSC::JSWrapperObject::mark):
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::setInternalValue):
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncAbs):
+ (JSC::mathProtoFuncACos):
+ (JSC::mathProtoFuncASin):
+ (JSC::mathProtoFuncATan):
+ (JSC::mathProtoFuncATan2):
+ (JSC::mathProtoFuncCeil):
+ (JSC::mathProtoFuncCos):
+ (JSC::mathProtoFuncExp):
+ (JSC::mathProtoFuncFloor):
+ (JSC::mathProtoFuncLog):
+ (JSC::mathProtoFuncMax):
+ (JSC::mathProtoFuncMin):
+ (JSC::mathProtoFuncPow):
+ (JSC::mathProtoFuncRound):
+ (JSC::mathProtoFuncSin):
+ (JSC::mathProtoFuncSqrt):
+ (JSC::mathProtoFuncTan):
+ * runtime/NativeErrorConstructor.cpp:
+ (JSC::NativeErrorConstructor::NativeErrorConstructor):
+ (JSC::NativeErrorConstructor::construct):
+ * runtime/NumberConstructor.cpp:
+ (JSC::constructWithNumberConstructor):
+ (JSC::callNumberConstructor):
+ * runtime/NumberPrototype.cpp:
+ (JSC::numberProtoFuncToString):
+ (JSC::numberProtoFuncToLocaleString):
+ (JSC::numberProtoFuncValueOf):
+ (JSC::numberProtoFuncToFixed):
+ (JSC::numberProtoFuncToExponential):
+ (JSC::numberProtoFuncToPrecision):
+ * runtime/ObjectConstructor.cpp:
+ (JSC::constructObject):
+ * runtime/ObjectPrototype.cpp:
+ (JSC::objectProtoFuncValueOf):
+ (JSC::objectProtoFuncHasOwnProperty):
+ (JSC::objectProtoFuncIsPrototypeOf):
+ (JSC::objectProtoFuncDefineGetter):
+ (JSC::objectProtoFuncDefineSetter):
+ (JSC::objectProtoFuncLookupGetter):
+ (JSC::objectProtoFuncLookupSetter):
+ (JSC::objectProtoFuncPropertyIsEnumerable):
+ (JSC::objectProtoFuncToLocaleString):
+ (JSC::objectProtoFuncToString):
+ * runtime/Operations.h:
+ (JSC::JSValuePtr::equalSlowCaseInline):
+ (JSC::JSValuePtr::strictEqual):
+ (JSC::JSValuePtr::strictEqualSlowCaseInline):
+ * runtime/Protect.h:
+ (JSC::gcProtect):
+ (JSC::gcUnprotect):
+ * runtime/RegExpConstructor.cpp:
+ (JSC::setRegExpConstructorInput):
+ (JSC::setRegExpConstructorMultiline):
+ (JSC::constructRegExp):
+ * runtime/RegExpObject.cpp:
+ (JSC::setRegExpObjectLastIndex):
+ (JSC::RegExpObject::match):
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncTest):
+ (JSC::regExpProtoFuncExec):
+ (JSC::regExpProtoFuncCompile):
+ (JSC::regExpProtoFuncToString):
+ * runtime/StringConstructor.cpp:
+ (JSC::stringFromCharCodeSlowCase):
+ (JSC::stringFromCharCode):
+ (JSC::constructWithStringConstructor):
+ (JSC::callStringConstructor):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncReplace):
+ (JSC::stringProtoFuncToString):
+ (JSC::stringProtoFuncCharAt):
+ (JSC::stringProtoFuncCharCodeAt):
+ (JSC::stringProtoFuncConcat):
+ (JSC::stringProtoFuncIndexOf):
+ (JSC::stringProtoFuncLastIndexOf):
+ (JSC::stringProtoFuncMatch):
+ (JSC::stringProtoFuncSearch):
+ (JSC::stringProtoFuncSlice):
+ (JSC::stringProtoFuncSplit):
+ (JSC::stringProtoFuncSubstr):
+ (JSC::stringProtoFuncSubstring):
+ (JSC::stringProtoFuncToLowerCase):
+ (JSC::stringProtoFuncToUpperCase):
+ (JSC::stringProtoFuncLocaleCompare):
+ (JSC::stringProtoFuncBig):
+ (JSC::stringProtoFuncSmall):
+ (JSC::stringProtoFuncBlink):
+ (JSC::stringProtoFuncBold):
+ (JSC::stringProtoFuncFixed):
+ (JSC::stringProtoFuncItalics):
+ (JSC::stringProtoFuncStrike):
+ (JSC::stringProtoFuncSub):
+ (JSC::stringProtoFuncSup):
+ (JSC::stringProtoFuncFontcolor):
+ (JSC::stringProtoFuncFontsize):
+ (JSC::stringProtoFuncAnchor):
+ (JSC::stringProtoFuncLink):
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+ (JSC::Structure::getEnumerablePropertyNames):
+ (JSC::Structure::createCachedPrototypeChain):
+ * runtime/Structure.h:
+ (JSC::Structure::mark):
+ * runtime/StructureChain.cpp:
+ (JSC::StructureChain::StructureChain):
+
+2009-01-19 Darin Adler <darin@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Bug 23409: REGRESSION: RegExp 'replace()' function improperly processes '$$'
+ <https://bugs.webkit.org/show_bug.cgi?id=23409>
+ <rdar://problem/6505723>
+
+ Test: fast/js/string-replace-3.html
+
+ * runtime/StringPrototype.cpp:
+ (JSC::substituteBackreferences): Remove code that adds an extra $ -- not sure
+ how this ever worked.
+
+2009-01-16 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ On x86-64 jit, cache JSImmedate::TagMask & JSImmedate::TagTypeNumber in
+ registers, save reloading them every time they're used.
+
+ Draws x86-64 jit performance close to that of i386 jit.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::subPtr):
+ (JSC::MacroAssembler::jnzPtr):
+ (JSC::MacroAssembler::jzPtr):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitJumpIfJSCell):
+ (JSC::JIT::emitJumpIfNotJSCell):
+ (JSC::JIT::emitJumpIfImmediateNumber):
+ (JSC::JIT::emitJumpIfNotImmediateNumber):
+ (JSC::JIT::emitJumpIfImmediateInteger):
+ (JSC::JIT::emitJumpIfNotImmediateInteger):
+ (JSC::JIT::emitFastArithIntToImmNoCheck):
+
+2009-01-16 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Add support to x86-64 JIT for inline double precision arithmetic ops.
+ +5/6% on x86-64, JIT enabled, sunspider.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::addPtr):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::movq_rr):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileFastArith_op_pre_inc):
+ (JSC::JIT::compileBinaryArithOp):
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ (JSC::JIT::compileFastArith_op_add):
+ (JSC::JIT::compileFastArithSlow_op_add):
+ (JSC::JIT::compileFastArith_op_mul):
+ (JSC::JIT::compileFastArithSlow_op_mul):
+ (JSC::JIT::compileFastArith_op_sub):
+ (JSC::JIT::compileFastArithSlow_op_sub):
+ * parser/ResultType.h:
+ (JSC::ResultType::isReusable):
+ (JSC::ResultType::isInt32):
+ (JSC::ResultType::definitelyIsNumber):
+ (JSC::ResultType::mightBeNumber):
+ (JSC::ResultType::isNotNumber):
+ (JSC::ResultType::unknownType):
+
+2009-01-16 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Fixes for SamplingTool.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23390
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::storePtr):
+ * bytecode/SamplingTool.cpp:
+ (JSC::SamplingTool::run):
+ (JSC::SamplingTool::dump):
+ * bytecode/SamplingTool.h:
+ (JSC::SamplingTool::encodeSample):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JSC::JIT::samplingToolTrackCodeBlock):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitCTICall_internal):
+
+2009-01-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Fixed <rdar://problem/6452301> REGRESSION: Latest WebKit nightlies
+ turn "c" into "" when stripping \\c_ character
+
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::Parser::consumeEscape): Mimic a Firefox quirk when parsing
+ control escapes inside character classes.
+
+2009-01-16 Adam Roben <aroben@apple.com>
+
+ Windows build fix
+
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::Parser::parseParentheses): Removed unreachable code.
+
+2009-01-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Fixed <rdar://problem/6471394> REGRESSION (r39164): Discarding quantifier
+ on assertion gives incorrect result (23075)
+
+ https://bugs.webkit.org/show_bug.cgi?id=23075
+
+ * pcre/pcre_compile.cpp:
+ (compileBranch): Throw away an assertion if it's followed by a quantifier
+ with a 0 minimum, to match SpiderMonkey, v8, and the ECMA spec.
+
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::Parser::parseParentheses): Fall back on PCRE for the rare
+ case of an assertion with a quantifier with a 0 minimum, since we
+ don't handle quantified subexpressions yet, and in this special case,
+ we can't just throw away the quantifier.
+
+2009-01-15 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Add support in ResultType to track that the results of bitops
+ are always of type int32_t.
+
+ * parser/Nodes.cpp:
+ (JSC::ReadModifyResolveNode::emitBytecode):
+ (JSC::ReadModifyDotNode::emitBytecode):
+ (JSC::ReadModifyBracketNode::emitBytecode):
+ * parser/Nodes.h:
+ (JSC::ExpressionNode::):
+ (JSC::BooleanNode::):
+ (JSC::NumberNode::):
+ (JSC::StringNode::):
+ (JSC::PrePostResolveNode::):
+ (JSC::TypeOfResolveNode::):
+ (JSC::TypeOfValueNode::):
+ (JSC::UnaryPlusNode::):
+ (JSC::NegateNode::):
+ (JSC::BitwiseNotNode::):
+ (JSC::LogicalNotNode::):
+ (JSC::MultNode::):
+ (JSC::DivNode::):
+ (JSC::ModNode::):
+ (JSC::SubNode::):
+ (JSC::LeftShiftNode::):
+ (JSC::RightShiftNode::):
+ (JSC::UnsignedRightShiftNode::):
+ (JSC::LessNode::):
+ (JSC::GreaterNode::):
+ (JSC::LessEqNode::):
+ (JSC::GreaterEqNode::):
+ (JSC::InstanceOfNode::):
+ (JSC::EqualNode::):
+ (JSC::NotEqualNode::):
+ (JSC::StrictEqualNode::):
+ (JSC::NotStrictEqualNode::):
+ (JSC::BitAndNode::):
+ (JSC::BitOrNode::):
+ (JSC::BitXOrNode::):
+ (JSC::LogicalOpNode::):
+ * parser/ResultType.h:
+ (JSC::ResultType::isInt32):
+ (JSC::ResultType::isNotNumber):
+ (JSC::ResultType::booleanType):
+ (JSC::ResultType::numberType):
+ (JSC::ResultType::numberTypeCanReuse):
+ (JSC::ResultType::numberTypeCanReuseIsInt32):
+ (JSC::ResultType::stringOrNumberTypeCanReuse):
+ (JSC::ResultType::stringType):
+ (JSC::ResultType::unknownType):
+ (JSC::ResultType::forAdd):
+ (JSC::ResultType::forBitOp):
+ (JSC::OperandTypes::OperandTypes):
+
+2009-01-15 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Add support for integer addition, subtraction and multiplication
+ in JIT code on x86-64.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::mul32):
+ (JSC::MacroAssembler::sub32):
+ (JSC::MacroAssembler::joMul32):
+ (JSC::MacroAssembler::joSub32):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileFastArith_op_add):
+ (JSC::JIT::compileFastArithSlow_op_add):
+ (JSC::JIT::compileFastArith_op_mul):
+ (JSC::JIT::compileFastArithSlow_op_mul):
+ (JSC::JIT::compileFastArith_op_sub):
+ (JSC::JIT::compileFastArithSlow_op_sub):
+
+2009-01-15 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ On x86-64 allow JSImmediate to encode 64-bit double precision values.
+ This patch only affects builds that set USE(ALTERNATE_JSIMMEDIATE).
+ Updates the implementation of JSValuePtr:: and JSImmediate:: methods
+ that operate on neumeric values to be be aware of the new representation.
+ When this representation is in use, the class JSNumberCell is redundant
+ and is compiled out.
+
+ The format of the new immediate representation is documented in JSImmediate.h.
+
+ * JavaScriptCore.exp:
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::subPtr):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::subq_rr):
+ (JSC::X86Assembler::movq_rr):
+ (JSC::X86Assembler::ucomisd_rr):
+ (JSC::X86Assembler::X86InstructionFormatter::twoByteOp64):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_op_stricteq):
+ (JSC::Interpreter::cti_op_nstricteq):
+ * jit/JIT.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileFastArith_op_lshift):
+ (JSC::JIT::compileFastArith_op_rshift):
+ (JSC::JIT::compileFastArith_op_bitand):
+ (JSC::JIT::compileFastArith_op_mod):
+ (JSC::JIT::compileFastArith_op_add):
+ (JSC::JIT::compileFastArith_op_mul):
+ (JSC::JIT::compileFastArith_op_post_inc):
+ (JSC::JIT::compileFastArith_op_post_dec):
+ (JSC::JIT::compileFastArith_op_pre_inc):
+ (JSC::JIT::compileFastArith_op_pre_dec):
+ (JSC::JIT::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::JIT::compileBinaryArithOp):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitJumpIfBothJSCells):
+ (JSC::JIT::emitJumpIfEitherNumber):
+ (JSC::JIT::emitJumpIfNotEitherNumber):
+ (JSC::JIT::emitJumpIfImmediateIntegerNumber):
+ (JSC::JIT::emitJumpIfNotImmediateIntegerNumber):
+ (JSC::JIT::emitJumpIfNotImmediateIntegerNumbers):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmediateIntegerNumber):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmediateIntegerNumbers):
+ (JSC::JIT::emitFastArithDeTagImmediate):
+ (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::JIT::emitFastArithReTagImmediate):
+ (JSC::JIT::emitFastArithIntToImmNoCheck):
+ * runtime/JSCell.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSImmediate.cpp:
+ (JSC::JSImmediate::toThisObject):
+ (JSC::JSImmediate::toObject):
+ (JSC::JSImmediate::toString):
+ * runtime/JSImmediate.h:
+ (JSC::wtf_reinterpret_cast):
+ (JSC::JSImmediate::isNumber):
+ (JSC::JSImmediate::isIntegerNumber):
+ (JSC::JSImmediate::isDoubleNumber):
+ (JSC::JSImmediate::isPositiveIntegerNumber):
+ (JSC::JSImmediate::areBothImmediateIntegerNumbers):
+ (JSC::JSImmediate::makeInt):
+ (JSC::JSImmediate::makeDouble):
+ (JSC::JSImmediate::doubleValue):
+ (JSC::doubleToBoolean):
+ (JSC::JSImmediate::toBoolean):
+ (JSC::JSImmediate::getTruncatedUInt32):
+ (JSC::JSImmediate::makeOutOfIntegerRange):
+ (JSC::JSImmediate::from):
+ (JSC::JSImmediate::getTruncatedInt32):
+ (JSC::JSImmediate::toDouble):
+ (JSC::JSImmediate::getUInt32):
+ (JSC::JSValuePtr::isInt32Fast):
+ (JSC::JSValuePtr::isUInt32Fast):
+ (JSC::JSValuePtr::areBothInt32Fast):
+ (JSC::JSFastMath::canDoFastBitwiseOperations):
+ (JSC::JSFastMath::xorImmediateNumbers):
+ (JSC::JSFastMath::canDoFastRshift):
+ (JSC::JSFastMath::canDoFastUrshift):
+ (JSC::JSFastMath::rightShiftImmediateNumbers):
+ (JSC::JSFastMath::canDoFastAdditiveOperations):
+ (JSC::JSFastMath::addImmediateNumbers):
+ (JSC::JSFastMath::subImmediateNumbers):
+ * runtime/JSNumberCell.cpp:
+ (JSC::jsNumberCell):
+ * runtime/JSNumberCell.h:
+ (JSC::createNumberStructure):
+ (JSC::isNumberCell):
+ (JSC::asNumberCell):
+ (JSC::jsNumber):
+ (JSC::JSValuePtr::isDoubleNumber):
+ (JSC::JSValuePtr::getDoubleNumber):
+ (JSC::JSValuePtr::isNumber):
+ (JSC::JSValuePtr::uncheckedGetNumber):
+ (JSC::jsNaN):
+ (JSC::JSValuePtr::getNumber):
+ (JSC::JSValuePtr::numberToInt32):
+ (JSC::JSValuePtr::numberToUInt32):
+ * runtime/JSValue.h:
+ * runtime/NumberConstructor.cpp:
+ (JSC::numberConstructorNegInfinity):
+ (JSC::numberConstructorPosInfinity):
+ (JSC::numberConstructorMaxValue):
+ (JSC::numberConstructorMinValue):
+ * runtime/NumberObject.cpp:
+ (JSC::constructNumber):
+ * runtime/NumberObject.h:
+ * runtime/Operations.h:
+ (JSC::JSValuePtr::equal):
+ (JSC::JSValuePtr::equalSlowCaseInline):
+ (JSC::JSValuePtr::strictEqual):
+ (JSC::JSValuePtr::strictEqualSlowCaseInline):
+ * wtf/Platform.h:
+
+2009-01-15 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ <rdar://problem/6045018>
+ REGRESSION (r34838): JavaScript objects appear to be leaked after loading google.com
+
+ Subtract the number of JSStrings cached in SmallStrings when calculating the
+ number of live JSObjects.
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::objectCount):
+ * runtime/SmallStrings.cpp:
+ (JSC::SmallStrings::count):
+ * runtime/SmallStrings.h:
+
+2009-01-15 Sam Weinig <sam@webkit.org>
+
+ Fix Qt build.
+
+ * runtime/Collector.cpp:
+
+2009-01-15 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Fix crash seen running fast/canvas.
+
+ Make sure to mark the ScopeNode and CodeBlock being created
+ in the re-parse for exception information.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::reparseForExceptionInfoIfNecessary):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::mark):
+ * runtime/Collector.cpp:
+ (JSC::Heap::collect):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+
+2009-01-15 Craig Schlenter <craig.schlenter@gmail.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23347
+ Compilation of JavaScriptCore/wtf/ThreadingPthreads.cpp fails on Linux
+
+ * wtf/ThreadingPthreads.cpp: included limits.h as INT_MAX is defined there.
+
+2009-01-15 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 23225: REGRESSION: Assertion failure in reparseInPlace() (m_sourceElements) at sfgate.com
+ <https://bugs.webkit.org/show_bug.cgi?id=23225> <rdar://problem/6487432>
+
+ Character position for open and closing brace was incorrectly referencing m_position to
+ record their position in a source document, however this is unsafe as BOMs may lead to
+ m_position being an arbitrary position from the real position of the current character.
+
+ * parser/Lexer.cpp:
+ (JSC::Lexer::matchPunctuator):
+
+2009-01-14 David Kilzer <ddkilzer@apple.com>
+
+ Bug 23153: JSC build always touches JavaScriptCore/docs/bytecode.html
+
+ <https://bugs.webkit.org/show_bug.cgi?id=23153>
+
+ Reviewed by Darin Adler.
+
+ Instead of building bytecode.html into ${SRCROOT}/docs/bytecode.html, build it
+ into ${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore/docs/bytecode.html.
+
+ Also fixes make-bytecode-docs.pl to actually generate documentation.
+
+ * DerivedSources.make: Changed bytecode.html to be built into local docs
+ directory in ${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Added "/docs" to the end of the
+ "mkdir -p" command so that the docs subdirectory is automatically created.
+ * docs/make-bytecode-docs.pl: Changed BEGIN_OPCODE to DEFINE_OPCODE so that
+ documentation is actually generated.
+
+2009-01-14 Adam Treat <adam.treat@torchmobile.com>
+
+ Build fix for Qt from Dmitry Titov.
+
+ * wtf/ThreadingQt.cpp:
+ (WTF::ThreadCondition::timedWait):
+
+2009-01-14 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Bug 22903: REGRESSION (r36267): visiting this site reliably crashes WebKit nightly
+
+ EvalCodeBlock's do not reference the functions that are declared inside the eval
+ code, this means that simply marking the EvalCodeBlock through the global object
+ is insufficient to mark the declared functions. This patch corrects this by
+ explicitly marking the CodeBlocks of all the functions declared in the cached
+ EvalNode.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::mark):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::hasFunctions):
+ * bytecode/EvalCodeCache.h:
+ (JSC::EvalCodeCache::mark):
+ * parser/Nodes.cpp:
+ (JSC::ScopeNodeData::mark):
+ (JSC::EvalNode::mark):
+ * parser/Nodes.h:
+
+2009-01-14 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23312
+ Implement MessageQueue::waitForMessageTimed()
+ Also fixed ThreadCondition::timedWait() to take absolute time, as discussed on webkit-dev.
+ Win32 version of timedWait still has to be implemented.
+
+ * wtf/MessageQueue.h:
+ (WTF::MessageQueueWaitResult: new enum for the result of MessageQueue::waitForMessageTimed.
+ (WTF::MessageQueue::waitForMessage):
+ (WTF::MessageQueue::waitForMessageTimed): New method.
+ * wtf/Threading.h:
+ * wtf/ThreadingGtk.cpp:
+ (WTF::ThreadCondition::timedWait): changed to use absolute time instead of interval.
+ * wtf/ThreadingNone.cpp:
+ (WTF::ThreadCondition::timedWait): ditto.
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::ThreadCondition::timedWait): ditto.
+ * wtf/ThreadingQt.cpp:
+ (WTF::ThreadCondition::timedWait): ditto.
+ * wtf/ThreadingWin.cpp:
+ (WTF::ThreadCondition::timedWait): ditto. The actual Win32 code is still to be implemented.
+
+2009-01-14 Dean McNamee <deanm@chromium.org>
+
+ Reviewed by Darin Adler and Oliver hunt.
+
+ Correctly match allocation functions by implementing a custom deref().
+
+ https://bugs.webkit.org/show_bug.cgi?id=23315
+
+ * runtime/ByteArray.h:
+ (JSC::ByteArray::deref):
+ (JSC::ByteArray::ByteArray):
+
+2009-01-14 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by John Sullivan.
+
+ - update copyright
+
+ * Info.plist:
+
+2009-01-13 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Darin Adler and Oliver Hunt.
+
+ <rdar://problem/6489314> REGRESSION: Business widget's front side
+ fails to render correctly when flipping widget
+
+ The problem here is that parseInt was parsing NaN as 0. This patch
+ corrects that by parsing NaN as NaN. This matches our old behavior
+ and Firefox.
+
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncParseInt):
+
+2009-01-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fix for: https://bugs.webkit.org/show_bug.cgi?id=23292
+
+ Implementation of two argument canDoFastAdditiveOperations does not correlate well with reality.
+
+ * runtime/JSImmediate.h:
+ (JSC::JSFastMath::canDoFastAdditiveOperations):
+
+2009-01-13 Zalan Bujtas <zbujtas@gmail.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23290
+ Fix JSImmediate::isImmediate(src) to !src->isCell()
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2009-01-13 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23281
+ Fix the Chromium Win build.
+ Need to use PLATFORM(WIN_OS) instead of PLATFORM(WIN).
+ Moved GTK and WX up in #if sequence because they could come with WIN_OS too,
+ while they have their own implementation even on Windows.
+
+ * wtf/CurrentTime.cpp:
+ (WTF::currentTime):
+
+2009-01-12 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Make the JSImmediate interface private.
+
+ All manipulation of JS values should be through the JSValuePtr class, not by using JSImmediate
+ directly. The key missing methods on JSValuePtr are:
+
+ * isCell() - check for values that are JSCell*s, and as such where asCell() may be used.
+ * isInt32Fast() getInt32Fast() - fast check/access for integer immediates.
+ * isUInt32Fast() getUInt32Fast() - ditto for unsigned integer immediates.
+
+ The JIT is allowed full access to JSImmediate, since it needs to be able to directly
+ manipulate JSValuePtrs. The Interpreter is provided access to perform operations directly
+ on JSValuePtrs through the new JSFastMath interface.
+
+ No performance impact.
+
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::toNumber):
+ * API/JSValueRef.cpp:
+ (JSValueIsEqual):
+ (JSValueIsStrictEqual):
+ * JavaScriptCore.exp:
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::isKnownNotImmediate):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::keyForImmediateSwitch):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::JSValueHashTraits::constructDeletedValue):
+ (JSC::BytecodeGenerator::JSValueHashTraits::isDeletedValue):
+ * interpreter/Interpreter.cpp:
+ (JSC::jsLess):
+ (JSC::jsLessEq):
+ (JSC::jsAdd):
+ (JSC::jsIsObjectType):
+ (JSC::cachePrototypeChain):
+ (JSC::Interpreter::tryCachePutByID):
+ (JSC::Interpreter::tryCacheGetByID):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::tryCTICachePutByID):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::Interpreter::cti_op_add):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list):
+ (JSC::Interpreter::cti_op_instanceof):
+ (JSC::Interpreter::cti_op_mul):
+ (JSC::Interpreter::cti_op_get_by_val):
+ (JSC::Interpreter::cti_op_get_by_val_byte_array):
+ (JSC::Interpreter::cti_op_sub):
+ (JSC::Interpreter::cti_op_put_by_val):
+ (JSC::Interpreter::cti_op_put_by_val_array):
+ (JSC::Interpreter::cti_op_put_by_val_byte_array):
+ (JSC::Interpreter::cti_op_negate):
+ (JSC::Interpreter::cti_op_div):
+ (JSC::Interpreter::cti_op_eq):
+ (JSC::Interpreter::cti_op_lshift):
+ (JSC::Interpreter::cti_op_bitand):
+ (JSC::Interpreter::cti_op_rshift):
+ (JSC::Interpreter::cti_op_bitnot):
+ (JSC::Interpreter::cti_op_neq):
+ (JSC::Interpreter::cti_op_urshift):
+ (JSC::Interpreter::cti_op_call_eval):
+ (JSC::Interpreter::cti_op_throw):
+ (JSC::Interpreter::cti_op_is_undefined):
+ (JSC::Interpreter::cti_op_stricteq):
+ (JSC::Interpreter::cti_op_nstricteq):
+ (JSC::Interpreter::cti_op_switch_imm):
+ (JSC::Interpreter::cti_vm_throw):
+ * interpreter/Interpreter.h:
+ (JSC::Interpreter::isJSArray):
+ (JSC::Interpreter::isJSString):
+ (JSC::Interpreter::isJSByteArray):
+ * jit/JIT.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ (JSC::JIT::isStrictEqCaseHandledInJITCode):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileFastArith_op_rshift):
+ (JSC::JIT::compileFastArith_op_bitand):
+ (JSC::JIT::compileFastArith_op_mod):
+ * jit/JITCall.cpp:
+ (JSC::JIT::unlinkCall):
+ (JSC::JIT::compileOpCall):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::getConstantOperandImmediateInt):
+ (JSC::JIT::isOperandConstantImmediateInt):
+ * parser/Nodes.cpp:
+ (JSC::processClauseList):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncIndexOf):
+ (JSC::arrayProtoFuncLastIndexOf):
+ * runtime/BooleanPrototype.cpp:
+ (JSC::booleanProtoFuncValueOf):
+ * runtime/Collector.cpp:
+ (JSC::Heap::protect):
+ (JSC::Heap::unprotect):
+ (JSC::Heap::heap):
+ * runtime/JSByteArray.cpp:
+ (JSC::JSByteArray::getOwnPropertySlot):
+ * runtime/JSByteArray.h:
+ (JSC::JSByteArray::getIndex):
+ * runtime/JSCell.cpp:
+ * runtime/JSCell.h:
+ (JSC::JSValuePtr::isNumberCell):
+ (JSC::JSValuePtr::asCell):
+ (JSC::JSValuePtr::isNumber):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncParseInt):
+ * runtime/JSImmediate.h:
+ (JSC::js0):
+ (JSC::jsImpossibleValue):
+ (JSC::JSValuePtr::toInt32):
+ (JSC::JSValuePtr::toUInt32):
+ (JSC::JSValuePtr::isCell):
+ (JSC::JSValuePtr::isInt32Fast):
+ (JSC::JSValuePtr::getInt32Fast):
+ (JSC::JSValuePtr::isUInt32Fast):
+ (JSC::JSValuePtr::getUInt32Fast):
+ (JSC::JSValuePtr::makeInt32Fast):
+ (JSC::JSValuePtr::areBothInt32Fast):
+ (JSC::JSFastMath::canDoFastBitwiseOperations):
+ (JSC::JSFastMath::equal):
+ (JSC::JSFastMath::notEqual):
+ (JSC::JSFastMath::andImmediateNumbers):
+ (JSC::JSFastMath::xorImmediateNumbers):
+ (JSC::JSFastMath::orImmediateNumbers):
+ (JSC::JSFastMath::canDoFastRshift):
+ (JSC::JSFastMath::canDoFastUrshift):
+ (JSC::JSFastMath::rightShiftImmediateNumbers):
+ (JSC::JSFastMath::canDoFastAdditiveOperations):
+ (JSC::JSFastMath::addImmediateNumbers):
+ (JSC::JSFastMath::subImmediateNumbers):
+ (JSC::JSFastMath::incImmediateNumber):
+ (JSC::JSFastMath::decImmediateNumber):
+ * runtime/JSNumberCell.h:
+ (JSC::JSValuePtr::asNumberCell):
+ (JSC::jsNumber):
+ (JSC::JSValuePtr::uncheckedGetNumber):
+ (JSC::JSNumberCell::toInt32):
+ (JSC::JSNumberCell::toUInt32):
+ (JSC::JSValuePtr::toJSNumber):
+ (JSC::JSValuePtr::getNumber):
+ (JSC::JSValuePtr::numberToInt32):
+ (JSC::JSValuePtr::numberToUInt32):
+ * runtime/JSObject.h:
+ (JSC::JSValuePtr::isObject):
+ (JSC::JSValuePtr::get):
+ (JSC::JSValuePtr::put):
+ * runtime/JSValue.cpp:
+ (JSC::JSValuePtr::toInteger):
+ (JSC::JSValuePtr::toIntegerPreserveNaN):
+ * runtime/JSValue.h:
+ * runtime/Operations.cpp:
+ (JSC::JSValuePtr::equalSlowCase):
+ (JSC::JSValuePtr::strictEqualSlowCase):
+ * runtime/Operations.h:
+ (JSC::JSValuePtr::equal):
+ (JSC::JSValuePtr::equalSlowCaseInline):
+ (JSC::JSValuePtr::strictEqual):
+ (JSC::JSValuePtr::strictEqualSlowCaseInline):
+ * runtime/Protect.h:
+ (JSC::gcProtect):
+ (JSC::gcUnprotect):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncCharAt):
+ (JSC::stringProtoFuncCharCodeAt):
+ * runtime/Structure.cpp:
+ (JSC::Structure::createCachedPrototypeChain):
+
+2009-01-12 Kevin Ollivier <kevino@theolliviers.com>
+
+ Since date time functions have moved here, now the wx port JSC
+ needs to depend on wx.
+
+ * jscore.bkl:
+
+2009-01-11 David Levin <levin@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23245
+
+ Add initializeThreading to key places in JS API to ensure that
+ UString is properly initialized.
+
+ * API/JSContextRef.cpp:
+ (JSContextGroupCreate):
+ (JSGlobalContextCreate):
+ * API/JSObjectRef.cpp:
+ (JSClassCreate):
+ * API/JSStringRef.cpp:
+ (JSStringCreateWithCharacters):
+ (JSStringCreateWithUTF8CString):
+ * API/JSStringRefCF.cpp:
+ (JSStringCreateWithCFString):
+
+2009-01-11 David Levin <levin@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23175
+
+ Separate out BaseString information from UString::Rep and make all baseString access go through
+ a member function, so that it may be used for something else (in the future) in the BaseString
+ case.
+
+ * runtime/SmallStrings.cpp:
+ (JSC::SmallStringsStorage::rep):
+ (JSC::SmallStringsStorage::SmallStringsStorage):
+ (JSC::SmallStrings::SmallStrings):
+ (JSC::SmallStrings::mark):
+ Adjust to account for the changes in UString and put the UString in place in
+ SmallStringsStorage to aid in locality of reference among the UChar[] and UString::Rep's.
+
+ * runtime/SmallStrings.h:
+ * runtime/UString.cpp:
+ (JSC::initializeStaticBaseString):
+ (JSC::initializeUString):
+ (JSC::UString::Rep::create):
+ (JSC::UString::Rep::destroy):
+ (JSC::UString::Rep::checkConsistency):
+ (JSC::expandCapacity):
+ (JSC::UString::expandPreCapacity):
+ (JSC::concatenate):
+ (JSC::UString::append):
+ (JSC::UString::operator=):
+ * runtime/UString.h:
+ (JSC::UString::Rep::baseIsSelf):
+ (JSC::UString::Rep::setBaseString):
+ (JSC::UString::Rep::baseString):
+ (JSC::UString::Rep::):
+ (JSC::UString::Rep::null):
+ (JSC::UString::Rep::empty):
+ (JSC::UString::Rep::data):
+ (JSC::UString::cost):
+ Separate out the items out used by base strings from those used in Rep's that only
+ point to base strings. (This potentially saves 24 bytes per Rep.)
+
+2009-01-11 Darin Adler <darin@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Bug 23239: improve handling of unused arguments in JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=23239
+
+ * runtime/DatePrototype.cpp: Moved LocaleDateTimeFormat enum outside #if
+ so we can use this on all platforms. Changed valueOf to share the same
+ function with getTime, since the contents of the two are identical. Removed
+ a FIXME since the idea isn't really specific enough or helpful enough to
+ need to sit here in the source code.
+ (JSC::formatLocaleDate): Changed the Mac version of this function to take
+ the same arguments as the non-Mac version so the caller doesn't have to
+ special-case the two platforms. Also made the formatString array be const;
+ before the characters were, but the array was a modifiable global variable.
+ (JSC::dateProtoFuncToLocaleString): Changed to call the new unified
+ version of formatLocaleDate and remove the ifdef.
+ (JSC::dateProtoFuncToLocaleDateString): Ditto.
+ (JSC::dateProtoFuncToLocaleTimeString): Ditto.
+
+ * runtime/JSNotAnObject.cpp:
+ (JSC::JSNotAnObject::toObject): Use the new ASSERT_UNUSED instead of the
+ old UNUSED_PARAM.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp): Changed to only use UNUSED_PARAM when the parameter
+ is actually unused.
+
+ * wtf/TCSystemAlloc.cpp:
+ (TCMalloc_SystemRelease): Changed to only use UNUSED_PARAM when the parameter
+ is actually unused.
+ (TCMalloc_SystemCommit): Changed to omit the argument names instead of using
+ UNUSED_PARAM.
+
+2009-01-11 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Fix the build (whoops)
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_op_get_by_val):
+
+2009-01-11 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Darin Adler and Anders Carlsson
+
+ Bug 23128: get/put_by_val need to respecialise in the face of ByteArray
+
+ Restructure the code slightly, and add comments per Darin's suggestions
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_op_get_by_val):
+ (JSC::Interpreter::cti_op_get_by_val_byte_array):
+ (JSC::Interpreter::cti_op_put_by_val):
+ (JSC::Interpreter::cti_op_put_by_val_byte_array):
+
+2009-01-11 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ Whoops, I accidentally removed an exception check from fast the
+ fast path for string indexing when i originally landed the
+ byte array logic.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_op_get_by_val):
+
+2009-01-11 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ Bug 23128: get/put_by_val need to respecialise in the face of ByteArray
+ <https://bugs.webkit.org/show_bug.cgi?id=23128>
+
+ Fairly simple patch, add specialised versions of cti_op_get/put_by_val
+ that assume ByteArray, thus avoiding a few branches in the case of bytearray
+ manipulation.
+
+ No effect on SunSpider. 15% win on the original testcase.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_op_get_by_val):
+ (JSC::Interpreter::cti_op_get_by_val_byte_array):
+ (JSC::Interpreter::cti_op_put_by_val):
+ (JSC::Interpreter::cti_op_put_by_val_byte_array):
+ * interpreter/Interpreter.h:
+
+2009-01-11 Alexey Proskuryakov <ap@webkit.org>
+
+ Try to fix Windows build.
+
+ * wtf/CurrentTime.cpp: Added a definition of msPerSecond (previously, this code was in
+ DateMath.cpp, with constant definition in DateTime.h)
+
+2009-01-11 Alexey Proskuryakov <ap@webkit.org>
+
+ Try to fix Windows build.
+
+ * wtf/CurrentTime.cpp: Include <sys/types.h> and <sys/timeb.h>, as MSDN says to.
+
+2009-01-11 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23207
+ Moved currentTime() to from WebCore to WTF.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.exp: added export for WTF::currentTime()
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * runtime/DateMath.cpp:
+ (JSC::getCurrentUTCTimeWithMicroseconds): This function had another implementation of currentTime(), essentially. Now uses WTF version.
+ * wtf/CurrentTime.cpp: Added.
+ (WTF::currentTime):
+ (WTF::highResUpTime):
+ (WTF::lowResUTCTime):
+ (WTF::qpcAvailable):
+ * wtf/CurrentTime.h: Added.
+
+2009-01-09 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Stage two of converting JSValue from a pointer to a class type.
+ Remove the class JSValue. The functionallity has been transitioned
+ into the wrapper class type JSValuePtr.
+
+ The last stage will be to rename JSValuePtr to JSValue, remove the
+ overloaded -> operator, and switch operations on JSValuePtrs from
+ using '->' to use '.' instead.
+
+ * API/APICast.h:
+ * JavaScriptCore.exp:
+ * runtime/JSCell.h:
+ (JSC::asCell):
+ (JSC::JSValuePtr::asCell):
+ (JSC::JSValuePtr::isNumber):
+ (JSC::JSValuePtr::isString):
+ (JSC::JSValuePtr::isGetterSetter):
+ (JSC::JSValuePtr::isObject):
+ (JSC::JSValuePtr::getNumber):
+ (JSC::JSValuePtr::getString):
+ (JSC::JSValuePtr::getObject):
+ (JSC::JSValuePtr::getCallData):
+ (JSC::JSValuePtr::getConstructData):
+ (JSC::JSValuePtr::getUInt32):
+ (JSC::JSValuePtr::getTruncatedInt32):
+ (JSC::JSValuePtr::getTruncatedUInt32):
+ (JSC::JSValuePtr::mark):
+ (JSC::JSValuePtr::marked):
+ (JSC::JSValuePtr::toPrimitive):
+ (JSC::JSValuePtr::getPrimitiveNumber):
+ (JSC::JSValuePtr::toBoolean):
+ (JSC::JSValuePtr::toNumber):
+ (JSC::JSValuePtr::toString):
+ (JSC::JSValuePtr::toObject):
+ (JSC::JSValuePtr::toThisObject):
+ (JSC::JSValuePtr::needsThisConversion):
+ (JSC::JSValuePtr::toThisString):
+ (JSC::JSValuePtr::getJSNumber):
+ * runtime/JSImmediate.h:
+ (JSC::JSValuePtr::isUndefined):
+ (JSC::JSValuePtr::isNull):
+ (JSC::JSValuePtr::isUndefinedOrNull):
+ (JSC::JSValuePtr::isBoolean):
+ (JSC::JSValuePtr::getBoolean):
+ (JSC::JSValuePtr::toInt32):
+ (JSC::JSValuePtr::toUInt32):
+ * runtime/JSNumberCell.h:
+ (JSC::JSValuePtr::uncheckedGetNumber):
+ (JSC::JSValuePtr::toJSNumber):
+ * runtime/JSObject.h:
+ (JSC::JSValuePtr::isObject):
+ (JSC::JSValuePtr::get):
+ (JSC::JSValuePtr::put):
+ * runtime/JSString.h:
+ (JSC::JSValuePtr::toThisJSString):
+ * runtime/JSValue.cpp:
+ (JSC::JSValuePtr::toInteger):
+ (JSC::JSValuePtr::toIntegerPreserveNaN):
+ (JSC::JSValuePtr::toInt32SlowCase):
+ (JSC::JSValuePtr::toUInt32SlowCase):
+ * runtime/JSValue.h:
+ (JSC::JSValuePtr::makeImmediate):
+ (JSC::JSValuePtr::immediateValue):
+ (JSC::JSValuePtr::JSValuePtr):
+ (JSC::JSValuePtr::operator->):
+ (JSC::JSValuePtr::operator bool):
+ (JSC::JSValuePtr::operator==):
+ (JSC::JSValuePtr::operator!=):
+ (JSC::JSValuePtr::encode):
+ (JSC::JSValuePtr::decode):
+ (JSC::JSValuePtr::toFloat):
+ (JSC::JSValuePtr::asValue):
+ (JSC::operator==):
+ (JSC::operator!=):
+
+2009-01-09 David Levin <levin@chromium.org>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23175
+
+ Adjustment to previous patch. Remove call to initilizeThreading from JSGlobalCreate
+ and fix jsc.cpp instead.
+
+ * jsc.cpp:
+ (main):
+ (jscmain):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::create):
+
+2009-01-09 Sam Weinig <sam@webkit.org>
+
+ Roll r39720 back in with a working interpreted mode.
+
+2009-01-09 David Levin <levin@chromium.org>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23175
+
+ Added a template to make the pointer and flags combination
+ in UString more readable and less error prone.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ Added PtrAndFlags.h (and sorted the xcode project file).
+
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add):
+ (JSC::Identifier::addSlowCase):
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ Made the init threading initialize the UString globals. Before
+ these were initilized using {} but that became harder due to the
+ addition of this tempalte class.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::create):
+ * runtime/PropertyNameArray.cpp:
+ (JSC::PropertyNameArray::add):
+ * runtime/UString.cpp:
+ (JSC::initializeStaticBaseString):
+ (JSC::initializeUString):
+ (JSC::UString::Rep::create):
+ (JSC::UString::Rep::createFromUTF8):
+ (JSC::createRep):
+ (JSC::UString::UString):
+ (JSC::concatenate):
+ (JSC::UString::operator=):
+ (JSC::UString::makeNull):
+ (JSC::UString::nullRep):
+ * runtime/UString.h:
+ (JSC::UString::Rep::identifierTable):
+ (JSC::UString::Rep::setIdentifierTable):
+ (JSC::UString::Rep::isStatic):
+ (JSC::UString::Rep::setStatic):
+ (JSC::UString::Rep::):
+ (JSC::UString::Rep::null):
+ (JSC::UString::Rep::empty):
+ (JSC::UString::isNull):
+ (JSC::UString::null):
+ (JSC::UString::UString):
+
+ * wtf/PtrAndFlags.h: Added.
+ (WTF::PtrAndFlags::PtrAndFlags):
+ (WTF::PtrAndFlags::isFlagSet):
+ (WTF::PtrAndFlags::setFlag):
+ (WTF::PtrAndFlags::clearFlag):
+ (WTF::PtrAndFlags::get):
+ (WTF::PtrAndFlags::set):
+ A simple way to layer together a pointer and 2 flags. It relies on the pointer being 4 byte aligned,
+ which should happen for all allocators (due to aligning pointers, int's, etc. on 4 byte boundaries).
+
+2009-01-08 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by -O-l-i-v-e-r- -H-u-n-t- Sam Weinig (sorry, Sam!).
+
+ Encode immediates in the low word of JSValuePtrs, on x86-64.
+
+ On 32-bit platforms a JSValuePtr may represent a 31-bit signed integer.
+ On 64-bit platforms, if USE(ALTERNATE_JSIMMEDIATE) is defined, a full
+ 32-bit integer may be stored in an immediate.
+
+ Presently USE(ALTERNATE_JSIMMEDIATE) uses the same encoding as the default
+ immediate format - the value is left shifted by one, so a one bit tag can
+ be added to indicate the value is an immediate. However this means that
+ values must be commonly be detagged (by right shifting by one) before
+ arithmetic operations can be performed on immediates. This patch modifies
+ the formattting so the the high bits of the immediate mark values as being
+ integer.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::not32):
+ (JSC::MacroAssembler::orPtr):
+ (JSC::MacroAssembler::zeroExtend32ToPtr):
+ (JSC::MacroAssembler::jaePtr):
+ (JSC::MacroAssembler::jbPtr):
+ (JSC::MacroAssembler::jnzPtr):
+ (JSC::MacroAssembler::jzPtr):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::notl_r):
+ (JSC::X86Assembler::testq_i32r):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileFastArith_op_lshift):
+ (JSC::JIT::compileFastArith_op_rshift):
+ (JSC::JIT::compileFastArith_op_bitand):
+ (JSC::JIT::compileFastArithSlow_op_bitand):
+ (JSC::JIT::compileFastArith_op_mod):
+ (JSC::JIT::compileFastArithSlow_op_mod):
+ (JSC::JIT::compileFastArith_op_add):
+ (JSC::JIT::compileFastArith_op_mul):
+ (JSC::JIT::compileFastArith_op_post_inc):
+ (JSC::JIT::compileFastArith_op_post_dec):
+ (JSC::JIT::compileFastArith_op_pre_inc):
+ (JSC::JIT::compileFastArith_op_pre_dec):
+ (JSC::JIT::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::JIT::compileBinaryArithOp):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitJumpIfJSCell):
+ (JSC::JIT::emitJumpIfNotJSCell):
+ (JSC::JIT::emitJumpIfImmNum):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmNum):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmNums):
+ (JSC::JIT::emitFastArithDeTagImmediate):
+ (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::JIT::emitFastArithReTagImmediate):
+ (JSC::JIT::emitFastArithImmToInt):
+ (JSC::JIT::emitFastArithIntToImmNoCheck):
+ (JSC::JIT::emitTagAsBoolImmediate):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::resizePropertyStorage):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+ * runtime/JSImmediate.h:
+ (JSC::JSImmediate::isNumber):
+ (JSC::JSImmediate::isPositiveNumber):
+ (JSC::JSImmediate::areBothImmediateNumbers):
+ (JSC::JSImmediate::xorImmediateNumbers):
+ (JSC::JSImmediate::rightShiftImmediateNumbers):
+ (JSC::JSImmediate::canDoFastAdditiveOperations):
+ (JSC::JSImmediate::addImmediateNumbers):
+ (JSC::JSImmediate::subImmediateNumbers):
+ (JSC::JSImmediate::makeInt):
+ (JSC::JSImmediate::toBoolean):
+ * wtf/Platform.h:
+
+2009-01-08 Sam Weinig <sam@webkit.org>
+
+ Revert r39720. It broke Interpreted mode.
+
+2009-01-08 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23197
+ Delay creating the PCVector until an exception is thrown
+ Part of <rdar://problem/6469060>
+ Don't store exception information for a CodeBlock until first exception is thrown
+
+ - Change the process for re-parsing/re-generating bytecode for exception information
+ to use data from the original CodeBlock (offsets of GlobalResolve instructions) to
+ aid in creating an identical instruction stream on re-parse, instead of padding
+ interchangeable opcodes, which would result in different JITed code.
+ - Fix bug where the wrong ScopeChainNode was used when re-parsing/regenerating from
+ within some odd modified scope chains.
+ - Lazily create the pcVector by re-JITing the regenerated CodeBlock and stealing the
+ the pcVector from it.
+
+ Saves ~2MB on Membuster head.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::reparseForExceptionInfoIfNecessary):
+ (JSC::CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset):
+ (JSC::CodeBlock::hasGlobalResolveInfoAtBytecodeOffset):
+ * bytecode/CodeBlock.h:
+ (JSC::JITCodeRef::JITCodeRef):
+ (JSC::GlobalResolveInfo::GlobalResolveInfo):
+ (JSC::CodeBlock::getBytecodeIndex):
+ (JSC::CodeBlock::addGlobalResolveInstruction):
+ (JSC::CodeBlock::addGlobalResolveInfo):
+ (JSC::CodeBlock::addFunctionRegisterInfo):
+ (JSC::CodeBlock::hasExceptionInfo):
+ (JSC::CodeBlock::pcVector):
+ (JSC::EvalCodeBlock::EvalCodeBlock):
+ (JSC::EvalCodeBlock::baseScopeDepth):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitGetScopedVar):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::setRegeneratingForExceptionInfo):
+ * interpreter/Interpreter.cpp:
+ (JSC::bytecodeOffsetForPC):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::retrieveLastCaller):
+ (JSC::Interpreter::cti_op_instanceof):
+ (JSC::Interpreter::cti_op_call_NotJSFunction):
+ (JSC::Interpreter::cti_op_resolve):
+ (JSC::Interpreter::cti_op_construct_NotJSConstruct):
+ (JSC::Interpreter::cti_op_resolve_func):
+ (JSC::Interpreter::cti_op_resolve_skip):
+ (JSC::Interpreter::cti_op_resolve_global):
+ (JSC::Interpreter::cti_op_resolve_with_base):
+ (JSC::Interpreter::cti_op_throw):
+ (JSC::Interpreter::cti_op_in):
+ (JSC::Interpreter::cti_vm_throw):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * parser/Nodes.cpp:
+ (JSC::EvalNode::generateBytecode):
+ (JSC::EvalNode::bytecodeForExceptionInfoReparse):
+ (JSC::FunctionBodyNode::bytecodeForExceptionInfoReparse):
+ * parser/Nodes.h:
+
+2009-01-08 Jian Li <jianli@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Add Win32 implementation of ThreadSpecific.
+ https://bugs.webkit.org/show_bug.cgi?id=22614
+
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * wtf/ThreadSpecific.h:
+ (WTF::ThreadSpecific::ThreadSpecific):
+ (WTF::ThreadSpecific::~ThreadSpecific):
+ (WTF::ThreadSpecific::get):
+ (WTF::ThreadSpecific::set):
+ (WTF::ThreadSpecific::destroy):
+ * wtf/ThreadSpecificWin.cpp: Added.
+ (WTF::ThreadSpecificThreadExit):
+ * wtf/ThreadingWin.cpp:
+ (WTF::wtfThreadEntryPoint):
+
+2009-01-08 Justin McPherson <justin.mcpherson@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix compilation with Qt on NetBSD.
+
+ * runtime/Collector.cpp:
+ (JSC::currentThreadStackBase): Use PLATFORM(NETBSD) to enter the
+ code path to retrieve the stack base using pthread_attr_get_np.
+ The PTHREAD_NP_H define is not used because the header file does
+ not exist on NetBSD, but the function is declared nevertheless.
+ * wtf/Platform.h: Introduce WTF_PLATFORM_NETBSD.
+
+2009-01-07 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ <rdar://problem/6469060> Don't store exception information for a CodeBlock until first exception is thrown
+
+ Don't initially store exception information (lineNumber/expressionRange/getByIdExcecptionInfo)
+ in CodeBlocks blocks. Instead, re-parse for the data on demand and cache it then.
+
+ One important change that was needed to make this work was to pad op_get_global_var with nops to
+ be the same length as op_resolve_global, since one could be replaced for the other on re-parsing,
+ and we want to keep the offsets bytecode offsets the same.
+
+ 1.3MB improvement on Membuster head.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump): Update op_get_global_var to account for the padding.
+ (JSC::CodeBlock::dumpStatistics): Add more statistic dumping.
+ (JSC::CodeBlock::CodeBlock): Initialize m_exceptionInfo.
+ (JSC::CodeBlock::reparseForExceptionInfoIfNecessary): Re-parses the CodeBlocks
+ associated SourceCode and steals the ExceptionInfo from it.
+ (JSC::CodeBlock::lineNumberForBytecodeOffset): Creates the exception info on demand.
+ (JSC::CodeBlock::expressionRangeForBytecodeOffset): Ditto.
+ (JSC::CodeBlock::getByIdExceptionInfoForBytecodeOffset): Ditto.
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::numberOfExceptionHandlers): Updated to account for m_exceptionInfo indirection.
+ (JSC::CodeBlock::addExceptionHandler): Ditto.
+ (JSC::CodeBlock::exceptionHandler): Ditto.
+ (JSC::CodeBlock::clearExceptionInfo): Ditto.
+ (JSC::CodeBlock::addExpressionInfo): Ditto.
+ (JSC::CodeBlock::addGetByIdExceptionInfo): Ditto.
+ (JSC::CodeBlock::numberOfLineInfos): Ditto.
+ (JSC::CodeBlock::addLineInfo): Ditto.
+ (JSC::CodeBlock::lastLineInfo): Ditto.
+
+ * bytecode/Opcode.h: Change length of op_get_global_var to match op_resolve_global.
+
+ * bytecode/SamplingTool.cpp:
+ (JSC::SamplingTool::dump): Add comment indicating why it is okay not to pass a CallFrame.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate): Clear the exception info after generation for Function and Eval
+ Code when not in regenerate for exception info mode.
+ (JSC::BytecodeGenerator::BytecodeGenerator): Initialize m_regeneratingForExceptionInfo to false.
+ (JSC::BytecodeGenerator::emitGetScopedVar): Pad op_get_global_var with 2 nops.
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::setRegeneratingForExcpeptionInfo): Added.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException): Pass the CallFrame to exception info accessors.
+ (JSC::Interpreter::privateExecute): Ditto.
+ (JSC::Interpreter::retrieveLastCaller): Ditto.
+ (JSC::Interpreter::cti_op_new_error): Ditto.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass): Pass the current bytecode offset instead of hard coding the
+ line number, the stub will do the accessing if it gets called.
+
+ * parser/Nodes.cpp:
+ (JSC::ProgramNode::emitBytecode): Moved.
+ (JSC::ProgramNode::generateBytecode): Moved.
+ (JSC::EvalNode::create): Moved.
+ (JSC::EvalNode::bytecodeForExceptionInfoReparse): Added.
+ (JSC::FunctionBodyNode::generateBytecode): Rename reparse to reparseInPlace.
+ (JSC::FunctionBodyNode::bytecodeForExceptionInfoReparse): Addded.
+
+ * parser/Nodes.h:
+ (JSC::ScopeNode::features): Added getter.
+ * parser/Parser.cpp:
+ (JSC::Parser::reparseInPlace): Renamed from reparse.
+ * parser/Parser.h:
+ (JSC::Parser::reparse): Added. Re-parses the passed in Node into
+ a new Node.
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createUndefinedVariableError): Pass along CallFrame.
+ (JSC::createInvalidParamError): Ditto.
+ (JSC::createNotAConstructorError): Ditto.
+ (JSC::createNotAFunctionError): Ditto.
+ (JSC::createNotAnObjectError): Ditto.
+
+2009-01-06 Gavin Barraclough <baraclough@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Replace accidentally removed references in BytecodeGenerator, deleting these
+ will be hindering the sharing of constant numbers and strings.
+
+ The code to add a new constant (either number or string) to their respective
+ map works by attempting to add a null entry, then checking the result of the
+ add for null. The first time, this should return the null (or noValue).
+ The code checks for null (to see if this is the initial add), and then allocates
+ a new number / string object. This code relies on the result returned from
+ the add to the map being stored as a reference, such that the allocated object
+ will be stored in the map, and will be resused if the same constant is encountered
+ again. By failing to use a reference we will be leaking GC object for each
+ additional entry added to the map. As GC objects they should be clollected,
+ be we should no be allocatin them in the first place.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23158
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitLoad):
+
+2009-01-06 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ <rdar://problem/6040850> JavaScript register file should use VirtualAlloc on Windows
+
+ Fairly simple, just reserve 4Mb of address space for the
+ register file, and then commit one section at a time. We
+ don't release committed memory as we drop back, but then
+ mac doesn't either so this probably not too much of a
+ problem.
+
+ * interpreter/RegisterFile.cpp:
+ (JSC::RegisterFile::~RegisterFile):
+ * interpreter/RegisterFile.h:
+ (JSC::RegisterFile::RegisterFile):
+ (JSC::RegisterFile::grow):
+
+2009-01-06 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23142
+ ThreadGlobalData leaks seen on buildbot
+
+ * wtf/ThreadSpecific.h: (WTF::ThreadSpecific::destroy): Temporarily reset the thread
+ specific value to make getter work on Mac OS X.
+
+ * wtf/Platform.h: Touch this file again to make sure all Windows builds use the most recent
+ version of ThreadSpecific.h.
+
+2009-01-05 Gavin Barraclough <baraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Replace all uses of JSValue* with a new smart pointer type, JSValuePtr.
+
+ A JavaScript value may be a heap object or boxed primitive, represented by a
+ pointer, or may be an unboxed immediate value, such as an integer. Since a
+ value may dynamically need to contain either a pointer value or an immediate,
+ we encode immediates as pointer values (since all valid JSCell pointers are
+ allocated at alligned addesses, unaligned addresses are available to encode
+ immediates). As such all JavaScript values are represented using a JSValue*.
+
+ This implementation is encumbered by a number of constraints. It ties the
+ JSValue representation to the size of pointer on the platform, which, for
+ example, means that we currently can represent different ranges of integers
+ as immediates on x86 and x86-64. It also prevents us from overloading the
+ to-boolean conversion used to test for noValue() - effectively forcing us
+ to represent noValue() as 0. This would potentially be problematic were we
+ to wish to encode integer values differently (e.g. were we to use the v8
+ encoding, where pointers are tagged with 1 and integers with 0, then the
+ immediate integer 0 would conflict with noValue()).
+
+ This patch replaces all usage of JSValue* with a new class, JSValuePtr,
+ which encapsulates the pointer. JSValuePtr maintains the same interface as
+ JSValue*, overloading operator-> and operator bool such that previous
+ operations in the code on variables of type JSValue* are still supported.
+
+ In order to provide a ProtectPtr<> type with support for the new value
+ representation (without using the internal JSValue type directly), a new
+ ProtectJSValuePtr type has been added, equivalent to the previous type
+ ProtectPtr<JSValue>.
+
+ This patch is likely the first in a sequence of three changes. With the
+ value now encapsulated it will likely make sense to migrate the functionality
+ from JSValue into JSValuePtr, such that the internal pointer representation
+ need not be exposed. Through migrating the functionality to the wrapper
+ class the existing JSValue should be rendered redundant, and the class is
+ likely to be removed (the JSValuePtr now wrapping a pointer to a JSCell).
+ At this stage it will likely make sense to rename JSValuePtr to JSValue.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23114
+
+ * API/APICast.h:
+ (toJS):
+ (toRef):
+ * API/JSBase.cpp:
+ (JSEvaluateScript):
+ * API/JSCallbackConstructor.h:
+ (JSC::JSCallbackConstructor::createStructure):
+ * API/JSCallbackFunction.cpp:
+ (JSC::JSCallbackFunction::call):
+ * API/JSCallbackFunction.h:
+ (JSC::JSCallbackFunction::createStructure):
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObject::createStructure):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::asCallbackObject):
+ (JSC::::put):
+ (JSC::::hasInstance):
+ (JSC::::call):
+ (JSC::::staticValueGetter):
+ (JSC::::staticFunctionGetter):
+ (JSC::::callbackGetter):
+ * API/JSContextRef.cpp:
+ * API/JSObjectRef.cpp:
+ (JSObjectMakeConstructor):
+ (JSObjectSetPrototype):
+ (JSObjectGetProperty):
+ (JSObjectSetProperty):
+ (JSObjectGetPropertyAtIndex):
+ (JSObjectSetPropertyAtIndex):
+ * API/JSValueRef.cpp:
+ (JSValueGetType):
+ (JSValueIsUndefined):
+ (JSValueIsNull):
+ (JSValueIsBoolean):
+ (JSValueIsNumber):
+ (JSValueIsString):
+ (JSValueIsObject):
+ (JSValueIsObjectOfClass):
+ (JSValueIsEqual):
+ (JSValueIsStrictEqual):
+ (JSValueIsInstanceOfConstructor):
+ (JSValueToBoolean):
+ (JSValueToNumber):
+ (JSValueToStringCopy):
+ (JSValueToObject):
+ (JSValueProtect):
+ (JSValueUnprotect):
+ * JavaScriptCore.exp:
+ * bytecode/CodeBlock.cpp:
+ (JSC::valueToSourceString):
+ (JSC::constantName):
+ (JSC::CodeBlock::dump):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::getConstant):
+ (JSC::CodeBlock::addUnexpectedConstant):
+ (JSC::CodeBlock::unexpectedConstant):
+ * bytecode/EvalCodeCache.h:
+ (JSC::EvalCodeCache::get):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::addConstant):
+ (JSC::BytecodeGenerator::addUnexpectedConstant):
+ (JSC::BytecodeGenerator::emitLoad):
+ (JSC::BytecodeGenerator::emitLoadJSV):
+ (JSC::BytecodeGenerator::emitGetScopedVar):
+ (JSC::BytecodeGenerator::emitPutScopedVar):
+ (JSC::BytecodeGenerator::emitNewError):
+ (JSC::keyForImmediateSwitch):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::JSValueHashTraits::constructDeletedValue):
+ (JSC::BytecodeGenerator::JSValueHashTraits::isDeletedValue):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::evaluate):
+ * debugger/DebuggerCallFrame.h:
+ (JSC::DebuggerCallFrame::DebuggerCallFrame):
+ (JSC::DebuggerCallFrame::exception):
+ * interpreter/CallFrame.cpp:
+ (JSC::CallFrame::thisValue):
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::setException):
+ (JSC::ExecState::exception):
+ (JSC::ExecState::exceptionSlot):
+ (JSC::ExecState::hadException):
+ * interpreter/Interpreter.cpp:
+ (JSC::fastIsNumber):
+ (JSC::fastToInt32):
+ (JSC::fastToUInt32):
+ (JSC::jsLess):
+ (JSC::jsLessEq):
+ (JSC::jsAddSlowCase):
+ (JSC::jsAdd):
+ (JSC::jsTypeStringForValue):
+ (JSC::jsIsObjectType):
+ (JSC::jsIsFunctionType):
+ (JSC::Interpreter::resolve):
+ (JSC::Interpreter::resolveSkip):
+ (JSC::Interpreter::resolveGlobal):
+ (JSC::inlineResolveBase):
+ (JSC::Interpreter::resolveBase):
+ (JSC::Interpreter::resolveBaseAndProperty):
+ (JSC::Interpreter::resolveBaseAndFunc):
+ (JSC::isNotObject):
+ (JSC::Interpreter::callEval):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::checkTimeout):
+ (JSC::Interpreter::createExceptionScope):
+ (JSC::cachePrototypeChain):
+ (JSC::Interpreter::tryCachePutByID):
+ (JSC::countPrototypeChainEntriesAndCheckForProxies):
+ (JSC::Interpreter::tryCacheGetByID):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::retrieveArguments):
+ (JSC::Interpreter::retrieveCaller):
+ (JSC::Interpreter::retrieveLastCaller):
+ (JSC::Interpreter::tryCTICachePutByID):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::returnToThrowTrampoline):
+ (JSC::Interpreter::cti_op_convert_this):
+ (JSC::Interpreter::cti_op_add):
+ (JSC::Interpreter::cti_op_pre_inc):
+ (JSC::Interpreter::cti_op_loop_if_less):
+ (JSC::Interpreter::cti_op_loop_if_lesseq):
+ (JSC::Interpreter::cti_op_get_by_id_generic):
+ (JSC::Interpreter::cti_op_get_by_id):
+ (JSC::Interpreter::cti_op_get_by_id_second):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list_full):
+ (JSC::Interpreter::cti_op_get_by_id_proto_fail):
+ (JSC::Interpreter::cti_op_get_by_id_array_fail):
+ (JSC::Interpreter::cti_op_get_by_id_string_fail):
+ (JSC::Interpreter::cti_op_instanceof):
+ (JSC::Interpreter::cti_op_del_by_id):
+ (JSC::Interpreter::cti_op_mul):
+ (JSC::Interpreter::cti_op_call_NotJSFunction):
+ (JSC::Interpreter::cti_op_resolve):
+ (JSC::Interpreter::cti_op_construct_NotJSConstruct):
+ (JSC::Interpreter::cti_op_get_by_val):
+ (JSC::Interpreter::cti_op_resolve_func):
+ (JSC::Interpreter::cti_op_sub):
+ (JSC::Interpreter::cti_op_put_by_val):
+ (JSC::Interpreter::cti_op_put_by_val_array):
+ (JSC::Interpreter::cti_op_lesseq):
+ (JSC::Interpreter::cti_op_loop_if_true):
+ (JSC::Interpreter::cti_op_negate):
+ (JSC::Interpreter::cti_op_resolve_base):
+ (JSC::Interpreter::cti_op_resolve_skip):
+ (JSC::Interpreter::cti_op_resolve_global):
+ (JSC::Interpreter::cti_op_div):
+ (JSC::Interpreter::cti_op_pre_dec):
+ (JSC::Interpreter::cti_op_jless):
+ (JSC::Interpreter::cti_op_not):
+ (JSC::Interpreter::cti_op_jtrue):
+ (JSC::Interpreter::cti_op_post_inc):
+ (JSC::Interpreter::cti_op_eq):
+ (JSC::Interpreter::cti_op_lshift):
+ (JSC::Interpreter::cti_op_bitand):
+ (JSC::Interpreter::cti_op_rshift):
+ (JSC::Interpreter::cti_op_bitnot):
+ (JSC::Interpreter::cti_op_resolve_with_base):
+ (JSC::Interpreter::cti_op_mod):
+ (JSC::Interpreter::cti_op_less):
+ (JSC::Interpreter::cti_op_neq):
+ (JSC::Interpreter::cti_op_post_dec):
+ (JSC::Interpreter::cti_op_urshift):
+ (JSC::Interpreter::cti_op_bitxor):
+ (JSC::Interpreter::cti_op_bitor):
+ (JSC::Interpreter::cti_op_call_eval):
+ (JSC::Interpreter::cti_op_throw):
+ (JSC::Interpreter::cti_op_next_pname):
+ (JSC::Interpreter::cti_op_typeof):
+ (JSC::Interpreter::cti_op_is_undefined):
+ (JSC::Interpreter::cti_op_is_boolean):
+ (JSC::Interpreter::cti_op_is_number):
+ (JSC::Interpreter::cti_op_is_string):
+ (JSC::Interpreter::cti_op_is_object):
+ (JSC::Interpreter::cti_op_is_function):
+ (JSC::Interpreter::cti_op_stricteq):
+ (JSC::Interpreter::cti_op_nstricteq):
+ (JSC::Interpreter::cti_op_to_jsnumber):
+ (JSC::Interpreter::cti_op_in):
+ (JSC::Interpreter::cti_op_switch_imm):
+ (JSC::Interpreter::cti_op_switch_char):
+ (JSC::Interpreter::cti_op_switch_string):
+ (JSC::Interpreter::cti_op_del_by_val):
+ (JSC::Interpreter::cti_op_new_error):
+ (JSC::Interpreter::cti_vm_throw):
+ * interpreter/Interpreter.h:
+ (JSC::Interpreter::isJSArray):
+ (JSC::Interpreter::isJSString):
+ * interpreter/Register.h:
+ (JSC::Register::):
+ (JSC::Register::Register):
+ (JSC::Register::jsValue):
+ (JSC::Register::getJSValue):
+ * jit/JIT.cpp:
+ (JSC::):
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ (JSC::):
+ (JSC::JIT::execute):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileFastArith_op_rshift):
+ (JSC::JIT::compileFastArithSlow_op_rshift):
+ * jit/JITCall.cpp:
+ (JSC::JIT::unlinkCall):
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCall):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitGetVirtualRegister):
+ (JSC::JIT::getConstantOperand):
+ (JSC::JIT::isOperandConstant31BitImmediateInt):
+ (JSC::JIT::emitPutJITStubArgFromVirtualRegister):
+ (JSC::JIT::emitInitRegister):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::resizePropertyStorage):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::patchGetByIdSelf):
+ (JSC::JIT::patchPutByIdReplace):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+ * jsc.cpp:
+ (functionPrint):
+ (functionDebug):
+ (functionGC):
+ (functionVersion):
+ (functionRun):
+ (functionLoad):
+ (functionReadline):
+ (functionQuit):
+ * parser/Nodes.cpp:
+ (JSC::NullNode::emitBytecode):
+ (JSC::ArrayNode::emitBytecode):
+ (JSC::FunctionCallValueNode::emitBytecode):
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::VoidNode::emitBytecode):
+ (JSC::ConstDeclNode::emitCodeSingle):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::processClauseList):
+ (JSC::EvalNode::emitBytecode):
+ (JSC::FunctionBodyNode::emitBytecode):
+ (JSC::ProgramNode::emitBytecode):
+ * profiler/ProfileGenerator.cpp:
+ (JSC::ProfileGenerator::addParentForConsoleStart):
+ * profiler/Profiler.cpp:
+ (JSC::Profiler::willExecute):
+ (JSC::Profiler::didExecute):
+ (JSC::Profiler::createCallIdentifier):
+ * profiler/Profiler.h:
+ * runtime/ArgList.cpp:
+ (JSC::ArgList::slowAppend):
+ * runtime/ArgList.h:
+ (JSC::ArgList::at):
+ (JSC::ArgList::append):
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::put):
+ * runtime/Arguments.h:
+ (JSC::Arguments::createStructure):
+ (JSC::asArguments):
+ * runtime/ArrayConstructor.cpp:
+ (JSC::callArrayConstructor):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::getProperty):
+ (JSC::putProperty):
+ (JSC::arrayProtoFuncToString):
+ (JSC::arrayProtoFuncToLocaleString):
+ (JSC::arrayProtoFuncJoin):
+ (JSC::arrayProtoFuncConcat):
+ (JSC::arrayProtoFuncPop):
+ (JSC::arrayProtoFuncPush):
+ (JSC::arrayProtoFuncReverse):
+ (JSC::arrayProtoFuncShift):
+ (JSC::arrayProtoFuncSlice):
+ (JSC::arrayProtoFuncSort):
+ (JSC::arrayProtoFuncSplice):
+ (JSC::arrayProtoFuncUnShift):
+ (JSC::arrayProtoFuncFilter):
+ (JSC::arrayProtoFuncMap):
+ (JSC::arrayProtoFuncEvery):
+ (JSC::arrayProtoFuncForEach):
+ (JSC::arrayProtoFuncSome):
+ (JSC::arrayProtoFuncIndexOf):
+ (JSC::arrayProtoFuncLastIndexOf):
+ * runtime/BooleanConstructor.cpp:
+ (JSC::callBooleanConstructor):
+ (JSC::constructBooleanFromImmediateBoolean):
+ * runtime/BooleanConstructor.h:
+ * runtime/BooleanObject.h:
+ (JSC::asBooleanObject):
+ * runtime/BooleanPrototype.cpp:
+ (JSC::booleanProtoFuncToString):
+ (JSC::booleanProtoFuncValueOf):
+ * runtime/CallData.cpp:
+ (JSC::call):
+ * runtime/CallData.h:
+ * runtime/Collector.cpp:
+ (JSC::Heap::protect):
+ (JSC::Heap::unprotect):
+ (JSC::Heap::heap):
+ (JSC::Heap::collect):
+ * runtime/Collector.h:
+ * runtime/Completion.cpp:
+ (JSC::evaluate):
+ * runtime/Completion.h:
+ (JSC::Completion::Completion):
+ (JSC::Completion::value):
+ (JSC::Completion::setValue):
+ (JSC::Completion::isValueCompletion):
+ * runtime/ConstructData.cpp:
+ (JSC::construct):
+ * runtime/ConstructData.h:
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+ (JSC::callDate):
+ (JSC::dateParse):
+ (JSC::dateNow):
+ (JSC::dateUTC):
+ * runtime/DateInstance.h:
+ (JSC::asDateInstance):
+ * runtime/DatePrototype.cpp:
+ (JSC::dateProtoFuncToString):
+ (JSC::dateProtoFuncToUTCString):
+ (JSC::dateProtoFuncToDateString):
+ (JSC::dateProtoFuncToTimeString):
+ (JSC::dateProtoFuncToLocaleString):
+ (JSC::dateProtoFuncToLocaleDateString):
+ (JSC::dateProtoFuncToLocaleTimeString):
+ (JSC::dateProtoFuncValueOf):
+ (JSC::dateProtoFuncGetTime):
+ (JSC::dateProtoFuncGetFullYear):
+ (JSC::dateProtoFuncGetUTCFullYear):
+ (JSC::dateProtoFuncToGMTString):
+ (JSC::dateProtoFuncGetMonth):
+ (JSC::dateProtoFuncGetUTCMonth):
+ (JSC::dateProtoFuncGetDate):
+ (JSC::dateProtoFuncGetUTCDate):
+ (JSC::dateProtoFuncGetDay):
+ (JSC::dateProtoFuncGetUTCDay):
+ (JSC::dateProtoFuncGetHours):
+ (JSC::dateProtoFuncGetUTCHours):
+ (JSC::dateProtoFuncGetMinutes):
+ (JSC::dateProtoFuncGetUTCMinutes):
+ (JSC::dateProtoFuncGetSeconds):
+ (JSC::dateProtoFuncGetUTCSeconds):
+ (JSC::dateProtoFuncGetMilliSeconds):
+ (JSC::dateProtoFuncGetUTCMilliseconds):
+ (JSC::dateProtoFuncGetTimezoneOffset):
+ (JSC::dateProtoFuncSetTime):
+ (JSC::setNewValueFromTimeArgs):
+ (JSC::setNewValueFromDateArgs):
+ (JSC::dateProtoFuncSetMilliSeconds):
+ (JSC::dateProtoFuncSetUTCMilliseconds):
+ (JSC::dateProtoFuncSetSeconds):
+ (JSC::dateProtoFuncSetUTCSeconds):
+ (JSC::dateProtoFuncSetMinutes):
+ (JSC::dateProtoFuncSetUTCMinutes):
+ (JSC::dateProtoFuncSetHours):
+ (JSC::dateProtoFuncSetUTCHours):
+ (JSC::dateProtoFuncSetDate):
+ (JSC::dateProtoFuncSetUTCDate):
+ (JSC::dateProtoFuncSetMonth):
+ (JSC::dateProtoFuncSetUTCMonth):
+ (JSC::dateProtoFuncSetFullYear):
+ (JSC::dateProtoFuncSetUTCFullYear):
+ (JSC::dateProtoFuncSetYear):
+ (JSC::dateProtoFuncGetYear):
+ * runtime/DatePrototype.h:
+ (JSC::DatePrototype::createStructure):
+ * runtime/ErrorConstructor.cpp:
+ (JSC::callErrorConstructor):
+ * runtime/ErrorPrototype.cpp:
+ (JSC::errorProtoFuncToString):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createInterruptedExecutionException):
+ (JSC::createError):
+ (JSC::createStackOverflowError):
+ (JSC::createUndefinedVariableError):
+ (JSC::createErrorMessage):
+ (JSC::createInvalidParamError):
+ (JSC::createNotAConstructorError):
+ (JSC::createNotAFunctionError):
+ * runtime/ExceptionHelpers.h:
+ * runtime/FunctionConstructor.cpp:
+ (JSC::callFunctionConstructor):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::callFunctionPrototype):
+ (JSC::functionProtoFuncToString):
+ (JSC::functionProtoFuncApply):
+ (JSC::functionProtoFuncCall):
+ * runtime/FunctionPrototype.h:
+ (JSC::FunctionPrototype::createStructure):
+ * runtime/GetterSetter.cpp:
+ (JSC::GetterSetter::toPrimitive):
+ (JSC::GetterSetter::getPrimitiveNumber):
+ * runtime/GetterSetter.h:
+ (JSC::asGetterSetter):
+ * runtime/InitializeThreading.cpp:
+ * runtime/InternalFunction.h:
+ (JSC::InternalFunction::createStructure):
+ (JSC::asInternalFunction):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::getOwnPropertySlot):
+ (JSC::JSActivation::put):
+ (JSC::JSActivation::putWithAttributes):
+ (JSC::JSActivation::argumentsGetter):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::createStructure):
+ (JSC::asActivation):
+ * runtime/JSArray.cpp:
+ (JSC::storageSize):
+ (JSC::JSArray::JSArray):
+ (JSC::JSArray::getOwnPropertySlot):
+ (JSC::JSArray::put):
+ (JSC::JSArray::putSlowCase):
+ (JSC::JSArray::deleteProperty):
+ (JSC::JSArray::getPropertyNames):
+ (JSC::JSArray::setLength):
+ (JSC::JSArray::pop):
+ (JSC::JSArray::push):
+ (JSC::JSArray::mark):
+ (JSC::JSArray::sort):
+ (JSC::JSArray::compactForSorting):
+ (JSC::JSArray::checkConsistency):
+ (JSC::constructArray):
+ * runtime/JSArray.h:
+ (JSC::JSArray::getIndex):
+ (JSC::JSArray::setIndex):
+ (JSC::JSArray::createStructure):
+ (JSC::asArray):
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::put):
+ (JSC::JSCell::getJSNumber):
+ * runtime/JSCell.h:
+ (JSC::asCell):
+ (JSC::JSValue::asCell):
+ (JSC::JSValue::toPrimitive):
+ (JSC::JSValue::getPrimitiveNumber):
+ (JSC::JSValue::getJSNumber):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::call):
+ (JSC::JSFunction::argumentsGetter):
+ (JSC::JSFunction::callerGetter):
+ (JSC::JSFunction::lengthGetter):
+ (JSC::JSFunction::getOwnPropertySlot):
+ (JSC::JSFunction::put):
+ (JSC::JSFunction::construct):
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::createStructure):
+ (JSC::asFunction):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::markIfNeeded):
+ (JSC::JSGlobalObject::put):
+ (JSC::JSGlobalObject::putWithAttributes):
+ (JSC::JSGlobalObject::reset):
+ (JSC::JSGlobalObject::resetPrototype):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::createStructure):
+ (JSC::JSGlobalObject::GlobalPropertyInfo::GlobalPropertyInfo):
+ (JSC::asGlobalObject):
+ (JSC::Structure::prototypeForLookup):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::encode):
+ (JSC::decode):
+ (JSC::globalFuncEval):
+ (JSC::globalFuncParseInt):
+ (JSC::globalFuncParseFloat):
+ (JSC::globalFuncIsNaN):
+ (JSC::globalFuncIsFinite):
+ (JSC::globalFuncDecodeURI):
+ (JSC::globalFuncDecodeURIComponent):
+ (JSC::globalFuncEncodeURI):
+ (JSC::globalFuncEncodeURIComponent):
+ (JSC::globalFuncEscape):
+ (JSC::globalFuncUnescape):
+ (JSC::globalFuncJSCPrint):
+ * runtime/JSGlobalObjectFunctions.h:
+ * runtime/JSImmediate.cpp:
+ (JSC::JSImmediate::toThisObject):
+ (JSC::JSImmediate::toObject):
+ (JSC::JSImmediate::prototype):
+ (JSC::JSImmediate::toString):
+ * runtime/JSImmediate.h:
+ (JSC::JSImmediate::isImmediate):
+ (JSC::JSImmediate::isNumber):
+ (JSC::JSImmediate::isPositiveNumber):
+ (JSC::JSImmediate::isBoolean):
+ (JSC::JSImmediate::isUndefinedOrNull):
+ (JSC::JSImmediate::isNegative):
+ (JSC::JSImmediate::isEitherImmediate):
+ (JSC::JSImmediate::isAnyImmediate):
+ (JSC::JSImmediate::areBothImmediate):
+ (JSC::JSImmediate::areBothImmediateNumbers):
+ (JSC::JSImmediate::andImmediateNumbers):
+ (JSC::JSImmediate::xorImmediateNumbers):
+ (JSC::JSImmediate::orImmediateNumbers):
+ (JSC::JSImmediate::rightShiftImmediateNumbers):
+ (JSC::JSImmediate::canDoFastAdditiveOperations):
+ (JSC::JSImmediate::addImmediateNumbers):
+ (JSC::JSImmediate::subImmediateNumbers):
+ (JSC::JSImmediate::incImmediateNumber):
+ (JSC::JSImmediate::decImmediateNumber):
+ (JSC::JSImmediate::makeValue):
+ (JSC::JSImmediate::makeInt):
+ (JSC::JSImmediate::makeBool):
+ (JSC::JSImmediate::makeUndefined):
+ (JSC::JSImmediate::makeNull):
+ (JSC::JSImmediate::intValue):
+ (JSC::JSImmediate::uintValue):
+ (JSC::JSImmediate::boolValue):
+ (JSC::JSImmediate::rawValue):
+ (JSC::JSImmediate::trueImmediate):
+ (JSC::JSImmediate::falseImmediate):
+ (JSC::JSImmediate::undefinedImmediate):
+ (JSC::JSImmediate::nullImmediate):
+ (JSC::JSImmediate::zeroImmediate):
+ (JSC::JSImmediate::oneImmediate):
+ (JSC::JSImmediate::impossibleValue):
+ (JSC::JSImmediate::toBoolean):
+ (JSC::JSImmediate::getTruncatedUInt32):
+ (JSC::JSImmediate::from):
+ (JSC::JSImmediate::getTruncatedInt32):
+ (JSC::JSImmediate::toDouble):
+ (JSC::JSImmediate::getUInt32):
+ (JSC::jsNull):
+ (JSC::jsBoolean):
+ (JSC::jsUndefined):
+ (JSC::JSValue::isUndefined):
+ (JSC::JSValue::isNull):
+ (JSC::JSValue::isUndefinedOrNull):
+ (JSC::JSValue::isBoolean):
+ (JSC::JSValue::getBoolean):
+ (JSC::JSValue::toInt32):
+ (JSC::JSValue::toUInt32):
+ (JSC::toInt32):
+ (JSC::toUInt32):
+ * runtime/JSNotAnObject.cpp:
+ (JSC::JSNotAnObject::toPrimitive):
+ (JSC::JSNotAnObject::getPrimitiveNumber):
+ (JSC::JSNotAnObject::put):
+ * runtime/JSNotAnObject.h:
+ (JSC::JSNotAnObject::createStructure):
+ * runtime/JSNumberCell.cpp:
+ (JSC::JSNumberCell::toPrimitive):
+ (JSC::JSNumberCell::getPrimitiveNumber):
+ (JSC::JSNumberCell::getJSNumber):
+ (JSC::jsNumberCell):
+ (JSC::jsNaN):
+ * runtime/JSNumberCell.h:
+ (JSC::JSNumberCell::createStructure):
+ (JSC::asNumberCell):
+ (JSC::jsNumber):
+ (JSC::JSValue::toJSNumber):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::mark):
+ (JSC::JSObject::put):
+ (JSC::JSObject::putWithAttributes):
+ (JSC::callDefaultValueFunction):
+ (JSC::JSObject::getPrimitiveNumber):
+ (JSC::JSObject::defaultValue):
+ (JSC::JSObject::defineGetter):
+ (JSC::JSObject::defineSetter):
+ (JSC::JSObject::lookupGetter):
+ (JSC::JSObject::lookupSetter):
+ (JSC::JSObject::hasInstance):
+ (JSC::JSObject::toNumber):
+ (JSC::JSObject::toString):
+ (JSC::JSObject::fillGetterPropertySlot):
+ * runtime/JSObject.h:
+ (JSC::JSObject::getDirect):
+ (JSC::JSObject::getDirectLocation):
+ (JSC::JSObject::offsetForLocation):
+ (JSC::JSObject::locationForOffset):
+ (JSC::JSObject::getDirectOffset):
+ (JSC::JSObject::putDirectOffset):
+ (JSC::JSObject::createStructure):
+ (JSC::asObject):
+ (JSC::JSObject::prototype):
+ (JSC::JSObject::setPrototype):
+ (JSC::JSObject::inlineGetOwnPropertySlot):
+ (JSC::JSObject::getOwnPropertySlotForWrite):
+ (JSC::JSObject::getPropertySlot):
+ (JSC::JSObject::get):
+ (JSC::JSObject::putDirect):
+ (JSC::JSObject::putDirectWithoutTransition):
+ (JSC::JSObject::toPrimitive):
+ (JSC::JSValue::get):
+ (JSC::JSValue::put):
+ (JSC::JSObject::allocatePropertyStorageInline):
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::toPrimitive):
+ (JSC::JSPropertyNameIterator::getPrimitiveNumber):
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::create):
+ (JSC::JSPropertyNameIterator::next):
+ * runtime/JSStaticScopeObject.cpp:
+ (JSC::JSStaticScopeObject::put):
+ (JSC::JSStaticScopeObject::putWithAttributes):
+ * runtime/JSStaticScopeObject.h:
+ (JSC::JSStaticScopeObject::JSStaticScopeObject):
+ (JSC::JSStaticScopeObject::createStructure):
+ * runtime/JSString.cpp:
+ (JSC::JSString::toPrimitive):
+ (JSC::JSString::getPrimitiveNumber):
+ (JSC::JSString::getOwnPropertySlot):
+ * runtime/JSString.h:
+ (JSC::JSString::createStructure):
+ (JSC::asString):
+ * runtime/JSValue.h:
+ (JSC::JSValuePtr::makeImmediate):
+ (JSC::JSValuePtr::immediateValue):
+ (JSC::JSValuePtr::JSValuePtr):
+ (JSC::JSValuePtr::operator->):
+ (JSC::JSValuePtr::hasValue):
+ (JSC::JSValuePtr::operator==):
+ (JSC::JSValuePtr::operator!=):
+ (JSC::JSValuePtr::encode):
+ (JSC::JSValuePtr::decode):
+ (JSC::JSValue::asValue):
+ (JSC::noValue):
+ (JSC::operator==):
+ (JSC::operator!=):
+ * runtime/JSVariableObject.h:
+ (JSC::JSVariableObject::symbolTablePut):
+ (JSC::JSVariableObject::symbolTablePutWithAttributes):
+ * runtime/JSWrapperObject.cpp:
+ (JSC::JSWrapperObject::mark):
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::internalValue):
+ (JSC::JSWrapperObject::setInternalValue):
+ * runtime/Lookup.cpp:
+ (JSC::setUpStaticFunctionSlot):
+ * runtime/Lookup.h:
+ (JSC::lookupPut):
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncAbs):
+ (JSC::mathProtoFuncACos):
+ (JSC::mathProtoFuncASin):
+ (JSC::mathProtoFuncATan):
+ (JSC::mathProtoFuncATan2):
+ (JSC::mathProtoFuncCeil):
+ (JSC::mathProtoFuncCos):
+ (JSC::mathProtoFuncExp):
+ (JSC::mathProtoFuncFloor):
+ (JSC::mathProtoFuncLog):
+ (JSC::mathProtoFuncMax):
+ (JSC::mathProtoFuncMin):
+ (JSC::mathProtoFuncPow):
+ (JSC::mathProtoFuncRandom):
+ (JSC::mathProtoFuncRound):
+ (JSC::mathProtoFuncSin):
+ (JSC::mathProtoFuncSqrt):
+ (JSC::mathProtoFuncTan):
+ * runtime/MathObject.h:
+ (JSC::MathObject::createStructure):
+ * runtime/NativeErrorConstructor.cpp:
+ (JSC::callNativeErrorConstructor):
+ * runtime/NumberConstructor.cpp:
+ (JSC::numberConstructorNaNValue):
+ (JSC::numberConstructorNegInfinity):
+ (JSC::numberConstructorPosInfinity):
+ (JSC::numberConstructorMaxValue):
+ (JSC::numberConstructorMinValue):
+ (JSC::callNumberConstructor):
+ * runtime/NumberConstructor.h:
+ (JSC::NumberConstructor::createStructure):
+ * runtime/NumberObject.cpp:
+ (JSC::NumberObject::getJSNumber):
+ (JSC::constructNumberFromImmediateNumber):
+ * runtime/NumberObject.h:
+ * runtime/NumberPrototype.cpp:
+ (JSC::numberProtoFuncToString):
+ (JSC::numberProtoFuncToLocaleString):
+ (JSC::numberProtoFuncValueOf):
+ (JSC::numberProtoFuncToFixed):
+ (JSC::numberProtoFuncToExponential):
+ (JSC::numberProtoFuncToPrecision):
+ * runtime/ObjectConstructor.cpp:
+ (JSC::constructObject):
+ (JSC::callObjectConstructor):
+ * runtime/ObjectPrototype.cpp:
+ (JSC::objectProtoFuncValueOf):
+ (JSC::objectProtoFuncHasOwnProperty):
+ (JSC::objectProtoFuncIsPrototypeOf):
+ (JSC::objectProtoFuncDefineGetter):
+ (JSC::objectProtoFuncDefineSetter):
+ (JSC::objectProtoFuncLookupGetter):
+ (JSC::objectProtoFuncLookupSetter):
+ (JSC::objectProtoFuncPropertyIsEnumerable):
+ (JSC::objectProtoFuncToLocaleString):
+ (JSC::objectProtoFuncToString):
+ * runtime/ObjectPrototype.h:
+ * runtime/Operations.cpp:
+ (JSC::equal):
+ (JSC::equalSlowCase):
+ (JSC::strictEqual):
+ (JSC::strictEqualSlowCase):
+ (JSC::throwOutOfMemoryError):
+ * runtime/Operations.h:
+ (JSC::equalSlowCaseInline):
+ (JSC::strictEqualSlowCaseInline):
+ * runtime/PropertySlot.cpp:
+ (JSC::PropertySlot::functionGetter):
+ * runtime/PropertySlot.h:
+ (JSC::PropertySlot::PropertySlot):
+ (JSC::PropertySlot::getValue):
+ (JSC::PropertySlot::putValue):
+ (JSC::PropertySlot::setValueSlot):
+ (JSC::PropertySlot::setValue):
+ (JSC::PropertySlot::setCustom):
+ (JSC::PropertySlot::setCustomIndex):
+ (JSC::PropertySlot::slotBase):
+ (JSC::PropertySlot::setBase):
+ (JSC::PropertySlot::):
+ * runtime/Protect.h:
+ (JSC::gcProtect):
+ (JSC::gcUnprotect):
+ (JSC::ProtectedPtr::ProtectedPtr):
+ (JSC::ProtectedPtr::operator JSValuePtr):
+ (JSC::ProtectedJSValuePtr::ProtectedJSValuePtr):
+ (JSC::ProtectedJSValuePtr::get):
+ (JSC::ProtectedJSValuePtr::operator JSValuePtr):
+ (JSC::ProtectedJSValuePtr::operator->):
+ (JSC::::ProtectedPtr):
+ (JSC::::~ProtectedPtr):
+ (JSC::::operator):
+ (JSC::ProtectedJSValuePtr::~ProtectedJSValuePtr):
+ (JSC::ProtectedJSValuePtr::operator=):
+ (JSC::operator==):
+ (JSC::operator!=):
+ * runtime/RegExpConstructor.cpp:
+ (JSC::RegExpConstructor::getBackref):
+ (JSC::RegExpConstructor::getLastParen):
+ (JSC::RegExpConstructor::getLeftContext):
+ (JSC::RegExpConstructor::getRightContext):
+ (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):
+ (JSC::RegExpConstructor::put):
+ (JSC::setRegExpConstructorInput):
+ (JSC::setRegExpConstructorMultiline):
+ (JSC::constructRegExp):
+ (JSC::callRegExpConstructor):
+ * runtime/RegExpConstructor.h:
+ (JSC::RegExpConstructor::createStructure):
+ (JSC::asRegExpConstructor):
+ * runtime/RegExpMatchesArray.h:
+ (JSC::RegExpMatchesArray::put):
+ * runtime/RegExpObject.cpp:
+ (JSC::regExpObjectGlobal):
+ (JSC::regExpObjectIgnoreCase):
+ (JSC::regExpObjectMultiline):
+ (JSC::regExpObjectSource):
+ (JSC::regExpObjectLastIndex):
+ (JSC::RegExpObject::put):
+ (JSC::setRegExpObjectLastIndex):
+ (JSC::RegExpObject::test):
+ (JSC::RegExpObject::exec):
+ (JSC::callRegExpObject):
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::createStructure):
+ (JSC::asRegExpObject):
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncTest):
+ (JSC::regExpProtoFuncExec):
+ (JSC::regExpProtoFuncCompile):
+ (JSC::regExpProtoFuncToString):
+ * runtime/StringConstructor.cpp:
+ (JSC::stringFromCharCodeSlowCase):
+ (JSC::stringFromCharCode):
+ (JSC::callStringConstructor):
+ * runtime/StringObject.cpp:
+ (JSC::StringObject::put):
+ * runtime/StringObject.h:
+ (JSC::StringObject::createStructure):
+ (JSC::asStringObject):
+ * runtime/StringObjectThatMasqueradesAsUndefined.h:
+ (JSC::StringObjectThatMasqueradesAsUndefined::createStructure):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncReplace):
+ (JSC::stringProtoFuncToString):
+ (JSC::stringProtoFuncCharAt):
+ (JSC::stringProtoFuncCharCodeAt):
+ (JSC::stringProtoFuncConcat):
+ (JSC::stringProtoFuncIndexOf):
+ (JSC::stringProtoFuncLastIndexOf):
+ (JSC::stringProtoFuncMatch):
+ (JSC::stringProtoFuncSearch):
+ (JSC::stringProtoFuncSlice):
+ (JSC::stringProtoFuncSplit):
+ (JSC::stringProtoFuncSubstr):
+ (JSC::stringProtoFuncSubstring):
+ (JSC::stringProtoFuncToLowerCase):
+ (JSC::stringProtoFuncToUpperCase):
+ (JSC::stringProtoFuncLocaleCompare):
+ (JSC::stringProtoFuncBig):
+ (JSC::stringProtoFuncSmall):
+ (JSC::stringProtoFuncBlink):
+ (JSC::stringProtoFuncBold):
+ (JSC::stringProtoFuncFixed):
+ (JSC::stringProtoFuncItalics):
+ (JSC::stringProtoFuncStrike):
+ (JSC::stringProtoFuncSub):
+ (JSC::stringProtoFuncSup):
+ (JSC::stringProtoFuncFontcolor):
+ (JSC::stringProtoFuncFontsize):
+ (JSC::stringProtoFuncAnchor):
+ (JSC::stringProtoFuncLink):
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::createCachedPrototypeChain):
+ * runtime/Structure.h:
+ (JSC::Structure::create):
+ (JSC::Structure::setPrototypeWithoutTransition):
+ (JSC::Structure::storedPrototype):
+
+2009-01-06 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ <https://bugs.webkit.org/show_bug.cgi?id=23085> [jsfunfuzz] Over released ScopeChainNode
+ <rdar://problem/6474110>
+
+ So this delightful bug was caused by our unwind code using a ScopeChain to perform
+ the unwind. The ScopeChain would ref the initial top of the scope chain, then deref
+ the resultant top of scope chain, which is incorrect.
+
+ This patch removes the dependency on ScopeChain for the unwind, and i've filed
+ <https://bugs.webkit.org/show_bug.cgi?id=23144> to look into the unintuitive
+ ScopeChain behaviour.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException):
+
+2009-01-06 Adam Roben <aroben@apple.com>
+
+ Hopeful Windows crash-on-launch fix
+
+ * wtf/Platform.h: Force a world rebuild by touching this file.
+
+2009-01-06 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by NOBODY (Build fix).
+
+ * GNUmakefile.am:Add ByteArray.cpp too
+
+2009-01-06 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by NOBODY (Speculative build fix).
+
+ AllInOneFile.cpp does not include the JSByteArray.cpp include it...
+
+ * GNUmakefile.am:
+
+2009-01-05 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Fix Wx build
+
+ * JavaScriptCoreSources.bkl:
+
+2009-01-05 Oliver Hunt <oliver@apple.com>
+
+ Windows build fixes
+
+ Rubber-stamped by Alice Liu.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::Interpreter):
+ * runtime/ByteArray.cpp:
+ (JSC::ByteArray::create):
+ * runtime/ByteArray.h:
+
+2009-01-05 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ CanvasPixelArray performance is too slow
+ <https://bugs.webkit.org/show_bug.cgi?id=23123>
+
+ The fix to this is to devirtualise get and put in a manner similar to
+ JSString and JSArray. To do this I've added a ByteArray implementation
+ and JSByteArray wrapper to JSC. We can then do vptr comparisons to
+ devirtualise the calls.
+
+ This devirtualisation improves performance by 1.5-2x in my somewhat ad
+ hoc tests.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::cti_op_get_by_val):
+ (JSC::Interpreter::cti_op_put_by_val):
+ * interpreter/Interpreter.h:
+ (JSC::Interpreter::isJSByteArray):
+ * runtime/ByteArray.cpp: Added.
+ (JSC::ByteArray::create):
+ * runtime/ByteArray.h: Added.
+ (JSC::ByteArray::length):
+ (JSC::ByteArray::set):
+ (JSC::ByteArray::get):
+ (JSC::ByteArray::data):
+ (JSC::ByteArray::ByteArray):
+ * runtime/JSByteArray.cpp: Added.
+ (JSC::):
+ (JSC::JSByteArray::JSByteArray):
+ (JSC::JSByteArray::createStructure):
+ (JSC::JSByteArray::getOwnPropertySlot):
+ (JSC::JSByteArray::put):
+ (JSC::JSByteArray::getPropertyNames):
+ * runtime/JSByteArray.h: Added.
+ (JSC::JSByteArray::canAccessIndex):
+ (JSC::JSByteArray::getIndex):
+ (JSC::JSByteArray::setIndex):
+ (JSC::JSByteArray::classInfo):
+ (JSC::JSByteArray::length):
+ (JSC::JSByteArray::):
+ (JSC::JSByteArray::JSByteArray):
+ (JSC::asByteArray):
+
+2009-01-05 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23073
+ <rdar://problem/6471129> Workers crash on Windows Release builds
+
+ * wtf/ThreadSpecific.h:
+ (WTF::ThreadSpecific::destroy): Changed to clear the pointer only after data object
+ destruction is finished - otherwise, WebCore::ThreadGlobalData destructor was re-creating
+ the object in order to access atomic string table.
+ (WTF::ThreadSpecific::operator T*): Symmetrically, set up the per-thread pointer before
+ data constructor is called.
+
+ * wtf/ThreadingWin.cpp: (WTF::wtfThreadEntryPoint): Remove a Windows-only hack to finalize
+ a thread - pthreadVC2 is a DLL, so it gets thread detached messages, and cleans up thread
+ specific data automatically. Besides, this code wasn't even compiled in for some time now.
+
+2009-01-05 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23115
+ Create a version of ASSERT for use with otherwise unused variables
+
+ * wtf/Assertions.h: Added ASSERT_UNUSED.
+
+ * jit/ExecutableAllocatorPosix.cpp:
+ (JSC::ExecutablePool::systemRelease):
+ * runtime/Collector.cpp:
+ (JSC::Heap::destroy):
+ (JSC::Heap::heapAllocate):
+ * runtime/JSNotAnObject.cpp:
+ (JSC::JSNotAnObject::toPrimitive):
+ (JSC::JSNotAnObject::getPrimitiveNumber):
+ (JSC::JSNotAnObject::toBoolean):
+ (JSC::JSNotAnObject::toNumber):
+ (JSC::JSNotAnObject::toString):
+ (JSC::JSNotAnObject::getOwnPropertySlot):
+ (JSC::JSNotAnObject::put):
+ (JSC::JSNotAnObject::deleteProperty):
+ (JSC::JSNotAnObject::getPropertyNames):
+ * wtf/TCSystemAlloc.cpp:
+ (TCMalloc_SystemRelease):
+ Use it in some places that used other idioms for this purpose.
+
+2009-01-04 Alice Liu <alice.liu@apple.com>
+
+ <rdar://problem/6341776> Merge m_transitionCount and m_offset in Structure.
+
+ Reviewed by Darin Adler.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure): Remove m_transitionCount
+ (JSC::Structure::addPropertyTransitionToExistingStructure): No need to wait until after the assignment to offset to assert if it's notFound; move it up.
+ (JSC::Structure::addPropertyTransition): Use method for transitionCount instead of m_transitionCount. Remove line that maintains the m_transitionCount.
+ (JSC::Structure::changePrototypeTransition): Remove line that maintains the m_transitionCount.
+ (JSC::Structure::getterSetterTransition): Remove line that maintains the m_transitionCount.
+ * runtime/Structure.h:
+ Changed s_maxTransitionLength and m_offset from size_t to signed char. m_offset will never become greater than 64
+ because the structure transitions to a dictionary at that time.
+ (JSC::Structure::transitionCount): method to replace the data member
+
+2009-01-04 Darin Adler <darin@apple.com>
+
+ Reviewed by David Kilzer.
+
+ Bug 15114: Provide compile-time assertions for sizeof(UChar), sizeof(DeprecatedChar), etc.
+ https://bugs.webkit.org/show_bug.cgi?id=15114
+
+ * wtf/unicode/Unicode.h: Assert size of UChar. There is no DeprecatedChar any more.
+
+2009-01-03 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ Change the pcVector from storing native code pointers to storing offsets
+ from the base pointer. This will allow us to generate the pcVector on demand
+ for exceptions.
+
+ * bytecode/CodeBlock.h:
+ (JSC::PC::PC):
+ (JSC::getNativePCOffset):
+ (JSC::CodeBlock::getBytecodeIndex):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+
+2009-01-02 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ * runtime/ScopeChain.cpp:
+
+2009-01-02 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ [jsfunfuzz] unwind logic for exceptions in eval fails to account for dynamic scope external to the eval
+ https://bugs.webkit.org/show_bug.cgi?id=23078
+
+ This bug was caused by eval codeblocks being generated without accounting
+ for the depth of the scope chain they inherited. This meant that exception
+ handlers would understate their expected scope chain depth, which in turn
+ led to incorrectly removing nodes from the scope chain.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitCatch):
+ * bytecompiler/BytecodeGenerator.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::depth):
+ * runtime/ScopeChain.cpp:
+ (JSC::ScopeChain::localDepth):
+ * runtime/ScopeChain.h:
+ (JSC::ScopeChainNode::deref):
+ (JSC::ScopeChainNode::ref):
+
+2009-01-02 David Smith <catfish.man@gmail.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22699
+ Enable NodeList caching for getElementsByTagName
+
+ * wtf/HashFunctions.h: Moved the definition of PHI here and renamed to stringHashingStartValue
+
+2009-01-02 David Kilzer <ddkilzer@apple.com>
+
+ Attempt to fix Qt Linux build after r39553
+
+ * wtf/RandomNumberSeed.h: Include <sys/time.h> for gettimeofday().
+ Include <sys/types.h> and <unistd.h> for getpid().
+
+2009-01-02 David Kilzer <ddkilzer@apple.com>
+
+ Bug 23081: These files are no longer part of the KDE libraries
+
+ <https://bugs.webkit.org/show_bug.cgi?id=23081>
+
+ Reviewed by Darin Adler.
+
+ Removed "This file is part of the KDE libraries" comment from
+ source files. Added or updated Apple copyrights as well.
+
+ * parser/Lexer.h:
+ * wtf/HashCountedSet.h:
+ * wtf/RetainPtr.h:
+ * wtf/VectorTraits.h:
+
+2009-01-02 David Kilzer <ddkilzer@apple.com>
+
+ Bug 23080: Remove last vestiges of KJS references
+
+ <https://bugs.webkit.org/show_bug.cgi?id=23080>
+
+ Reviewed by Darin Adler.
+
+ Also updated Apple copyright statements.
+
+ * DerivedSources.make: Changed bison "kjsyy" prefix to "jscyy".
+ * GNUmakefile.am: Ditto.
+ * JavaScriptCore.pri: Ditto. Also changed KJSBISON to JSCBISON
+ and kjsbison to jscbison.
+
+ * JavaScriptCoreSources.bkl: Changed JSCORE_KJS_SOURCES to
+ JSCORE_JSC_SOURCES.
+ * jscore.bkl: Ditto.
+
+ * create_hash_table: Updated copyright and removed old comment.
+
+ * parser/Grammar.y: Changed "kjsyy" prefix to "jscyy" prefix.
+ * parser/Lexer.cpp: Ditto. Also changed KJS_DEBUG_LEX to
+ JSC_DEBUG_LEX.
+ (jscyylex):
+ (JSC::Lexer::lex):
+ * parser/Parser.cpp: Ditto.
+ (JSC::Parser::parse):
+
+ * pcre/dftables: Changed "kjs_pcre_" prefix to "jsc_pcre_".
+ * pcre/pcre_compile.cpp: Ditto.
+ (getOthercaseRange):
+ (encodeUTF8):
+ (compileBranch):
+ (calculateCompiledPatternLength):
+ * pcre/pcre_exec.cpp: Ditto.
+ (matchRef):
+ (getUTF8CharAndIncrementLength):
+ (match):
+ * pcre/pcre_internal.h: Ditto.
+ (toLowerCase):
+ (flipCase):
+ (classBitmapForChar):
+ (charTypeForChar):
+ * pcre/pcre_tables.cpp: Ditto.
+ * pcre/pcre_ucp_searchfuncs.cpp: Ditto.
+ (jsc_pcre_ucp_othercase):
+ * pcre/pcre_xclass.cpp: Ditto.
+ (getUTF8CharAndAdvancePointer):
+ (jsc_pcre_xclass):
+
+ * runtime/Collector.h: Updated header guards using the
+ clean-header-guards script.
+ * runtime/CollectorHeapIterator.h: Added missing header guard.
+ * runtime/Identifier.h: Updated header guards.
+ * runtime/JSFunction.h: Fixed end-of-namespace comment.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset): Renamed "kjsprint" debug function
+ to "jscprint". Changed implementation method from
+ globalFuncKJSPrint() to globalFuncJSCPrint().
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncJSCPrint): Renamed from globalFuncKJSPrint().
+ * runtime/JSGlobalObjectFunctions.h: Ditto.
+
+ * runtime/JSImmediate.h: Updated header guards.
+ * runtime/JSLock.h: Ditto.
+ * runtime/JSType.h: Ditto.
+ * runtime/JSWrapperObject.h: Ditto.
+ * runtime/Lookup.h: Ditto.
+ * runtime/Operations.h: Ditto.
+ * runtime/Protect.h: Ditto.
+ * runtime/RegExp.h: Ditto.
+ * runtime/UString.h: Ditto.
+
+ * tests/mozilla/js1_5/Array/regress-157652.js: Changed "KJS"
+ reference in comment to "JSC".
+
+ * wrec/CharacterClassConstructor.cpp: Change "kjs_pcre_" function
+ prefixes to "jsc_pcre_".
+ (JSC::WREC::CharacterClassConstructor::put):
+ (JSC::WREC::CharacterClassConstructor::flush):
+
+ * wtf/unicode/Unicode.h: Change "KJS_" header guard to "WTF_".
+ * wtf/unicode/icu/UnicodeIcu.h: Ditto.
+ * wtf/unicode/qt4/UnicodeQt4.h: Ditto.
+
+2009-01-02 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Make randomNumber generate 2^53 values instead of 2^32 (or 2^31 for rand() platforms)
+
+ * wtf/RandomNumber.cpp:
+ (WTF::randomNumber):
+
+2009-01-02 David Kilzer <ddkilzer@apple.com>
+
+ Remove declaration for JSC::Identifier::initializeIdentifierThreading()
+
+ Reviewed by Alexey Proskuryakov.
+
+ * runtime/Identifier.h:
+ (JSC::Identifier::initializeIdentifierThreading): Removed
+ declaration since the implementation was removed in r34412.
+
+2009-01-01 Darin Adler <darin@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ String.replace does not support $& replacement metacharacter when search term is not a RegExp
+ <https://bugs.webkit.org/show_bug.cgi?id=21431>
+ <rdar://problem/6274993>
+
+ Test: fast/js/string-replace-3.html
+
+ * runtime/StringPrototype.cpp:
+ (JSC::substituteBackreferences): Added a null check here so we won't try to handle $$-$9
+ backreferences when the search term is a string, not a RegExp. Added a check for 0 so we
+ won't try to handle $0 or $00 as a backreference.
+ (JSC::stringProtoFuncReplace): Added a call to substituteBackreferences.
+
+2009-01-01 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Allow 32-bit integers to be stored in JSImmediates, on x64-bit.
+ Presently the top 32-bits of a 64-bit JSImmediate serve as a sign extension of a 31-bit
+ int stored in the low word (shifted left by one, to make room for a tag). In the new
+ format, the top 31-bits serve as a sign extension of a 32-bit int, still shifted left by
+ one.
+
+ The new behavior is enabled using a flag in Platform.h, 'WTF_USE_ALTERNATE_JSIMMEDIATE'.
+ When this is set the constants defining the range of ints allowed to be stored as
+ JSImmediate values is extended. The code in JSImmediate.h can safely operate on either
+ format. This patch updates the JIT so that it can also operate with the new format.
+
+ ~2% progression on x86-64, with & without the JIT, on sunspider & v8 tests.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::addPtr):
+ (JSC::MacroAssembler::orPtr):
+ (JSC::MacroAssembler::or32):
+ (JSC::MacroAssembler::rshiftPtr):
+ (JSC::MacroAssembler::rshift32):
+ (JSC::MacroAssembler::subPtr):
+ (JSC::MacroAssembler::xorPtr):
+ (JSC::MacroAssembler::xor32):
+ (JSC::MacroAssembler::move):
+ (JSC::MacroAssembler::compareImm64ForBranch):
+ (JSC::MacroAssembler::compareImm64ForBranchEquality):
+ (JSC::MacroAssembler::jePtr):
+ (JSC::MacroAssembler::jgePtr):
+ (JSC::MacroAssembler::jlPtr):
+ (JSC::MacroAssembler::jlePtr):
+ (JSC::MacroAssembler::jnePtr):
+ (JSC::MacroAssembler::jnzSubPtr):
+ (JSC::MacroAssembler::joAddPtr):
+ (JSC::MacroAssembler::jzSubPtr):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::addq_rr):
+ (JSC::X86Assembler::orq_ir):
+ (JSC::X86Assembler::subq_ir):
+ (JSC::X86Assembler::xorq_rr):
+ (JSC::X86Assembler::sarq_CLr):
+ (JSC::X86Assembler::sarq_i8r):
+ (JSC::X86Assembler::cmpq_ir):
+ * jit/JIT.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileFastArith_op_lshift):
+ (JSC::JIT::compileFastArithSlow_op_lshift):
+ (JSC::JIT::compileFastArith_op_rshift):
+ (JSC::JIT::compileFastArithSlow_op_rshift):
+ (JSC::JIT::compileFastArith_op_bitand):
+ (JSC::JIT::compileFastArithSlow_op_bitand):
+ (JSC::JIT::compileFastArith_op_mod):
+ (JSC::JIT::compileFastArithSlow_op_mod):
+ (JSC::JIT::compileFastArith_op_add):
+ (JSC::JIT::compileFastArithSlow_op_add):
+ (JSC::JIT::compileFastArith_op_mul):
+ (JSC::JIT::compileFastArithSlow_op_mul):
+ (JSC::JIT::compileFastArith_op_post_inc):
+ (JSC::JIT::compileFastArithSlow_op_post_inc):
+ (JSC::JIT::compileFastArith_op_post_dec):
+ (JSC::JIT::compileFastArithSlow_op_post_dec):
+ (JSC::JIT::compileFastArith_op_pre_inc):
+ (JSC::JIT::compileFastArithSlow_op_pre_inc):
+ (JSC::JIT::compileFastArith_op_pre_dec):
+ (JSC::JIT::compileFastArithSlow_op_pre_dec):
+ (JSC::JIT::compileBinaryArithOp):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::getConstantOperand):
+ (JSC::JIT::getConstantOperandImmediateInt):
+ (JSC::JIT::isOperandConstantImmediateInt):
+ (JSC::JIT::isOperandConstant31BitImmediateInt):
+ (JSC::JIT::emitFastArithDeTagImmediate):
+ (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::JIT::emitFastArithReTagImmediate):
+ (JSC::JIT::emitFastArithImmToInt):
+ (JSC::JIT::emitFastArithIntToImmNoCheck):
+ * runtime/JSImmediate.h:
+ (JSC::JSImmediate::isPositiveNumber):
+ (JSC::JSImmediate::isNegative):
+ (JSC::JSImmediate::rightShiftImmediateNumbers):
+ (JSC::JSImmediate::canDoFastAdditiveOperations):
+ (JSC::JSImmediate::makeValue):
+ (JSC::JSImmediate::makeInt):
+ (JSC::JSImmediate::makeBool):
+ (JSC::JSImmediate::intValue):
+ (JSC::JSImmediate::rawValue):
+ (JSC::JSImmediate::toBoolean):
+ (JSC::JSImmediate::from):
+ * wtf/Platform.h:
+
+2008-12-31 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ [jsfunfuzz] Assertion + incorrect behaviour with dynamically created local variable in a catch block
+ <https://bugs.webkit.org/show_bug.cgi?id=23063>
+
+ Eval inside a catch block attempts to use the catch block's static scope in
+ an unsafe way by attempting to add new properties to the scope. This patch
+ fixes this issue simply by preventing the catch block from using a static
+ scope if it contains an eval.
+
+ * parser/Grammar.y:
+ * parser/Nodes.cpp:
+ (JSC::TryNode::emitBytecode):
+ * parser/Nodes.h:
+ (JSC::TryNode::):
+
+2008-12-31 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ [jsfunfuzz] Computed exception offset wrong when first instruction is attempt to resolve deleted eval
+ <https://bugs.webkit.org/show_bug.cgi?id=23062>
+
+ This was caused by the expression information for the initial resolve of
+ eval not being emitted. If this resolve was the first instruction that
+ could throw an exception the information search would fail leading to an
+ assertion failure. If it was not the first throwable opcode the wrong
+ expression information would used.
+
+ Fix is simply to emit the expression info.
+
+ * parser/Nodes.cpp:
+ (JSC::EvalFunctionCallNode::emitBytecode):
+
+2008-12-31 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 23054: Caching of global lookups occurs even when the global object has become a dictionary
+ <https://bugs.webkit.org/show_bug.cgi?id=23054>
+ <rdar://problem/6469905>
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::resolveGlobal): Do not cache lookup if the global
+ object has transitioned to a dictionary.
+ (JSC::Interpreter::cti_op_resolve_global): Do not cache lookup if the
+ global object has transitioned to a dictionary.
+
+2008-12-30 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <https://bugs.webkit.org/show_bug.cgi?id=23049> [jsfunfuzz] With blocks do not correctly protect their scope object
+ <rdar://problem/6469742> Crash in JSC::TypeInfo::hasStandardGetOwnPropertySlot() running jsfunfuzz
+
+ The problem that caused this was that with nodes were not correctly protecting
+ the final object that was placed in the scope chain. We correct this by forcing
+ the use of a temporary register (which stops us relying on a local register
+ protecting the scope) and changing the behaviour of op_push_scope so that it
+ will store the final scope object.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitPushScope):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::cti_op_push_scope):
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * parser/Nodes.cpp:
+ (JSC::WithNode::emitBytecode):
+
+2008-12-30 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Sam Weinig.
+
+ Bug 23037: Parsing and reparsing disagree on automatic semicolon insertion
+ <https://bugs.webkit.org/show_bug.cgi?id=23037>
+ <rdar://problem/6467124>
+
+ Parsing and reparsing disagree about automatic semicolon insertion, so that a
+ function like
+
+ function() { a = 1, }
+
+ is parsed as being syntactically valid but gets a syntax error upon reparsing.
+ This leads to an assertion failure in Parser::reparse(). It is not that big of
+ an issue in practice, because in a Release build such a function will return
+ 'undefined' when called.
+
+ In this case, we are not following the spec and it should be a syntax error.
+ However, unless there is a newline separating the ',' and the '}', WebKit would
+ not treat it as a syntax error in the past either. It would be a bit of work to
+ make the automatic semicolon insertion match the spec exactly, so this patch
+ changes it to match our past behaviour.
+
+ The problem is that even during reparsing, the Lexer adds a semicolon at the
+ end of the input, which confuses allowAutomaticSemicolon(), because it is
+ expecting either a '}', the end of input, or a terminator like a newline.
+
+ * parser/Lexer.cpp:
+ (JSC::Lexer::Lexer): Initialize m_isReparsing to false.
+ (JSC::Lexer::lex): Do not perform automatic semicolon insertion in the Lexer if
+ we are in the middle of reparsing.
+ (JSC::Lexer::clear): Set m_isReparsing to false.
+ * parser/Lexer.h:
+ (JSC::Lexer::setIsReparsing): Added.
+ * parser/Parser.cpp:
+ (JSC::Parser::reparse): Call Lexer::setIsReparsing() to notify the Lexer of
+ reparsing.
+
+2008-12-29 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Yet another attempt to fix Tiger.
+
+ * wtf/RandomNumber.cpp:
+ (WTF::randomNumber):
+
+2008-12-29 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Tiger build fix (correct this time)
+
+ * wtf/RandomNumber.cpp:
+
+2008-12-29 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Rubber-stamped by Alexey Proskuryakov.
+
+ Revert r39509, because kjsyydebug is used in the generated code if YYDEBUG is 1.
+
+ * parser/Grammar.y:
+
+2008-12-29 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Tiger build fix.
+
+ * wtf/RandomNumber.cpp:
+
+2008-12-29 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ <rdar://problem/6358108> Insecure randomness in Math.random() leads to user tracking
+
+ Switch to arc4random on PLATFORM(DARWIN), this is ~1.5x slower than random(), but the
+ it is still so fast that there is no fathomable way it could be a bottleneck for anything.
+
+ randomNumber is called in two places
+ * During form submission where it is called once per form
+ * Math.random in JSC. For this difference to show up you have to be looping on
+ a cached local copy of random, for a large (>10000) calls.
+
+ No change in SunSpider.
+
+ * wtf/RandomNumber.cpp:
+ (WTF::randomNumber):
+ * wtf/RandomNumberSeed.h:
+ (WTF::initializeRandomNumberGenerator):
+
+2008-12-29 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Rubber-stamped by Sam Weinig.
+
+ Remove unused kjsyydebug #define.
+
+ * parser/Grammar.y:
+
+2008-12-29 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Oliver Hunt and Sam Weinig.
+
+ Bug 23029: REGRESSION (r39337): jsfunfuzz generates identical test files
+ <https://bugs.webkit.org/show_bug.cgi?id=23029>
+ <rdar://problem/6469185>
+
+ The unification of random number generation in r39337 resulted in random()
+ being initialized on Darwin, but rand() actually being used. Fix this by
+ making randomNumber() use random() instead of rand() on Darwin.
+
+ * wtf/RandomNumber.cpp:
+ (WTF::randomNumber):
+
+2008-12-29 Sam Weinig <sam@webkit.org>
+
+ Fix buildbots.
+
+ * runtime/Structure.cpp:
+
+2008-12-29 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ Patch for https://bugs.webkit.org/show_bug.cgi?id=23026
+ Move the deleted offsets vector into the PropertyMap
+
+ Saves 3 words per Structure.
+
+ * runtime/PropertyMapHashTable.h:
+ * runtime/Structure.cpp:
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::getterSetterTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::fromDictionaryTransition):
+ (JSC::Structure::copyPropertyTable):
+ (JSC::Structure::put):
+ (JSC::Structure::remove):
+ (JSC::Structure::rehashPropertyMapHashTable):
+ * runtime/Structure.h:
+ (JSC::Structure::propertyStorageSize):
+
+2008-12-29 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Oliver Hunt.
+
+ Change code using m_body.get() as a boolean to take advantage of the
+ implicit conversion of RefPtr to boolean.
+
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::~JSFunction):
+
+2008-12-28 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 22840: REGRESSION (r38349): Gmail doesn't load with profiling enabled
+ <https://bugs.webkit.org/show_bug.cgi?id=22840>
+ <rdar://problem/6468077>
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitNewArray): Add an assertion that the range
+ of registers passed to op_new_array is sequential.
+ (JSC::BytecodeGenerator::emitCall): Correct the relocation of registers
+ when emitting profiler hooks so that registers aren't leaked. Also, add
+ an assertion that the 'this' register is always ref'd (because it is),
+ remove the needless protection of the 'this' register when relocating,
+ and add an assertion that the range of registers passed to op_call for
+ function call arguments is sequential.
+ (JSC::BytecodeGenerator::emitConstruct): Correct the relocation of
+ registers when emitting profiler hooks so that registers aren't leaked.
+ Also, add an assertion that the range of registers passed to op_construct
+ for function call arguments is sequential.
+
+2008-12-26 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ <rdar://problem/6467376> Race condition in WTF::currentThread can lead to a thread using two different identifiers during its lifetime
+
+ If a newly-created thread calls WTF::currentThread() before WTF::createThread calls establishIdentifierForPthreadHandle
+ then more than one identifier will be used for the same thread. We can avoid this by adding some extra synchronization
+ during thread creation that delays the execution of the thread function until the thread identifier has been set up, and
+ an assertion to catch this problem should it reappear in the future.
+
+ * wtf/Threading.cpp: Added.
+ (WTF::NewThreadContext::NewThreadContext):
+ (WTF::threadEntryPoint):
+ (WTF::createThread): Add cross-platform createThread function that delays the execution of the thread function until
+ after the thread identifier has been set up.
+ * wtf/Threading.h:
+ * wtf/ThreadingGtk.cpp:
+ (WTF::establishIdentifierForThread):
+ (WTF::createThreadInternal):
+ * wtf/ThreadingNone.cpp:
+ (WTF::createThreadInternal):
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::establishIdentifierForPthreadHandle):
+ (WTF::createThreadInternal):
+ * wtf/ThreadingQt.cpp:
+ (WTF::identifierByQthreadHandle):
+ (WTF::establishIdentifierForThread):
+ (WTF::createThreadInternal):
+ * wtf/ThreadingWin.cpp:
+ (WTF::storeThreadHandleByIdentifier):
+ (WTF::createThreadInternal):
+
+ Add Threading.cpp to the build.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+
+2008-12-26 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Remove unused method.
+
+ * runtime/Structure.h: Remove mutableTypeInfo.
+
+2008-12-22 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fix rounding / bounds / signed comparison bug in ExecutableAllocator.
+
+ ExecutableAllocator::alloc assumed that m_freePtr would be aligned. This was
+ not always true, since the first allocation from an additional pool would not
+ be rounded up. Subsequent allocations would be unaligned, and too much memory
+ could be erroneously allocated from the pool, when the size requested was
+ available, but the size rounded up to word granularity was not available in the
+ pool. This may result in the value of m_freePtr being greater than m_end.
+
+ Under these circumstances, the unsigned check for space will always pass,
+ resulting in pointers to memory outside of the arena being returned, and
+ ultimately segfaulty goodness when attempting to memcpy the hot freshly jitted
+ code from the AssemblerBuffer.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22974
+ ... and probably many, many more.
+
+ * jit/ExecutableAllocator.h:
+ (JSC::ExecutablePool::alloc):
+ (JSC::ExecutablePool::roundUpAllocationSize):
+ (JSC::ExecutablePool::ExecutablePool):
+ (JSC::ExecutablePool::poolAllocate):
+
+2008-12-22 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Rename all uses of the term "repatch" to "patch".
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::DataLabelPtr::patch):
+ (JSC::MacroAssembler::DataLabel32::patch):
+ (JSC::MacroAssembler::Jump::patch):
+ (JSC::MacroAssembler::PatchBuffer::PatchBuffer):
+ (JSC::MacroAssembler::PatchBuffer::setPtr):
+ (JSC::MacroAssembler::loadPtrWithAddressOffsetPatch):
+ (JSC::MacroAssembler::storePtrWithAddressOffsetPatch):
+ (JSC::MacroAssembler::storePtrWithPatch):
+ (JSC::MacroAssembler::jnePtrWithPatch):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::patchAddress):
+ (JSC::X86Assembler::patchImmediate):
+ (JSC::X86Assembler::patchPointer):
+ (JSC::X86Assembler::patchBranchOffset):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::tryCTICachePutByID):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::Interpreter::cti_op_put_by_id):
+ (JSC::Interpreter::cti_op_get_by_id):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list):
+ (JSC::Interpreter::cti_vm_dontLazyLinkCall):
+ * jit/JIT.cpp:
+ (JSC::ctiPatchCallByReturnAddress):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITCall.cpp:
+ (JSC::JIT::unlinkCall):
+ (JSC::JIT::linkCall):
+ (JSC::JIT::compileOpCall):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdSlowCase):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::patchGetByIdSelf):
+ (JSC::JIT::patchPutByIdReplace):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+
+2008-12-22 Adam Roben <aroben@apple.com>
+
+ Build fix after r39428
+
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallSlowCase): Added a missing MacroAssembler::
+
+2008-12-22 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com>
+
+ Rubber-stamped by George Staikos.
+
+ Unify all TorchMobile copyright lines. Consolidate in a single line, as requested by Mark Rowe, some time ago.
+
+ * wtf/RandomNumber.cpp:
+ * wtf/RandomNumber.h:
+ * wtf/RandomNumberSeed.h:
+
+2008-12-21 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com>
+
+ Rubber-stamped by George Staikos.
+
+ Fix copyright of the new RandomNumber* files.
+
+ * wtf/RandomNumber.cpp:
+ * wtf/RandomNumber.h:
+ * wtf/RandomNumberSeed.h:
+
+2008-12-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt & Cameron Zwarich.
+
+ Add support for call and property access repatching on x86-64.
+
+ No change in performance on current configurations (2x impovement on v8-tests with JIT enabled on x86-64).
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::DataLabelPtr::repatch):
+ (JSC::MacroAssembler::DataLabelPtr::operator X86Assembler::JmpDst):
+ (JSC::MacroAssembler::DataLabel32::repatch):
+ (JSC::MacroAssembler::RepatchBuffer::addressOf):
+ (JSC::MacroAssembler::add32):
+ (JSC::MacroAssembler::sub32):
+ (JSC::MacroAssembler::loadPtrWithAddressOffsetRepatch):
+ (JSC::MacroAssembler::storePtrWithAddressOffsetRepatch):
+ (JSC::MacroAssembler::jePtr):
+ (JSC::MacroAssembler::jnePtr):
+ (JSC::MacroAssembler::jnePtrWithRepatch):
+ (JSC::MacroAssembler::differenceBetween):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::addl_im):
+ (JSC::X86Assembler::subl_im):
+ (JSC::X86Assembler::cmpl_rm):
+ (JSC::X86Assembler::movq_rm_disp32):
+ (JSC::X86Assembler::movq_mr_disp32):
+ (JSC::X86Assembler::repatchPointer):
+ (JSC::X86Assembler::X86InstructionFormatter::oneByteOp64_disp32):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITCall.cpp:
+ (JSC::JIT::unlinkCall):
+ (JSC::JIT::linkCall):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::restoreArgumentReferenceForTrampoline):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::compilePutByIdSlowCase):
+ (JSC::resizePropertyStorage):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * wtf/Platform.h:
+
+2008-12-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Port optimized property access generation to the MacroAssembler.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::AbsoluteAddress::AbsoluteAddress):
+ (JSC::MacroAssembler::DataLabelPtr::repatch):
+ (JSC::MacroAssembler::DataLabel32::DataLabel32):
+ (JSC::MacroAssembler::DataLabel32::repatch):
+ (JSC::MacroAssembler::Label::operator X86Assembler::JmpDst):
+ (JSC::MacroAssembler::Jump::repatch):
+ (JSC::MacroAssembler::JumpList::empty):
+ (JSC::MacroAssembler::RepatchBuffer::link):
+ (JSC::MacroAssembler::add32):
+ (JSC::MacroAssembler::and32):
+ (JSC::MacroAssembler::sub32):
+ (JSC::MacroAssembler::loadPtrWithAddressRepatch):
+ (JSC::MacroAssembler::storePtrWithAddressRepatch):
+ (JSC::MacroAssembler::push):
+ (JSC::MacroAssembler::ja32):
+ (JSC::MacroAssembler::jePtr):
+ (JSC::MacroAssembler::jnePtr):
+ (JSC::MacroAssembler::jnePtrWithRepatch):
+ (JSC::MacroAssembler::align):
+ (JSC::MacroAssembler::differenceBetween):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::movl_rm_disp32):
+ (JSC::X86Assembler::movl_mr_disp32):
+ (JSC::X86Assembler::X86InstructionFormatter::oneByteOp_disp32):
+ (JSC::X86Assembler::X86InstructionFormatter::memoryModRM):
+ * jit/JIT.cpp:
+ (JSC::ctiRepatchCallByReturnAddress):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::compilePutByIdSlowCase):
+ (JSC::resizePropertyStorage):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::patchGetByIdSelf):
+ (JSC::JIT::patchPutByIdReplace):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+ * wtf/RefCounted.h:
+ (WTF::RefCountedBase::addressOfCount):
+
+2008-12-19 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22686
+
+ Added file which was missing to the javascriptcore_sources
+ variable, so that it shows up in the tarball created by `make
+ dist'.
+
+ * GNUmakefile.am:
+
+2008-12-19 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Antti Koivisto.
+
+ Build fix when building JS API tests with a c89 c compiler
+
+ Do not use C++ style comments and convert them to C comments.
+
+ * wtf/Platform.h:
+
+2008-12-18 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Same as last revision, adding cases for pre & post inc & dec.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22928
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+
+2008-12-18 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixes for the JIT's handling of JSImmediate values on x86-64.
+ On 64-bit systems, the code in JSImmediate.h relies on the upper
+ bits of a JSImmediate being a sign extension of the low 32-bits.
+ This was not being enforced by the JIT, since a number of inline
+ operations were being performed on 32-bit values in registers, and
+ when a 32-bit result is written to a register on x86-64 the value
+ is zero-extended to 64-bits.
+
+ This fix honors previous behavoir. A better fix in the long run
+ (when the JIT is enabled by default) may be to change JSImmediate.h
+ so it no longer relies on the upper bits of the pointer,... though
+ if we're going to change JSImmediate.h for 64-bit, we probably may
+ as well change the format so that the full range of 32-bit ints can
+ be stored, rather than just 31-bits.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22925
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::addPtr):
+ (JSC::MacroAssembler::andPtr):
+ (JSC::MacroAssembler::orPtr):
+ (JSC::MacroAssembler::or32):
+ (JSC::MacroAssembler::xor32):
+ (JSC::MacroAssembler::xorPtr):
+ (JSC::MacroAssembler::signExtend32ToPtr):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::andq_rr):
+ (JSC::X86Assembler::andq_ir):
+ (JSC::X86Assembler::orq_rr):
+ (JSC::X86Assembler::xorq_ir):
+ (JSC::X86Assembler::movsxd_rr):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitFastArithReTagImmediate):
+ (JSC::JIT::emitFastArithPotentiallyReTagImmediate):
+ (JSC::JIT::emitFastArithImmToInt):
+
+2008-12-18 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Just a tidy up - rename & refactor some the #defines configuring the JIT.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_op_convert_this):
+ (JSC::Interpreter::cti_op_end):
+ (JSC::Interpreter::cti_op_add):
+ (JSC::Interpreter::cti_op_pre_inc):
+ (JSC::Interpreter::cti_timeout_check):
+ (JSC::Interpreter::cti_register_file_check):
+ (JSC::Interpreter::cti_op_loop_if_less):
+ (JSC::Interpreter::cti_op_loop_if_lesseq):
+ (JSC::Interpreter::cti_op_new_object):
+ (JSC::Interpreter::cti_op_put_by_id_generic):
+ (JSC::Interpreter::cti_op_get_by_id_generic):
+ (JSC::Interpreter::cti_op_put_by_id):
+ (JSC::Interpreter::cti_op_put_by_id_second):
+ (JSC::Interpreter::cti_op_put_by_id_fail):
+ (JSC::Interpreter::cti_op_get_by_id):
+ (JSC::Interpreter::cti_op_get_by_id_second):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list_full):
+ (JSC::Interpreter::cti_op_get_by_id_proto_fail):
+ (JSC::Interpreter::cti_op_get_by_id_array_fail):
+ (JSC::Interpreter::cti_op_get_by_id_string_fail):
+ (JSC::Interpreter::cti_op_instanceof):
+ (JSC::Interpreter::cti_op_del_by_id):
+ (JSC::Interpreter::cti_op_mul):
+ (JSC::Interpreter::cti_op_new_func):
+ (JSC::Interpreter::cti_op_call_JSFunction):
+ (JSC::Interpreter::cti_op_call_arityCheck):
+ (JSC::Interpreter::cti_vm_dontLazyLinkCall):
+ (JSC::Interpreter::cti_vm_lazyLinkCall):
+ (JSC::Interpreter::cti_op_push_activation):
+ (JSC::Interpreter::cti_op_call_NotJSFunction):
+ (JSC::Interpreter::cti_op_create_arguments):
+ (JSC::Interpreter::cti_op_create_arguments_no_params):
+ (JSC::Interpreter::cti_op_tear_off_activation):
+ (JSC::Interpreter::cti_op_tear_off_arguments):
+ (JSC::Interpreter::cti_op_profile_will_call):
+ (JSC::Interpreter::cti_op_profile_did_call):
+ (JSC::Interpreter::cti_op_ret_scopeChain):
+ (JSC::Interpreter::cti_op_new_array):
+ (JSC::Interpreter::cti_op_resolve):
+ (JSC::Interpreter::cti_op_construct_JSConstruct):
+ (JSC::Interpreter::cti_op_construct_NotJSConstruct):
+ (JSC::Interpreter::cti_op_get_by_val):
+ (JSC::Interpreter::cti_op_resolve_func):
+ (JSC::Interpreter::cti_op_sub):
+ (JSC::Interpreter::cti_op_put_by_val):
+ (JSC::Interpreter::cti_op_put_by_val_array):
+ (JSC::Interpreter::cti_op_lesseq):
+ (JSC::Interpreter::cti_op_loop_if_true):
+ (JSC::Interpreter::cti_op_negate):
+ (JSC::Interpreter::cti_op_resolve_base):
+ (JSC::Interpreter::cti_op_resolve_skip):
+ (JSC::Interpreter::cti_op_resolve_global):
+ (JSC::Interpreter::cti_op_div):
+ (JSC::Interpreter::cti_op_pre_dec):
+ (JSC::Interpreter::cti_op_jless):
+ (JSC::Interpreter::cti_op_not):
+ (JSC::Interpreter::cti_op_jtrue):
+ (JSC::Interpreter::cti_op_post_inc):
+ (JSC::Interpreter::cti_op_eq):
+ (JSC::Interpreter::cti_op_lshift):
+ (JSC::Interpreter::cti_op_bitand):
+ (JSC::Interpreter::cti_op_rshift):
+ (JSC::Interpreter::cti_op_bitnot):
+ (JSC::Interpreter::cti_op_resolve_with_base):
+ (JSC::Interpreter::cti_op_new_func_exp):
+ (JSC::Interpreter::cti_op_mod):
+ (JSC::Interpreter::cti_op_less):
+ (JSC::Interpreter::cti_op_neq):
+ (JSC::Interpreter::cti_op_post_dec):
+ (JSC::Interpreter::cti_op_urshift):
+ (JSC::Interpreter::cti_op_bitxor):
+ (JSC::Interpreter::cti_op_new_regexp):
+ (JSC::Interpreter::cti_op_bitor):
+ (JSC::Interpreter::cti_op_call_eval):
+ (JSC::Interpreter::cti_op_throw):
+ (JSC::Interpreter::cti_op_get_pnames):
+ (JSC::Interpreter::cti_op_next_pname):
+ (JSC::Interpreter::cti_op_push_scope):
+ (JSC::Interpreter::cti_op_pop_scope):
+ (JSC::Interpreter::cti_op_typeof):
+ (JSC::Interpreter::cti_op_is_undefined):
+ (JSC::Interpreter::cti_op_is_boolean):
+ (JSC::Interpreter::cti_op_is_number):
+ (JSC::Interpreter::cti_op_is_string):
+ (JSC::Interpreter::cti_op_is_object):
+ (JSC::Interpreter::cti_op_is_function):
+ (JSC::Interpreter::cti_op_stricteq):
+ (JSC::Interpreter::cti_op_nstricteq):
+ (JSC::Interpreter::cti_op_to_jsnumber):
+ (JSC::Interpreter::cti_op_in):
+ (JSC::Interpreter::cti_op_push_new_scope):
+ (JSC::Interpreter::cti_op_jmp_scopes):
+ (JSC::Interpreter::cti_op_put_by_index):
+ (JSC::Interpreter::cti_op_switch_imm):
+ (JSC::Interpreter::cti_op_switch_char):
+ (JSC::Interpreter::cti_op_switch_string):
+ (JSC::Interpreter::cti_op_del_by_val):
+ (JSC::Interpreter::cti_op_put_getter):
+ (JSC::Interpreter::cti_op_put_setter):
+ (JSC::Interpreter::cti_op_new_error):
+ (JSC::Interpreter::cti_op_debug):
+ (JSC::Interpreter::cti_vm_throw):
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::restoreArgumentReference):
+ (JSC::JIT::restoreArgumentReferenceForTrampoline):
+ * wtf/Platform.h:
+
+2008-12-18 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 21855: REGRESSION (r37323): Gmail complains about popup blocking when opening a link
+ <https://bugs.webkit.org/show_bug.cgi?id=21855>
+ <rdar://problem/6278244>
+
+ Move DynamicGlobalObjectScope to JSGlobalObject.h so that it can be used
+ from WebCore.
+
+ * interpreter/Interpreter.cpp:
+ * runtime/JSGlobalObject.h:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope):
+ (JSC::DynamicGlobalObjectScope::~DynamicGlobalObjectScope):
+
+2008-12-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Fixed https://bugs.webkit.org/show_bug.cgi?id=22393
+ Segfault when caching property accesses to primitive cells.
+
+ Changed some asObject casts to asCell casts in cases where a primitive
+ value may be a cell and not an object.
+
+ Re-enabled property caching for primitives in cases where it had been
+ disabled because of this bug.
+
+ Updated a comment to better explain something Darin thought needed
+ explaining in an old patch review.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::countPrototypeChainEntriesAndCheckForProxies):
+ (JSC::Interpreter::tryCacheGetByID):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list):
+
+2008-12-17 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Fixes for Sunspider failures with the JIT enabled on x86-64.
+
+ * assembler/MacroAssembler.h:
+ Switch the order of the RegisterID & Address form of je32, to keep it consistent with jne32.
+ * jit/JIT.cpp:
+ * jit/JIT.h:
+ * jit/JITInlineMethods.h:
+ Port the m_ctiVirtualCall tramopline generation to use the MacroAssembler interface.
+ * jit/JITCall.cpp:
+ Fix bug in the non-optimizing code path, vptr check should have been to the memory address pointer
+ to by the register, not to the register itself.
+ * wrec/WRECGenerator.cpp:
+ See assembler/MacroAssembler.h, above.
+
+2008-12-17 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ print("Hello, 64-bit jitted world!");
+ Get hello-world working through the JIT, on x86-64.
+
+ * assembler/X86Assembler.h:
+ Fix encoding of opcode + RegisterID format instructions for 64-bit.
+ * interpreter/Interpreter.cpp:
+ * interpreter/Interpreter.h:
+ Make VoidPtrPair actually be a pair of void*s.
+ (Possibly should make this change for 32-bit Mac platforms, too - but won't change 32-bit behaviour in this patch).
+ * jit/JIT.cpp:
+ * jit/JIT.h:
+ Provide names for the timeoutCheckRegister & callFrameRegister on x86-64,
+ force x86-64 ctiTrampoline arguments onto the stack,
+ implement the asm trampolines for x86-64,
+ implement the restoreArgumentReference methods for x86-64 calling conventions.
+ * jit/JITCall.cpp:
+ * jit/JITInlineMethods.h:
+ * wtf/Platform.h:
+ Add switch settings to ENABLE(JIT), on PLATFORM(X86_64) (currently still disabled).
+
+2008-12-17 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Add more CodeBlock statistics.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpStatistics):
+
+2008-12-17 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=22897
+ <rdar://problem/6428342>
+ Look into feasibility of discarding bytecode after native codegen
+
+ Clear the bytecode Instruction vector at the end JIT generation.
+
+ Saves 4.8 MB on Membuster head.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump): Add logging for the case that someone tries
+ to dump the instructions of a CodeBlock that has had its bytecode
+ vector cleared.
+ (JSC::CodeBlock::CodeBlock): Initialize the instructionCount
+ (JSC::CodeBlock::handlerForBytecodeOffset): Use instructionCount instead
+ of the size of the instruction vector in the assertion.
+ (JSC::CodeBlock::lineNumberForBytecodeOffset): Ditto.
+ (JSC::CodeBlock::expressionRangeForBytecodeOffset): Ditto.
+ (JSC::CodeBlock::getByIdExceptionInfoForBytecodeOffset): Ditto.
+ (JSC::CodeBlock::functionRegisterForBytecodeOffset): Ditto.
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::setInstructionCount): Store the instruction vector size
+ in debug builds for assertions.
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile): Clear the bytecode vector unless we
+ have compiled with Opcode sampling where we will continue to require it
+
+2008-12-17 Cary Clark <caryclark@google.com>
+
+ Reviewed by Darin Adler.
+ Landed by Adam Barth.
+
+ Add ENABLE_TEXT_CARET to permit the ANDROID platform
+ to invalidate and draw the caret in a separate thread.
+
+ * wtf/Platform.h:
+ Default ENABLE_TEXT_CARET to 1.
+
+2008-12-17 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Don't use unique context group in JSGlobalContextCreate() on Tiger or Leopard, take two.
+
+ * API/JSContextRef.cpp: The previous patch that claimed to do this was making Tiger and
+ Leopard always use unique context group instead.
+
+2008-12-16 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=22838
+ Remove dependency on the bytecode Instruction buffer in Interpreter::throwException
+ Part of <rdar://problem/6428342>
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::functionRegisterForBytecodeOffset): Added. Function to get
+ a function Register index in a callFrame for a bytecode offset.
+ (JSC::CodeBlock::shrinkToFit): Shrink m_getByIdExceptionInfo and m_functionRegisterInfos.
+ * bytecode/CodeBlock.h:
+ (JSC::FunctionRegisterInfo::FunctionRegisterInfo): Added.
+ (JSC::CodeBlock::addFunctionRegisterInfo):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitCall):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException): Use functionRegisterForBytecodeOffset in JIT
+ mode.
+
+2008-12-16 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=22837
+ Remove dependency on the bytecode Instruction buffer in Interpreter::cti_op_call_NotJSFunction
+ Part of <rdar://problem/6428342>
+
+ * interpreter/CallFrame.h: Added comment regarding returnPC storing a void*.
+ * interpreter/Interpreter.cpp:
+ (JSC::bytecodeOffsetForPC): We no longer have any cases of the PC
+ being in the instruction stream for JIT, so we can remove the check.
+ (JSC::Interpreter::cti_op_call_NotJSFunction): Use the CTI_RETURN_ADDRESS
+ as the call frame returnPC as it is only necessary for looking up when
+ throwing an exception.
+ * interpreter/RegisterFile.h:
+ (JSC::RegisterFile::): Added comment regarding returnPC storing a void*.
+ * jit/JIT.h: Remove ARG_instr4.
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallSetupArgs): Don't pass the instruction pointer.
+
+2008-12-16 Darin Adler <darin@apple.com>
+
+ Reviewed and landed by Cameron Zwarich.
+
+ Preparatory work for fixing
+
+ Bug 22887: Make UString::Rep use RefCounted rather than implementing its own ref counting
+ <https://bugs.webkit.org/show_bug.cgi?id=22887>
+
+ Change the various string translators used by Identifier:add() so that
+ they never zero the ref count of a newly created UString::Rep.
+
+ * runtime/Identifier.cpp:
+ (JSC::CStringTranslator::translate):
+ (JSC::Identifier::add):
+ (JSC::UCharBufferTranslator::translate):
+
+2008-12-16 Gavin Barraclough <barraclough@apple.com>
+
+ Build fix for 'doze.
+
+ * assembler/AssemblerBuffer.h:
+
+2008-12-16 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Make the JIT compile on x86-64.
+ This largely involves populting the missing calls in MacroAssembler.h.
+ In addition some reinterpret_casts need removing from the JIT, and the
+ repatching property access code will need to be fully compiled out for
+ now. The changes in interpret.cpp are to reorder the functions so that
+ the _generic forms come before all other property access methods, and
+ then to place all property access methods other than the generic forms
+ under control of the ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS macro.
+
+ No performance impact.
+
+ * assembler/AssemblerBuffer.h:
+ (JSC::AssemblerBuffer::putInt64Unchecked):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::loadPtr):
+ (JSC::MacroAssembler::load32):
+ (JSC::MacroAssembler::storePtr):
+ (JSC::MacroAssembler::storePtrWithRepatch):
+ (JSC::MacroAssembler::store32):
+ (JSC::MacroAssembler::poke):
+ (JSC::MacroAssembler::move):
+ (JSC::MacroAssembler::testImm64):
+ (JSC::MacroAssembler::jePtr):
+ (JSC::MacroAssembler::jnePtr):
+ (JSC::MacroAssembler::jnzPtr):
+ (JSC::MacroAssembler::jzPtr):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::cmpq_rr):
+ (JSC::X86Assembler::cmpq_rm):
+ (JSC::X86Assembler::cmpq_im):
+ (JSC::X86Assembler::testq_i32m):
+ (JSC::X86Assembler::movl_mEAX):
+ (JSC::X86Assembler::movl_i32r):
+ (JSC::X86Assembler::movl_EAXm):
+ (JSC::X86Assembler::movq_rm):
+ (JSC::X86Assembler::movq_mEAX):
+ (JSC::X86Assembler::movq_mr):
+ (JSC::X86Assembler::movq_i64r):
+ (JSC::X86Assembler::movl_mr):
+ (JSC::X86Assembler::X86InstructionFormatter::oneByteOp64):
+ (JSC::X86Assembler::X86InstructionFormatter::immediate64):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_op_put_by_id_generic):
+ (JSC::Interpreter::cti_op_get_by_id_generic):
+ (JSC::Interpreter::cti_op_put_by_id):
+ (JSC::Interpreter::cti_op_put_by_id_second):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallSetupArgs):
+ (JSC::JIT::compileOpCall):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compilePutByIdHotPath):
+ * runtime/JSImmediate.h:
+ (JSC::JSImmediate::makeInt):
+
+2008-12-16 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Bug 22869: REGRESSION (r38407): http://news.cnet.com/8301-13579_3-9953533-37.html crashes
+ <https://bugs.webkit.org/show_bug.cgi?id=22869>
+ <rdar://problem/6402499>
+
+ Before r38407, Structure::m_nameInPrevious was ref'd due to it being
+ stored in a PropertyMap. However, PropertyMaps are created lazily after
+ r38407, so Structure::m_nameInPrevious is not necessarily ref'd while
+ it is being used. Making it a RefPtr instead of a raw pointer fixes
+ the problem.
+
+ Unfortunately, the crash in the bug is rather intermittent, and it is
+ impossible to add an assertion in UString::Ref::ref() to catch this bug
+ because some users of UString::Rep deliberately zero out the reference
+ count. Therefore, there is no layout test accompanying this bug fix.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::~Structure): Use get().
+ (JSC::Structure::materializePropertyMap): Use get().
+ (JSC::Structure::addPropertyTransitionToExistingStructure): Use get().
+ (JSC::Structure::addPropertyTransition): Use get().
+ * runtime/Structure.h: Make Structure::m_nameInPrevious a RefPtr instead
+ of a raw pointer.
+
+2008-12-16 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com>
+
+ Not reviewed. Attempt to fix win build. No 'using namespace WTF' in this file, needs manual WTF:: prefix.
+ Not sure why the build works as is here.
+
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncRandom):
+
+2008-12-16 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com>
+
+ Reviewed by Darin Adler.
+
+ Fixes: https://bugs.webkit.org/show_bug.cgi?id=22876
+
+ Unify random number generation in JavaScriptCore & WebCore, by introducing
+ wtf/RandomNumber.h and moving wtf_random/wtf_random_init out of MathExtras.h.
+
+ wtf_random_init() has been renamed to initializeRandomNumberGenerator() and
+ lives in it's own private header: wtf/RandomNumberSeed.h, only intended to
+ be used from within JavaScriptCore.
+
+ wtf_random() has been renamed to randomNumber() and lives in a public header
+ wtf/RandomNumber.h, usable from within JavaScriptCore & WebCore. It encapsulates
+ the code taking care of initializing the random number generator (only when
+ building without ENABLE(JSC_MULTIPLE_THREADS), otherwhise initializeThreading()
+ already took care of that).
+
+ Functional change on darwin: Use random() instead of rand(), as it got a larger
+ period (more randomness). HTMLFormElement already contains this implementation
+ and I just moved it in randomNumber(), as special case for PLATFORM(DARWIN).
+
+ * GNUmakefile.am: Add RandomNumber.(cpp/h) / RandomNumberSeed.h.
+ * JavaScriptCore.exp: Ditto.
+ * JavaScriptCore.pri: Ditto.
+ * JavaScriptCore.scons: Ditto.
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj: Ditto.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
+ * JavaScriptCoreSources.bkl: Ditto.
+ * runtime/MathObject.cpp: Use new WTF::randomNumber() functionality.
+ (JSC::mathProtoFuncRandom):
+ * wtf/MathExtras.h: Move wtf_random / wtf_random_init to new files.
+ * wtf/RandomNumber.cpp: Added.
+ (WTF::randomNumber):
+ * wtf/RandomNumber.h: Added.
+ * wtf/RandomNumberSeed.h: Added. Internal usage within JSC only.
+ (WTF::initializeRandomNumberGenerator):
+ * wtf/ThreadingGtk.cpp: Rename wtf_random_init() to initializeRandomNumberGenerator().
+ (WTF::initializeThreading):
+ * wtf/ThreadingPthreads.cpp: Ditto.
+ (WTF::initializeThreading):
+ * wtf/ThreadingQt.cpp: Ditto.
+ (WTF::initializeThreading):
+ * wtf/ThreadingWin.cpp: Ditto.
+ (WTF::initializeThreading):
+
+2008-12-16 Yael Aharon <yael.aharon@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Qt/Win build fix
+
+ * JavaScriptCore.pri:
+
+2008-12-15 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Fix the build with GCC 4.0.
+
+ * Configurations/JavaScriptCore.xcconfig: GCC 4.0 appears to have a bug when compiling with -funwind-tables on,
+ so don't use it with that compiler version.
+
+2008-12-15 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Cameron Zwarich.
+
+ <rdar://problem/6289933> Change WebKit-related projects to build with GCC 4.2 on Leopard.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/DebugRelease.xcconfig:
+
+2008-12-15 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Don't use unique context group in JSGlobalContextCreate() on Tiger or Leopard.
+
+ * API/JSContextRef.cpp: (JSGlobalContextCreate):
+
+2008-12-15 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/6445089> Mach ports leak from worker threads
+
+ * interpreter/Interpreter.cpp: (JSC::getCPUTime):
+ Deallocate the thread self port.
+
+2008-12-15 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Construct stack frames in JIT code, so that backtracing can still work.
+ <rdar://problem/6447870> JIT should play nice with attempts to take stack traces
+
+ * jit/JIT.cpp:
+ (JSC::):
+ (JSC::JIT::privateCompileMainPass):
+
+2008-12-15 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ <rdar://problem/6402262> JavaScriptCore needs exception handling tables in order to get stack traces without frame pointers
+
+ * Configurations/JavaScriptCore.xcconfig:
+
+2008-12-15 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber stamped by Mark Rowe.
+
+ Revert r39226 / Bug 22818: Unify JIT callback argument access OS X / Windows
+ This causes Acid3 failures – reverting for now & will revisit later.
+ https://bugs.webkit.org/show_bug.cgi?id=22873
+
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::restoreArgumentReference):
+ (JSC::JIT::restoreArgumentReferenceForTrampoline):
+ (JSC::JIT::emitCTICall_internal):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+ * wtf/Platform.h:
+
+2008-12-15 Darin Adler <darin@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ - fix <rdar://problem/6427048> crash due to infinite recursion after setting window.__proto__ = window
+
+ Replaced toGlobalObject with the more generally useful unwrappedObject and used it to
+ fix the cycle detection code in put(__proto__).
+
+ * JavaScriptCore.exp: Updated.
+
+ * runtime/JSGlobalObject.cpp: Removed toGlobalObject. We now use unwrappedObject instead.
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::isGlobalObject): Ditto.
+
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncEval): Use unwrappedObject and isGlobalObject here rather than toGlobalObject.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::put): Rewrote prototype cycle checking loop. Use unwrappedObject in the loop now.
+ (JSC::JSObject::unwrappedObject): Replaced toGlobalObject with this new function.
+ * runtime/JSObject.h: More of the same.
+
+2008-12-15 Steve Falkenburg <sfalken@apple.com>
+
+ Windows build fix.
+
+ Visual Studio requires visibility of forward declarations to match class declaration.
+
+ * assembler/X86Assembler.h:
+
+2008-12-15 Gustavo Noronha Silva <kov@kov.eti.br>
+
+ Reviewed by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22686
+
+ GTK+ build fix.
+
+ * GNUmakefile.am:
+
+2008-12-15 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Add support to X86Assembler emitting instructions that access all 16 registers on x86-64.
+ Add a new formating class, that is reponsible for both emitting the opcode bytes and the
+ ModRm bytes of an instruction in a single call; this can insert the REX byte as necessary
+ before the opcode, but has access to the register numbers to build the REX.
+
+ * assembler/AssemblerBuffer.h:
+ (JSC::AssemblerBuffer::isAligned):
+ (JSC::AssemblerBuffer::data):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::addPtr):
+ (JSC::MacroAssembler::add32):
+ (JSC::MacroAssembler::and32):
+ (JSC::MacroAssembler::or32):
+ (JSC::MacroAssembler::sub32):
+ (JSC::MacroAssembler::xor32):
+ (JSC::MacroAssembler::loadPtr):
+ (JSC::MacroAssembler::load32):
+ (JSC::MacroAssembler::load16):
+ (JSC::MacroAssembler::storePtr):
+ (JSC::MacroAssembler::storePtrWithRepatch):
+ (JSC::MacroAssembler::store32):
+ (JSC::MacroAssembler::pop):
+ (JSC::MacroAssembler::push):
+ (JSC::MacroAssembler::compareImm32ForBranch):
+ (JSC::MacroAssembler::compareImm32ForBranchEquality):
+ (JSC::MacroAssembler::testImm32):
+ (JSC::MacroAssembler::jae32):
+ (JSC::MacroAssembler::jb32):
+ (JSC::MacroAssembler::je16):
+ (JSC::MacroAssembler::jg32):
+ (JSC::MacroAssembler::jnePtr):
+ (JSC::MacroAssembler::jne32):
+ (JSC::MacroAssembler::jump):
+ * assembler/X86Assembler.h:
+ (JSC::X86::):
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::size):
+ (JSC::X86Assembler::push_r):
+ (JSC::X86Assembler::pop_r):
+ (JSC::X86Assembler::push_i32):
+ (JSC::X86Assembler::push_m):
+ (JSC::X86Assembler::pop_m):
+ (JSC::X86Assembler::addl_rr):
+ (JSC::X86Assembler::addl_mr):
+ (JSC::X86Assembler::addl_ir):
+ (JSC::X86Assembler::addq_ir):
+ (JSC::X86Assembler::addl_im):
+ (JSC::X86Assembler::andl_rr):
+ (JSC::X86Assembler::andl_ir):
+ (JSC::X86Assembler::orl_rr):
+ (JSC::X86Assembler::orl_mr):
+ (JSC::X86Assembler::orl_ir):
+ (JSC::X86Assembler::subl_rr):
+ (JSC::X86Assembler::subl_mr):
+ (JSC::X86Assembler::subl_ir):
+ (JSC::X86Assembler::subl_im):
+ (JSC::X86Assembler::xorl_rr):
+ (JSC::X86Assembler::xorl_ir):
+ (JSC::X86Assembler::sarl_i8r):
+ (JSC::X86Assembler::sarl_CLr):
+ (JSC::X86Assembler::shll_i8r):
+ (JSC::X86Assembler::shll_CLr):
+ (JSC::X86Assembler::imull_rr):
+ (JSC::X86Assembler::imull_i32r):
+ (JSC::X86Assembler::idivl_r):
+ (JSC::X86Assembler::cmpl_rr):
+ (JSC::X86Assembler::cmpl_rm):
+ (JSC::X86Assembler::cmpl_mr):
+ (JSC::X86Assembler::cmpl_ir):
+ (JSC::X86Assembler::cmpl_ir_force32):
+ (JSC::X86Assembler::cmpl_im):
+ (JSC::X86Assembler::cmpl_im_force32):
+ (JSC::X86Assembler::cmpw_rm):
+ (JSC::X86Assembler::testl_rr):
+ (JSC::X86Assembler::testl_i32r):
+ (JSC::X86Assembler::testl_i32m):
+ (JSC::X86Assembler::testq_rr):
+ (JSC::X86Assembler::testq_i32r):
+ (JSC::X86Assembler::testb_i8r):
+ (JSC::X86Assembler::sete_r):
+ (JSC::X86Assembler::setz_r):
+ (JSC::X86Assembler::setne_r):
+ (JSC::X86Assembler::setnz_r):
+ (JSC::X86Assembler::cdq):
+ (JSC::X86Assembler::xchgl_rr):
+ (JSC::X86Assembler::movl_rr):
+ (JSC::X86Assembler::movl_rm):
+ (JSC::X86Assembler::movl_mr):
+ (JSC::X86Assembler::movl_i32r):
+ (JSC::X86Assembler::movl_i32m):
+ (JSC::X86Assembler::movq_rr):
+ (JSC::X86Assembler::movq_rm):
+ (JSC::X86Assembler::movq_mr):
+ (JSC::X86Assembler::movzwl_mr):
+ (JSC::X86Assembler::movzbl_rr):
+ (JSC::X86Assembler::leal_mr):
+ (JSC::X86Assembler::call):
+ (JSC::X86Assembler::jmp):
+ (JSC::X86Assembler::jmp_r):
+ (JSC::X86Assembler::jmp_m):
+ (JSC::X86Assembler::jne):
+ (JSC::X86Assembler::jnz):
+ (JSC::X86Assembler::je):
+ (JSC::X86Assembler::jl):
+ (JSC::X86Assembler::jb):
+ (JSC::X86Assembler::jle):
+ (JSC::X86Assembler::jbe):
+ (JSC::X86Assembler::jge):
+ (JSC::X86Assembler::jg):
+ (JSC::X86Assembler::ja):
+ (JSC::X86Assembler::jae):
+ (JSC::X86Assembler::jo):
+ (JSC::X86Assembler::jp):
+ (JSC::X86Assembler::js):
+ (JSC::X86Assembler::addsd_rr):
+ (JSC::X86Assembler::addsd_mr):
+ (JSC::X86Assembler::cvtsi2sd_rr):
+ (JSC::X86Assembler::cvttsd2si_rr):
+ (JSC::X86Assembler::movd_rr):
+ (JSC::X86Assembler::movsd_rm):
+ (JSC::X86Assembler::movsd_mr):
+ (JSC::X86Assembler::mulsd_rr):
+ (JSC::X86Assembler::mulsd_mr):
+ (JSC::X86Assembler::pextrw_irr):
+ (JSC::X86Assembler::subsd_rr):
+ (JSC::X86Assembler::subsd_mr):
+ (JSC::X86Assembler::ucomis_rr):
+ (JSC::X86Assembler::int3):
+ (JSC::X86Assembler::ret):
+ (JSC::X86Assembler::predictNotTaken):
+ (JSC::X86Assembler::label):
+ (JSC::X86Assembler::align):
+ (JSC::X86Assembler::link):
+ (JSC::X86Assembler::executableCopy):
+ (JSC::X86Assembler::X86InstructionFormater::prefix):
+ (JSC::X86Assembler::X86InstructionFormater::oneByteOp):
+ (JSC::X86Assembler::X86InstructionFormater::twoByteOp):
+ (JSC::X86Assembler::X86InstructionFormater::oneByteOp64):
+ (JSC::X86Assembler::X86InstructionFormater::oneByteOp8):
+ (JSC::X86Assembler::X86InstructionFormater::twoByteOp8):
+ (JSC::X86Assembler::X86InstructionFormater::instructionImmediate8):
+ (JSC::X86Assembler::X86InstructionFormater::instructionImmediate32):
+ (JSC::X86Assembler::X86InstructionFormater::instructionRel32):
+ (JSC::X86Assembler::X86InstructionFormater::size):
+ (JSC::X86Assembler::X86InstructionFormater::isAligned):
+ (JSC::X86Assembler::X86InstructionFormater::data):
+ (JSC::X86Assembler::X86InstructionFormater::executableCopy):
+ (JSC::X86Assembler::X86InstructionFormater::registerModRM):
+ (JSC::X86Assembler::X86InstructionFormater::memoryModRM):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::JIT::compileBinaryArithOp):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+
+2008-12-15 Darin Adler <darin@apple.com>
+
+ * interpreter/RegisterFile.h: Tweak include formatting.
+
+2008-12-15 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Build fix for Gtk+.
+
+ * interpreter/RegisterFile.h: Include stdio.h for fprintf
+
+2008-12-15 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/6444455> Worker Thread crash running multiple workers for a moderate amount of time
+
+ * interpreter/RegisterFile.h: (JSC::RegisterFile::RegisterFile):
+ Improve error handling: if mmap fails, crash immediately, and print out the reason.
+
+2008-12-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Re-enable WREC on 64-bit.
+ Implements one of the MacroAssembler::jnzPtr methods, previously only implemented for 32-bit x86.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22849
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::testImm64):
+ (JSC::MacroAssembler::jnzPtr):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::testq_i32r):
+ (JSC::X86Assembler::testq_rr):
+ * wtf/Platform.h:
+
+2008-12-13 Gavin Barraclough <barraclough@apple.com>
+
+ Fix PPC builds.
+
+ * assembler/MacroAssembler.h:
+
+2008-12-13 Gavin Barraclough <barraclough@apple.com>
+
+ Build fix only, no review.
+
+ * bytecode/CodeBlock.h:
+
+2008-12-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Port the remainder of the JIT, bar calling convention related code, and code
+ implementing optimizations which can be disabled, to use the MacroAssembler.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::DataLabelPtr::DataLabelPtr):
+ (JSC::MacroAssembler::RepatchBuffer::RepatchBuffer):
+ (JSC::MacroAssembler::RepatchBuffer::link):
+ (JSC::MacroAssembler::RepatchBuffer::addressOf):
+ (JSC::MacroAssembler::RepatchBuffer::setPtr):
+ (JSC::MacroAssembler::addPtr):
+ (JSC::MacroAssembler::lshift32):
+ (JSC::MacroAssembler::mod32):
+ (JSC::MacroAssembler::rshift32):
+ (JSC::MacroAssembler::storePtrWithRepatch):
+ (JSC::MacroAssembler::jnzPtr):
+ (JSC::MacroAssembler::jzPtr):
+ (JSC::MacroAssembler::jump):
+ (JSC::MacroAssembler::label):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::xchgl_rr):
+ (JSC::X86Assembler::jmp_m):
+ (JSC::X86Assembler::repatchAddress):
+ (JSC::X86Assembler::getRelocatedAddress):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (JSC::JITCodeRef::JITCodeRef):
+ (JSC::CodeBlock::setJITCode):
+ (JSC::CodeBlock::jitCode):
+ (JSC::CodeBlock::executablePool):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileLinkPass):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ (JSC::CallRecord::CallRecord):
+ (JSC::JumpTable::JumpTable):
+ (JSC::JIT::emitCTICall):
+ (JSC::JIT::JSRInfo::JSRInfo):
+ * jit/JITArithmetic.cpp:
+ * jit/JITCall.cpp:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitNakedCall):
+ (JSC::JIT::emitCTICall_internal):
+ (JSC::JIT::checkStructure):
+ (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::JIT::addSlowCase):
+ (JSC::JIT::addJump):
+ (JSC::JIT::emitJumpSlowToHot):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+
+2008-12-12 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix the failures of the following layout tests, which regressed in
+ r39255:
+
+ fast/dom/StyleSheet/ownerNode-lifetime-2.html
+ fast/xsl/transform-xhr-doc.xhtml
+
+ The binary search in CodeBlock::getByIdExceptionInfoForBytecodeOffset()
+ doesn't guarantee that it actually finds a match, so add an explicit check
+ for this.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::getByIdExceptionInfoForBytecodeOffset):
+
+2008-12-12 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Replace emitPutCallArg methods with emitPutJITStubArg methods. Primarily to make the argument numbering
+ more sensible (1-based incrementing by 1, rather than 0-based incrementing by 4). The CTI name also seems
+ to be being deprecated from the code generally.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileBinaryArithOp):
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallSetupArgs):
+ (JSC::JIT::compileOpCallEvalSetupArgs):
+ (JSC::JIT::compileOpConstructSetupArgs):
+ (JSC::JIT::compileOpCall):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitPutJITStubArg):
+ (JSC::JIT::emitPutJITStubArgConstant):
+ (JSC::JIT::emitGetJITStubArg):
+ (JSC::JIT::emitPutJITStubArgFromVirtualRegister):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdSlowCase):
+
+2008-12-12 Gavin Barraclough <barraclough@apple.com>
+
+ Fix windows builds.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+
+2008-12-12 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Remove loop counter 'i' from the JIT generation passes, replace with a member m_bytecodeIndex.
+
+ No impact on performance.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emitSlowScriptCheck):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JSC::CallRecord::CallRecord):
+ (JSC::JmpTable::JmpTable):
+ (JSC::JIT::emitCTICall):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileBinaryArithOp):
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitGetVirtualRegister):
+ (JSC::JIT::emitGetVirtualRegisters):
+ (JSC::JIT::emitNakedCall):
+ (JSC::JIT::emitCTICall_internal):
+ (JSC::JIT::emitJumpSlowCaseIfJSCell):
+ (JSC::JIT::emitJumpSlowCaseIfNotJSCell):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmNum):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmNums):
+ (JSC::JIT::emitFastArithIntToImmOrSlowCase):
+ (JSC::JIT::addSlowCase):
+ (JSC::JIT::addJump):
+ (JSC::JIT::emitJumpSlowToHot):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::compilePutByIdSlowCase):
+
+2008-12-12 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Cameron Zwarich.
+
+ <rdar://problem/6428342> Look into feasibility of discarding bytecode after native codegen
+
+ Move more JIT functionality to using offsets into the Instruction buffer
+ instead of raw pointers. Two to go!
+
+ * interpreter/Interpreter.cpp:
+ (JSC::bytecodeOffsetForPC): Rename from vPCForPC.
+ (JSC::Interpreter::resolve): Pass offset to exception helper.
+ (JSC::Interpreter::resolveSkip): Ditto.
+ (JSC::Interpreter::resolveGlobal): Ditto.
+ (JSC::Interpreter::resolveBaseAndProperty): Ditto.
+ (JSC::Interpreter::resolveBaseAndFunc): Ditto.
+ (JSC::isNotObject): Ditto.
+ (JSC::Interpreter::unwindCallFrame): Call bytecodeOffsetForPC.
+ (JSC::Interpreter::throwException): Use offsets instead of vPCs.
+ (JSC::Interpreter::privateExecute): Pass offset to exception helper.
+ (JSC::Interpreter::retrieveLastCaller): Ditto.
+ (JSC::Interpreter::cti_op_instanceof): Ditto.
+ (JSC::Interpreter::cti_op_call_NotJSFunction): Ditto.
+ (JSC::Interpreter::cti_op_resolve): Pass offset to exception helper.
+ (JSC::Interpreter::cti_op_construct_NotJSConstruct): Ditto.
+ (JSC::Interpreter::cti_op_resolve_func): Ditto.
+ (JSC::Interpreter::cti_op_resolve_skip): Ditto.
+ (JSC::Interpreter::cti_op_resolve_global): Ditto.
+ (JSC::Interpreter::cti_op_resolve_with_base): Ditto.
+ (JSC::Interpreter::cti_op_throw): Ditto.
+ (JSC::Interpreter::cti_op_in): Ditto.
+ (JSC::Interpreter::cti_vm_throw): Ditto.
+ * interpreter/Interpreter.h:
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass): Don't pass unnecessary vPC to stub.
+ * jit/JIT.h: Remove ARG_instr1 - ARG_instr3 and ARG_instr5 - ARG_instr6.
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallEvalSetupArgs): Don't pass unnecessary vPC to stub..
+ (JSC::JIT::compileOpConstructSetupArgs): Ditto.
+
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createUndefinedVariableError): Take an offset instead of vPC.
+ (JSC::createInvalidParamError): Ditto.
+ (JSC::createNotAConstructorError): Ditto.
+ (JSC::createNotAFunctionError): Ditto.
+ (JSC::createNotAnObjectError): Ditto.
+ * runtime/ExceptionHelpers.h:
+
+2008-12-12 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 22835: Crash during bytecode generation when comparing to null
+ <https://bugs.webkit.org/show_bug.cgi?id=22835>
+ <rdar://problem/6286749>
+
+ Change the special cases in bytecode generation for comparison to null
+ to use tempDestination().
+
+ * parser/Nodes.cpp:
+ (JSC::BinaryOpNode::emitBytecode):
+ (JSC::EqualNode::emitBytecode):
+
+2008-12-12 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Move slow-cases of JIT code generation over to the MacroAssembler interface.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::Label::Label):
+ (JSC::MacroAssembler::jae32):
+ (JSC::MacroAssembler::jg32):
+ (JSC::MacroAssembler::jzPtr):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::emitGetVariableObjectRegister):
+ (JSC::JIT::emitPutVariableObjectRegister):
+ * jit/JIT.h:
+ (JSC::SlowCaseEntry::SlowCaseEntry):
+ (JSC::JIT::getSlowCase):
+ (JSC::JIT::linkSlowCase):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitJumpSlowCaseIfNotJSCell):
+ (JSC::JIT::linkSlowCaseIfNotJSCell):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdSlowCase):
+
+2008-12-12 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Bug 22828: Do not inspect bytecode instruction stream for op_get_by_id exception information
+ <https://bugs.webkit.org/show_bug.cgi?id=22828>
+
+ In order to remove the bytecode instruction stream after generating
+ native code, all inspection of bytecode instructions at runtime must
+ be removed. One particular instance of this is the special handling of
+ exceptions thrown by the op_get_by_id emitted directly before an
+ op_construct or an op_instanceof. This patch moves that information to
+ an auxiliary data structure in CodeBlock.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::getByIdExceptionInfoForBytecodeOffset):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::addGetByIdExceptionInfo):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitConstruct):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::emitGetByIdExceptionInfo):
+ * parser/Nodes.cpp:
+ (JSC::InstanceOfNode::emitBytecode):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createNotAnObjectError):
+
+2008-12-12 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Change exception information accessors to take offsets into the bytecode
+ instruction buffer instead of pointers so that they can work even even
+ if the bytecode buffer is purged.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::instructionOffsetForNth):
+ (JSC::CodeBlock::handlerForBytecodeOffset):
+ (JSC::CodeBlock::lineNumberForBytecodeOffset):
+ (JSC::CodeBlock::expressionRangeForBytecodeOffset):
+ * bytecode/CodeBlock.h:
+ * bytecode/SamplingTool.cpp:
+ (JSC::SamplingTool::dump):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::retrieveLastCaller):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createUndefinedVariableError):
+ (JSC::createInvalidParamError):
+ (JSC::createNotAConstructorError):
+ (JSC::createNotAFunctionError):
+ (JSC::createNotAnObjectError):
+
+2008-12-12 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Tiny bit of refactoring in quantifier generation.
+
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateNonGreedyQuantifier):
+ (JSC::WREC::Generator::generateGreedyQuantifier):
+
+2008-12-11 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Remove dependancy on having the Instruction buffer in order to
+ deref Structures used for property access and global resolves.
+ Instead, we put references to the necessary Structures in auxiliary
+ data structures on the CodeBlock. This is not an ideal solution,
+ as we still pay for having the Structures in two places and we
+ would like to eventually just hold on to offsets into the machine
+ code buffer.
+
+ - Also removes CodeBlock bloat in non-JIT by #ifdefing the JIT
+ only data structures.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * bytecode/CodeBlock.cpp:
+ (JSC::isGlobalResolve):
+ (JSC::isPropertyAccess):
+ (JSC::instructionOffsetForNth):
+ (JSC::printGlobalResolveInfo):
+ (JSC::printStructureStubInfo):
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::~CodeBlock):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::GlobalResolveInfo::GlobalResolveInfo):
+ (JSC::getNativePC):
+ (JSC::CodeBlock::instructions):
+ (JSC::CodeBlock::getStubInfo):
+ (JSC::CodeBlock::getBytecodeIndex):
+ (JSC::CodeBlock::addPropertyAccessInstruction):
+ (JSC::CodeBlock::addGlobalResolveInstruction):
+ (JSC::CodeBlock::numberOfStructureStubInfos):
+ (JSC::CodeBlock::addStructureStubInfo):
+ (JSC::CodeBlock::structureStubInfo):
+ (JSC::CodeBlock::addGlobalResolveInfo):
+ (JSC::CodeBlock::globalResolveInfo):
+ (JSC::CodeBlock::numberOfCallLinkInfos):
+ (JSC::CodeBlock::addCallLinkInfo):
+ (JSC::CodeBlock::callLinkInfo):
+ * bytecode/Instruction.h:
+ (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
+ (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
+ * bytecode/Opcode.h:
+ (JSC::):
+ * bytecode/StructureStubInfo.cpp: Copied from bytecode/CodeBlock.cpp.
+ (JSC::StructureStubInfo::deref):
+ * bytecode/StructureStubInfo.h: Copied from bytecode/CodeBlock.h.
+ (JSC::StructureStubInfo::StructureStubInfo):
+ (JSC::StructureStubInfo::initGetByIdSelf):
+ (JSC::StructureStubInfo::initGetByIdProto):
+ (JSC::StructureStubInfo::initGetByIdChain):
+ (JSC::StructureStubInfo::initGetByIdSelfList):
+ (JSC::StructureStubInfo::initGetByIdProtoList):
+ (JSC::StructureStubInfo::initPutByIdTransition):
+ (JSC::StructureStubInfo::initPutByIdReplace):
+ (JSC::StructureStubInfo::):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitGetById):
+ (JSC::BytecodeGenerator::emitPutById):
+ (JSC::BytecodeGenerator::emitCall):
+ (JSC::BytecodeGenerator::emitConstruct):
+ (JSC::BytecodeGenerator::emitCatch):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::tryCTICachePutByID):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::getPolymorphicAccessStructureListSlot):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list):
+ (JSC::Interpreter::cti_op_resolve_global):
+ * jit/JIT.cpp:
+ (JSC::JIT::JIT):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdSlowCase):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+
+2008-12-11 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Remove CTI_ARGUMENTS mode, use va_start implementation on Windows,
+ unifying JIT callback (cti_*) argument access on OS X & Windows
+
+ No performance impact.
+
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitCTICall):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+ * wtf/Platform.h:
+
+2008-12-11 Holger Freyther <zecke@selfish.org>
+
+ Reviewed by Simon Hausmann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=20953
+
+ For Qt it is not pratical to have a FontCache and GlyphPageTreeNode
+ implementation. This is one of the reasons why the Qt port is currently not
+ using WebCore/platform/graphics/Font.cpp. By allowing to not use
+ the simple/fast-path the Qt port will be able to use it.
+
+ Introduce USE(FONT_FAST_PATH) and define it for every port but the
+ Qt one.
+
+ * wtf/Platform.h: Enable USE(FONT_FAST_PATH)
+
+2008-12-11 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Darin Adler and landed by Holger Freyther.
+
+ <https://bugs.webkit.org/show_bug.cgi?id=22648>
+ Fix threading on Qt-port and Gtk-port for Sampling tool.
+
+ * wtf/ThreadingGtk.cpp:
+ (WTF::waitForThreadCompletion):
+ * wtf/ThreadingQt.cpp:
+ (WTF::waitForThreadCompletion):
+
+2008-12-10 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 22734: Debugger crashes when stepping into a function call in a return statement
+ <https://bugs.webkit.org/show_bug.cgi?id=22734>
+ <rdar://problem/6426796>
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator): The DebuggerCallFrame uses
+ the 'this' value stored in a callFrame, so op_convert_this should be
+ emitted at the beginning of a function body when generating bytecode
+ with debug hooks.
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::thisObject): The assertion inherent in the call
+ to asObject() here is valid, because any 'this' value should have been
+ converted to a JSObject*.
+
+2008-12-10 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Port more of the JIT to use the MacroAssembler interface.
+
+ Everything in the main pass, bar a few corner cases (operations with required
+ registers, or calling convention code). Slightly refactors array creation,
+ moving the offset calculation into the callFrame into C code (reducing code
+ planted).
+
+ Overall this appears to be a 1% win on v8-tests, due to the smaller immediates
+ being planted (in jfalse in particular).
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_op_new_array):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateEnter):
+
+2008-12-10 Sam Weinig <sam@webkit.org>
+
+ Fix non-JIT builds.
+
+ * bytecode/CodeBlock.h:
+
+2008-12-10 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ <rdar://problem/6428332> Remove the CTI return address table from CodeBlock
+
+ Step 2:
+
+ Convert the return address table from a HashMap to a sorted Vector. This
+ reduces the size of the data structure by ~4.5MB on Membuster head.
+
+ SunSpider reports a 0.5% progression.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::sizeInBytes): Generic method to get the cost of a Vector.
+ (JSC::CodeBlock::dumpStatistics): Add dumping of member sizes.
+ * bytecode/CodeBlock.h:
+ (JSC::PC::PC): Struct representing NativePC -> VirtualPC mappings.
+ (JSC::getNativePC): Helper for binary chop.
+ (JSC::CodeBlock::getBytecodeIndex): Used to get the VirtualPC from a
+ NativePC using a binary chop of the pcVector.
+ (JSC::CodeBlock::pcVector): Accessor.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::vPCForPC): Use getBytecodeIndex instead of jitReturnAddressVPCMap().get().
+ (JSC::Interpreter::cti_op_instanceof): Ditto.
+ (JSC::Interpreter::cti_op_resolve): Ditto.
+ (JSC::Interpreter::cti_op_resolve_func): Ditto.
+ (JSC::Interpreter::cti_op_resolve_skip): Ditto.
+ (JSC::Interpreter::cti_op_resolve_with_base): Ditto.
+ (JSC::Interpreter::cti_op_throw): Ditto.
+ (JSC::Interpreter::cti_op_in): Ditto.
+ (JSC::Interpreter::cti_vm_throw): Ditto.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile): Reserve exact capacity and fill the pcVector.
+
+2008-12-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Added WREC support for an assertion followed by a quantifier. Fixed
+ PCRE to match.
+
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::Parser::parseParentheses): Throw away the quantifier, since
+ it's meaningless. (Firefox does the same.)
+
+ * pcre/pcre_compile.cpp:
+ (compileBranch): ditto.
+
+2008-12-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ In preparation for compiling WREC without PCRE:
+
+ Further relaxed WREC's parsing to be more web-compatible. Fixed PCRE to
+ match in cases where it didn't already.
+
+ Changed JavaScriptCore to report syntax errors detected by WREC, rather
+ than falling back on PCRE any time WREC sees an error.
+
+ * pcre/pcre_compile.cpp:
+ (checkEscape): Relaxed parsing of \c and \N escapes to be more
+ web-compatible.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp): Only fall back on PCRE if WREC has not reported
+ a syntax error.
+
+ * wrec/WREC.cpp:
+ (JSC::WREC::Generator::compileRegExp): Fixed some error reporting to
+ match PCRE.
+
+ * wrec/WRECParser.cpp: Added error messages that match PCRE.
+
+ (JSC::WREC::Parser::consumeGreedyQuantifier):
+ (JSC::WREC::Parser::parseParentheses):
+ (JSC::WREC::Parser::parseCharacterClass):
+ (JSC::WREC::Parser::parseNonCharacterEscape): Updated the above functions to
+ use the new setError API.
+
+ (JSC::WREC::Parser::consumeEscape): Relaxed parsing of \c \N \u \x \B
+ to be more web-compatible.
+
+ (JSC::WREC::Parser::parseAlternative): Distinguish between a malformed
+ quantifier and a quantifier with no prefix, like PCRE does.
+
+ (JSC::WREC::Parser::consumeParenthesesType): Updated to use the new setError API.
+
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::error):
+ (JSC::WREC::Parser::syntaxError):
+ (JSC::WREC::Parser::parsePattern):
+ (JSC::WREC::Parser::reset):
+ (JSC::WREC::Parser::setError): Store error messages instead of error codes,
+ to provide for exception messages. Use a setter for reporting errors, so
+ errors detected early are not overwritten by errors detected later.
+
+2008-12-09 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Use va_args to access cti function arguments.
+ https://bugs.webkit.org/show_bug.cgi?id=22774
+
+ This may be a minor regression, but we'll take the hit if so to reduce fragility.
+
+ * interpreter/Interpreter.cpp:
+ * interpreter/Interpreter.h:
+
+2008-12-09 Sam Weinig <sam@webkit.org>
+
+ Reviewed twice by Cameron Zwarich.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=22752
+ Clear SymbolTable after codegen for Function codeblocks that
+ don't require an activation
+
+ This is a ~1.5MB improvement on Membuster-head.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpStatistics): Add logging of non-empty symbol tables
+ and total size used by symbol tables.
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate): Clear the symbol table here.
+
+2008-12-09 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Remove unnecessary extra lookup when throwing an exception.
+ We used to first lookup the target offset using getHandlerForVPC
+ and then we would lookup the native code stub using
+ nativeExceptionCodeForHandlerVPC. Instead, we can just pass around
+ the HandlerInfo.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::handlerForVPC): Return the HandlerInfo.
+ * bytecode/CodeBlock.h: Remove nativeExceptionCodeForHandlerVPC.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException): Return a HandlerInfo instead of
+ and Instruction offset.
+ (JSC::Interpreter::privateExecute): Get the offset from HandlerInfo.
+ (JSC::Interpreter::cti_op_throw): Get the native code from the HandleInfo.
+ (JSC::Interpreter::cti_vm_throw): Ditto.
+ * interpreter/Interpreter.h:
+
+2008-12-09 Eric Seidel <eric@webkit.org>
+
+ Build fix only, no review.
+
+ Speculative fix for the Chromium-Windows bot.
+ Add JavaScriptCore/os-win32 to the include path (for stdint.h)
+ Strangely it builds fine on my local windows box (or at least doesn't hit this error)
+
+ * JavaScriptCore.scons:
+
+2008-12-09 Eric Seidel <eric@webkit.org>
+
+ No review, build fix only.
+
+ Add ExecutableAllocator files missing from Scons build.
+
+ * JavaScriptCore.scons:
+
+2008-12-09 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Timothy Hatcher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22631
+ Allow ScriptCallFrame query names of functions in the call stack.
+
+ * JavaScriptCore.exp: added InternalFunction::name and
+ UString operator==() as exported symbol
+
+2008-12-08 Judit Jasz <jasy@inf.u-szeged.hu>
+
+ Reviewed and tweaked by Cameron Zwarich.
+
+ Bug 22352: Annotate opcodes with their length
+ <https://bugs.webkit.org/show_bug.cgi?id=22352>
+
+ * bytecode/Opcode.cpp:
+ * bytecode/Opcode.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+
+2008-12-08 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Implemented more of the relaxed and somewhat weird rules for deciding
+ how to interpret a non-pattern-character.
+
+ * wrec/Escapes.h:
+ (JSC::WREC::Escape::):
+ (JSC::WREC::Escape::Escape): Eliminated Escape::None because it was
+ unused. If you see an '\\', it's either a valid escape or an error.
+
+ * wrec/Quantifier.h:
+ (JSC::WREC::Quantifier::Quantifier):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateNonGreedyQuantifier):
+ (JSC::WREC::Generator::generateGreedyQuantifier): Renamed "noMaxSpecified"
+ to "Infinity", since that's what it means.
+
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::Parser::consumeGreedyQuantifier): Re-wrote {n,m} parsing rules
+ because they were too strict before. Added support for backtracking
+ in the case where the {n,m} fails to parse as a quantifier, and yet is
+ not a syntax error.
+
+ (JSC::WREC::Parser::parseCharacterClass):
+ (JSC::WREC::Parser::parseNonCharacterEscape): Eliminated Escape::None,
+ as above.
+
+ (JSC::WREC::Parser::consumeEscape): Don't treat ASCII and _ escapes
+ as syntax errors. See fast/regex/non-pattern-characters.html.
+
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::SavedState::SavedState):
+ (JSC::WREC::Parser::SavedState::restore): Added a state backtracker,
+ since parsing {n,m} forms requires backtracking if the form turns out
+ not to be a quantifier.
+
+2008-12-08 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Refactored WREC parsing so that only one piece of code needs to know
+ the relaxed and somewhat weird rules for deciding how to interpret a
+ non-pattern-character, in preparation for implementing those rules.
+
+ Also, implemented the relaxed and somewhat weird rules for '}' and ']'.
+
+ * wrec/WREC.cpp: Reduced the regular expression size limit. Now that
+ WREC handles ']' properly, it compiles fast/js/regexp-charclass-crash.html,
+ which makes it hang at the old limit. (The old limit was based on the
+ misimpression that the same value in PCRE limited the regular expression
+ pattern size; in reality, it limited the expected compiled regular
+ expression size. WREC doesn't have a way to calculate an expected
+ compiled regular expression size, but this should be good enough.)
+
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::parsePatternCharacterSequence): Nixed this function because
+ it contained a second copy of the logic for handling non-pattern-characters,
+ which is about to get a lot more complicated.
+
+ (JSC::WREC::PatternCharacterSequence::PatternCharacterSequence):
+ (JSC::WREC::PatternCharacterSequence::size):
+ (JSC::WREC::PatternCharacterSequence::append):
+ (JSC::WREC::PatternCharacterSequence::flush): Helper object for generating
+ an optimized sequence of pattern characters.
+
+ (JSC::WREC::Parser::parseNonCharacterEscape): Renamed to reflect the fact
+ that the main parseAlternative loop handles character escapes.
+
+ (JSC::WREC::Parser::parseAlternative): Moved pattern character sequence
+ logic from parsePatternCharacterSequence to here, using
+ PatternCharacterSequence to help with the details.
+
+ * wrec/WRECParser.h: Updated for renames.
+
+2008-12-08 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Geoff Garen.
+
+ <rdar://problem/6166088> Give JSGlobalContextCreate a behavior that is concurrency aware,
+ and un-deprecate it
+
+ * API/JSContextRef.cpp: (JSGlobalContextCreate):
+ * API/JSContextRef.h:
+ Use a unique context group for the context, unless the application was linked against old
+ JavaScriptCore.
+
+2008-12-08 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Cameron Zwarich.
+
+ Fix for <rdar://problem/6428332> Remove the CTI return address table from CodeBlock
+
+ Step 1:
+
+ Remove use of jitReturnAddressVPCMap when looking for vPC to store Structures
+ in for cached lookup. Instead, use the offset in the StructureStubInfo that is
+ already required.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpStatistics): Fix extraneous semicolon.
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::tryCTICachePutByID):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list):
+ * jit/JIT.h:
+ (JSC::JIT::compileGetByIdSelf):
+ (JSC::JIT::compileGetByIdProto):
+ (JSC::JIT::compileGetByIdChain):
+ (JSC::JIT::compilePutByIdReplace):
+ (JSC::JIT::compilePutByIdTransition):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::patchGetByIdSelf):
+ (JSC::JIT::patchPutByIdReplace):
+ (JSC::JIT::privateCompilePatchGetArrayLength): Remove extra call to getStubInfo.
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+
+2008-12-08 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Port the op_j?n?eq_null JIT code generation to use the MacroAssembler,
+ and clean up slightly at the same time. The 'j' forms currently compare,
+ then set a register, then compare again, then branch. Branch directly on
+ the result of the first compare.
+
+ Around a 1% progression on deltablue, crypto & early boyer, for about 1/2%
+ overall on v8-tests.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdSlowCase):
+
+2008-12-08 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Expand MacroAssembler to support more operations, required by the JIT.
+
+ Generally adds more operations and permutations of operands to the existing
+ interface. Rename 'jset' to 'jnz' and 'jnset' to 'jz', which seem clearer,
+ and require that immediate pointer operands (though not pointer addresses to
+ load and store instructions) are wrapped in a ImmPtr() type, akin to Imm32().
+
+ No performance impact.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::):
+ (JSC::MacroAssembler::ImmPtr::ImmPtr):
+ (JSC::MacroAssembler::add32):
+ (JSC::MacroAssembler::and32):
+ (JSC::MacroAssembler::or32):
+ (JSC::MacroAssembler::sub32):
+ (JSC::MacroAssembler::xor32):
+ (JSC::MacroAssembler::loadPtr):
+ (JSC::MacroAssembler::load32):
+ (JSC::MacroAssembler::storePtr):
+ (JSC::MacroAssembler::store32):
+ (JSC::MacroAssembler::poke):
+ (JSC::MacroAssembler::move):
+ (JSC::MacroAssembler::testImm32):
+ (JSC::MacroAssembler::jae32):
+ (JSC::MacroAssembler::jb32):
+ (JSC::MacroAssembler::jePtr):
+ (JSC::MacroAssembler::je32):
+ (JSC::MacroAssembler::jnePtr):
+ (JSC::MacroAssembler::jne32):
+ (JSC::MacroAssembler::jnzPtr):
+ (JSC::MacroAssembler::jnz32):
+ (JSC::MacroAssembler::jzPtr):
+ (JSC::MacroAssembler::jz32):
+ (JSC::MacroAssembler::joSub32):
+ (JSC::MacroAssembler::jump):
+ (JSC::MacroAssembler::sete32):
+ (JSC::MacroAssembler::setne32):
+ (JSC::MacroAssembler::setnz32):
+ (JSC::MacroAssembler::setz32):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::addl_mr):
+ (JSC::X86Assembler::andl_i8r):
+ (JSC::X86Assembler::cmpl_rm):
+ (JSC::X86Assembler::cmpl_mr):
+ (JSC::X86Assembler::cmpl_i8m):
+ (JSC::X86Assembler::subl_mr):
+ (JSC::X86Assembler::testl_i32m):
+ (JSC::X86Assembler::xorl_i32r):
+ (JSC::X86Assembler::movl_rm):
+ (JSC::X86Assembler::modRm_opmsib):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitGetVirtualRegister):
+ (JSC::JIT::emitPutCTIArgConstant):
+ (JSC::JIT::emitPutCTIParam):
+ (JSC::JIT::emitPutImmediateToCallFrameHeader):
+ (JSC::JIT::emitInitRegister):
+ (JSC::JIT::checkStructure):
+ (JSC::JIT::emitJumpIfJSCell):
+ (JSC::JIT::emitJumpIfNotJSCell):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmNum):
+
+2008-12-08 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixed a bug where WREC would allow a quantifier whose minimum was
+ greater than its maximum.
+
+ * wrec/Quantifier.h:
+ (JSC::WREC::Quantifier::Quantifier): ASSERT that the quantifier is not
+ backwards.
+
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::Parser::consumeGreedyQuantifier): Verify that the minimum
+ is not greater than the maximum.
+
+2008-12-08 Eric Seidel <eric@webkit.org>
+
+ Build fix only, no review.
+
+ * JavaScriptCore.scons: add bytecode/JumpTable.cpp
+
+2008-12-08 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Patch for https://bugs.webkit.org/show_bug.cgi?id=22716
+ <rdar://problem/6428315>
+ Add RareData structure to CodeBlock for infrequently used auxiliary data
+ members.
+
+ Reduces memory on Membuster-head by ~.5MB
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::dumpStatistics):
+ (JSC::CodeBlock::mark):
+ (JSC::CodeBlock::getHandlerForVPC):
+ (JSC::CodeBlock::nativeExceptionCodeForHandlerVPC):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::numberOfExceptionHandlers):
+ (JSC::CodeBlock::addExceptionHandler):
+ (JSC::CodeBlock::exceptionHandler):
+ (JSC::CodeBlock::addFunction):
+ (JSC::CodeBlock::function):
+ (JSC::CodeBlock::addUnexpectedConstant):
+ (JSC::CodeBlock::unexpectedConstant):
+ (JSC::CodeBlock::addRegExp):
+ (JSC::CodeBlock::regexp):
+ (JSC::CodeBlock::numberOfImmediateSwitchJumpTables):
+ (JSC::CodeBlock::addImmediateSwitchJumpTable):
+ (JSC::CodeBlock::immediateSwitchJumpTable):
+ (JSC::CodeBlock::numberOfCharacterSwitchJumpTables):
+ (JSC::CodeBlock::addCharacterSwitchJumpTable):
+ (JSC::CodeBlock::characterSwitchJumpTable):
+ (JSC::CodeBlock::numberOfStringSwitchJumpTables):
+ (JSC::CodeBlock::addStringSwitchJumpTable):
+ (JSC::CodeBlock::stringSwitchJumpTable):
+ (JSC::CodeBlock::evalCodeCache):
+ (JSC::CodeBlock::createRareDataIfNecessary):
+
+2008-11-26 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Anders Carlsson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=16814
+ Allow ports to disable ActiveX->NPAPI conversion for Media Player.
+ Improve handling of miscellaneous ActiveX objects.
+
+ * wtf/Platform.h: Add another ENABLE(...).
+
+2008-12-08 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ Add dumping of CodeBlock member structure usage.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpStatistics):
+ * bytecode/EvalCodeCache.h:
+ (JSC::EvalCodeCache::isEmpty):
+
+2008-12-08 David Kilzer <ddkilzer@apple.com>
+
+ Bug 22555: Sort "children" sections in Xcode project files
+
+ <https://bugs.webkit.org/show_bug.cgi?id=22555>
+
+ Reviewed by Eric Seidel.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Sorted.
+
+2008-12-08 Tony Chang <tony@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Enable Pan scrolling only when building on PLATFORM(WIN_OS)
+ Previously platforms like Apple Windows WebKit, Cairo Windows WebKit,
+ Wx and Chromium were enabling it explicitly, now we just turn it on
+ for all WIN_OS, later platforms can turn it off as needed on Windows
+ (or turn it on under Linux, etc.)
+ https://bugs.webkit.org/show_bug.cgi?id=22698
+
+ * wtf/Platform.h:
+
+2008-12-08 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Cameron Zwarich.
+
+ Add basic memory statistics dumping for CodeBlock.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpStatistics):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::~CodeBlock):
+ * bytecode/CodeBlock.h:
+
+2008-12-08 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Fix the Linux build with newer gcc/glibc.
+
+ * jit/ExecutableAllocatorPosix.cpp: Include unistd.h for
+ getpagesize(), according to
+ http://opengroup.org/onlinepubs/007908775/xsh/getpagesize.html
+
+2008-12-08 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Fix the build with Qt on Windows.
+
+ * JavaScriptCore.pri: Compile ExecutableAllocatorWin.cpp on Windows.
+
+2008-12-07 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Buildfix).
+
+ Fix non-WREC builds
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+
+2008-12-07 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Put ENABLE(ASSEMBLER) guards around use of ExecutableAllocator in global data
+
+ Correct Qt and Gtk project files
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * runtime/JSGlobalData.h:
+
+2008-12-07 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Add new files to other projects.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.pro:
+
+2008-12-07 Oliver Hunt <oliver@apple.com>
+
+ Rubber stamped by Mark Rowe.
+
+ Rename ExecutableAllocatorMMAP to the more sensible ExecutableAllocatorPosix
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * jit/ExecutableAllocator.h:
+ * jit/ExecutableAllocatorPosix.cpp: Renamed from JavaScriptCore/jit/ExecutableAllocatorMMAP.cpp.
+ (JSC::ExecutableAllocator::intializePageSize):
+ (JSC::ExecutablePool::systemAlloc):
+ (JSC::ExecutablePool::systemRelease):
+
+2008-12-07 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Cameron Zwarich and Sam Weinig
+
+ <rdar://problem/6309878> Need more granular control over allocation of executable memory (21783)
+ <https://bugs.webkit.org/show_bug.cgi?id=21783>
+
+ Add a new allocator for use by the JIT that provides executable pages, so
+ we can get rid of the current hack that makes the entire heap executable.
+
+ 1-2% progression on SunSpider-v8, 1% on SunSpider. Reduces memory usage as well!
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/AssemblerBuffer.h:
+ (JSC::AssemblerBuffer::size):
+ (JSC::AssemblerBuffer::executableCopy):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::size):
+ (JSC::MacroAssembler::copyCode):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::size):
+ (JSC::X86Assembler::executableCopy):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::~CodeBlock):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::executablePool):
+ (JSC::CodeBlock::setExecutablePool):
+ * bytecode/Instruction.h:
+ (JSC::PolymorphicAccessStructureList::derefStructures):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::~Interpreter):
+ * interpreter/Interpreter.h:
+ * jit/ExecutableAllocator.cpp: Added.
+ * jit/ExecutableAllocator.h: Added.
+ (JSC::ExecutablePool::create):
+ (JSC::ExecutablePool::alloc):
+ (JSC::ExecutablePool::~ExecutablePool):
+ (JSC::ExecutablePool::available):
+ (JSC::ExecutablePool::ExecutablePool):
+ (JSC::ExecutablePool::poolAllocate):
+ (JSC::ExecutableAllocator::ExecutableAllocator):
+ (JSC::ExecutableAllocator::poolForSize):
+ (JSC::ExecutablePool::sizeForAllocation):
+ * jit/ExecutableAllocatorMMAP.cpp: Added.
+ (JSC::ExecutableAllocator::intializePageSize):
+ (JSC::ExecutablePool::systemAlloc):
+ (JSC::ExecutablePool::systemRelease):
+ * jit/ExecutableAllocatorWin.cpp: Added.
+ (JSC::ExecutableAllocator::intializePageSize):
+ (JSC::ExecutablePool::systemAlloc):
+ (JSC::ExecutablePool::systemRelease):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ (JSC::JIT::compileCTIMachineTrampolines):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+ * parser/Nodes.cpp:
+ (JSC::RegExpNode::emitBytecode):
+ * runtime/JSGlobalData.h:
+ (JSC::JSGlobalData::poolForSize):
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ (JSC::RegExp::create):
+ (JSC::RegExp::~RegExp):
+ * runtime/RegExp.h:
+ * runtime/RegExpConstructor.cpp:
+ (JSC::constructRegExp):
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncCompile):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncMatch):
+ (JSC::stringProtoFuncSearch):
+ * wrec/WREC.cpp:
+ (JSC::WREC::Generator::compileRegExp):
+ * wrec/WRECGenerator.h:
+ * wtf/FastMalloc.cpp:
+ * wtf/FastMalloc.h:
+ * wtf/TCSystemAlloc.cpp:
+ (TryMmap):
+ (TryVirtualAlloc):
+ (TryDevMem):
+ (TCMalloc_SystemRelease):
+
+2008-12-06 Sam Weinig <sam@webkit.org>
+
+ Fix the Gtk build.
+
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compilePutByIdHotPath):
+
+2008-12-06 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Cameron Zwarich,
+
+ Move CodeBlock constructor into the .cpp file.
+
+ Sunspider reports a .7% progression, but I can only assume this
+ is noise.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+
+2008-12-06 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Cameron Zwarich.
+
+ Split JumpTable code into its own file.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * bytecode/CodeBlock.cpp:
+ * bytecode/CodeBlock.h:
+ * bytecode/JumpTable.cpp: Copied from bytecode/CodeBlock.cpp.
+ * bytecode/JumpTable.h: Copied from bytecode/CodeBlock.h.
+
+2008-12-05 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Cameron Zwarich.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=22715
+ Encapsulate more CodeBlock members in preparation
+ of moving some of them to a rare data structure.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::locationForOffset):
+ (JSC::printConditionalJump):
+ (JSC::printGetByIdOp):
+ (JSC::printPutByIdOp):
+ (JSC::CodeBlock::printStructure):
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::~CodeBlock):
+ (JSC::CodeBlock::unlinkCallers):
+ (JSC::CodeBlock::derefStructures):
+ (JSC::CodeBlock::refStructures):
+ (JSC::CodeBlock::mark):
+ (JSC::CodeBlock::getHandlerForVPC):
+ (JSC::CodeBlock::nativeExceptionCodeForHandlerVPC):
+ (JSC::CodeBlock::lineNumberForVPC):
+ (JSC::CodeBlock::expressionRangeForVPC):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::addCaller):
+ (JSC::CodeBlock::removeCaller):
+ (JSC::CodeBlock::isKnownNotImmediate):
+ (JSC::CodeBlock::isConstantRegisterIndex):
+ (JSC::CodeBlock::getConstant):
+ (JSC::CodeBlock::isTemporaryRegisterIndex):
+ (JSC::CodeBlock::getStubInfo):
+ (JSC::CodeBlock::getCallLinkInfo):
+ (JSC::CodeBlock::instructions):
+ (JSC::CodeBlock::setJITCode):
+ (JSC::CodeBlock::jitCode):
+ (JSC::CodeBlock::ownerNode):
+ (JSC::CodeBlock::setGlobalData):
+ (JSC::CodeBlock::setThisRegister):
+ (JSC::CodeBlock::thisRegister):
+ (JSC::CodeBlock::setNeedsFullScopeChain):
+ (JSC::CodeBlock::needsFullScopeChain):
+ (JSC::CodeBlock::setUsesEval):
+ (JSC::CodeBlock::usesEval):
+ (JSC::CodeBlock::setUsesArguments):
+ (JSC::CodeBlock::usesArguments):
+ (JSC::CodeBlock::codeType):
+ (JSC::CodeBlock::source):
+ (JSC::CodeBlock::sourceOffset):
+ (JSC::CodeBlock::addGlobalResolveInstruction):
+ (JSC::CodeBlock::numberOfPropertyAccessInstructions):
+ (JSC::CodeBlock::addPropertyAccessInstruction):
+ (JSC::CodeBlock::propertyAccessInstruction):
+ (JSC::CodeBlock::numberOfCallLinkInfos):
+ (JSC::CodeBlock::addCallLinkInfo):
+ (JSC::CodeBlock::callLinkInfo):
+ (JSC::CodeBlock::numberOfJumpTargets):
+ (JSC::CodeBlock::addJumpTarget):
+ (JSC::CodeBlock::jumpTarget):
+ (JSC::CodeBlock::lastJumpTarget):
+ (JSC::CodeBlock::numberOfExceptionHandlers):
+ (JSC::CodeBlock::addExceptionHandler):
+ (JSC::CodeBlock::exceptionHandler):
+ (JSC::CodeBlock::addExpressionInfo):
+ (JSC::CodeBlock::numberOfLineInfos):
+ (JSC::CodeBlock::addLineInfo):
+ (JSC::CodeBlock::lastLineInfo):
+ (JSC::CodeBlock::jitReturnAddressVPCMap):
+ (JSC::CodeBlock::numberOfIdentifiers):
+ (JSC::CodeBlock::addIdentifier):
+ (JSC::CodeBlock::identifier):
+ (JSC::CodeBlock::numberOfConstantRegisters):
+ (JSC::CodeBlock::addConstantRegister):
+ (JSC::CodeBlock::constantRegister):
+ (JSC::CodeBlock::addFunction):
+ (JSC::CodeBlock::function):
+ (JSC::CodeBlock::addFunctionExpression):
+ (JSC::CodeBlock::functionExpression):
+ (JSC::CodeBlock::addUnexpectedConstant):
+ (JSC::CodeBlock::unexpectedConstant):
+ (JSC::CodeBlock::addRegExp):
+ (JSC::CodeBlock::regexp):
+ (JSC::CodeBlock::symbolTable):
+ (JSC::CodeBlock::evalCodeCache):
+ New inline setters/getters.
+
+ (JSC::ProgramCodeBlock::ProgramCodeBlock):
+ (JSC::ProgramCodeBlock::~ProgramCodeBlock):
+ (JSC::ProgramCodeBlock::clearGlobalObject):
+ * bytecode/SamplingTool.cpp:
+ (JSC::ScopeSampleRecord::sample):
+ (JSC::SamplingTool::dump):
+ * bytecompiler/BytecodeGenerator.cpp:
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/Label.h:
+ * interpreter/CallFrame.cpp:
+ * interpreter/Interpreter.cpp:
+ * jit/JIT.cpp:
+ * jit/JITCall.cpp:
+ * jit/JITInlineMethods.h:
+ * jit/JITPropertyAccess.cpp:
+ * parser/Nodes.cpp:
+ * runtime/Arguments.h:
+ * runtime/ExceptionHelpers.cpp:
+ * runtime/JSActivation.cpp:
+ * runtime/JSActivation.h:
+ * runtime/JSGlobalObject.cpp:
+ Change direct access to use new getter/setters.
+
+2008-12-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Prevent GCC4.2 from hanging when trying to compile Interpreter.cpp.
+ Added "-fno-var-tracking" compiler flag.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22704
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2008-12-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Ordering of branch operands in MacroAssembler in unnecessarily inconsistent.
+
+ je, jg etc take an immediate operand as the second argument, but for the
+ equality branches (je, jne) the immediate operand was the first argument. This
+ was unnecessarily inconsistent. Change je, jne methods to take the immediate
+ as the second argument.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22703
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::je32):
+ (JSC::MacroAssembler::jne32):
+ * jit/JIT.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateEnter):
+ (JSC::WREC::Generator::generateNonGreedyQuantifier):
+ (JSC::WREC::Generator::generateGreedyQuantifier):
+ (JSC::WREC::Generator::generatePatternCharacterPair):
+ (JSC::WREC::Generator::generatePatternCharacter):
+ (JSC::WREC::Generator::generateCharacterClassInvertedRange):
+ (JSC::WREC::Generator::generateCharacterClassInverted):
+ (JSC::WREC::Generator::generateAssertionBOL):
+ (JSC::WREC::Generator::generateAssertionWordBoundary):
+
+2008-12-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Second tranche of porting JIT.cpp to MacroAssembler interface.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::mul32):
+ (JSC::MacroAssembler::jl32):
+ (JSC::MacroAssembler::jnzSub32):
+ (JSC::MacroAssembler::joAdd32):
+ (JSC::MacroAssembler::joMul32):
+ (JSC::MacroAssembler::jzSub32):
+ * jit/JIT.cpp:
+ (JSC::JIT::emitSlowScriptCheck):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitJumpIfNotJSCell):
+ (JSC::JIT::emitJumpSlowCaseIfNotJSCell):
+
+2008-12-05 David Kilzer <ddkilzer@apple.com>
+
+ Bug 22609: Provide a build-time choice when generating hash tables for properties of built-in DOM objects
+
+ <https://bugs.webkit.org/show_bug.cgi?id=22609>
+ <rdar://problem/6331749>
+
+ Reviewed by Darin Adler.
+
+ Initial patch by Yosen Lin. Adapted for ToT WebKit by David Kilzer.
+
+ Added back the code that generates a "compact" hash (instead of a
+ perfect hash) as a build-time option using the
+ ENABLE(PERFECT_HASH_SIZE) macro as defined in Lookup.h.
+
+ * create_hash_table: Rename variables to differentiate perfect hash
+ values from compact hash values. Added back code to compute compact
+ hash tables. Generate both hash table sizes and emit
+ conditionalized code based on ENABLE(PERFECT_HASH_SIZE).
+ * runtime/Lookup.cpp:
+ (JSC::HashTable::createTable): Added version of createTable() for
+ use with compact hash tables.
+ (JSC::HashTable::deleteTable): Updated to work with compact hash
+ tables.
+ * runtime/Lookup.h: Defined ENABLE(PERFECT_HASH_SIZE) macro here.
+ (JSC::HashEntry::initialize): Set m_next to zero when using compact
+ hash tables.
+ (JSC::HashEntry::setNext): Added for compact hash tables.
+ (JSC::HashEntry::next): Added for compact hash tables.
+ (JSC::HashTable::entry): Added version of entry() for use with
+ compact hash tables.
+ * runtime/Structure.cpp:
+ (JSC::Structure::getEnumerablePropertyNames): Updated to work with
+ compact hash tables.
+
+2008-12-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Remove redundant calls to JIT::emitSlowScriptCheck.
+ This is checked in the hot path, so is not needed on the slow path - and the code
+ was being planted before the start of the slow case, so was completely unreachable!
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileSlowCases):
+
+2008-12-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Move JIT::compileOpStrictEq to MacroAssembler interface.
+
+ The rewrite also looks like a small (<1%) performance progression.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22697
+
+ * jit/JIT.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitJumpIfJSCell):
+ (JSC::JIT::emitJumpSlowCaseIfJSCell):
+
+2008-12-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Remove m_assembler from MacroAssembler::Jump.
+ Keeping a pointer allowed for some syntactic sugar - "link()" looks nicer
+ than "link(this)". But maintaining this doubles the size of Jump, which
+ is even more unfortunate for the JIT, since there are many large structures
+ holding JmpSrcs. Probably best to remove it.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22693
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::Jump::Jump):
+ (JSC::MacroAssembler::Jump::link):
+ (JSC::MacroAssembler::Jump::linkTo):
+ (JSC::MacroAssembler::JumpList::link):
+ (JSC::MacroAssembler::JumpList::linkTo):
+ (JSC::MacroAssembler::jae32):
+ (JSC::MacroAssembler::je32):
+ (JSC::MacroAssembler::je16):
+ (JSC::MacroAssembler::jg32):
+ (JSC::MacroAssembler::jge32):
+ (JSC::MacroAssembler::jl32):
+ (JSC::MacroAssembler::jle32):
+ (JSC::MacroAssembler::jnePtr):
+ (JSC::MacroAssembler::jne32):
+ (JSC::MacroAssembler::jnset32):
+ (JSC::MacroAssembler::jset32):
+ (JSC::MacroAssembler::jump):
+ (JSC::MacroAssembler::jzSub32):
+ (JSC::MacroAssembler::joAdd32):
+ (JSC::MacroAssembler::call):
+ * wrec/WREC.cpp:
+ (JSC::WREC::Generator::compileRegExp):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateEnter):
+ (JSC::WREC::Generator::generateBackreferenceQuantifier):
+ (JSC::WREC::Generator::generateNonGreedyQuantifier):
+ (JSC::WREC::Generator::generateGreedyQuantifier):
+ (JSC::WREC::Generator::generatePatternCharacter):
+ (JSC::WREC::Generator::generateCharacterClassInvertedRange):
+ (JSC::WREC::Generator::generateCharacterClassInverted):
+ (JSC::WREC::Generator::generateCharacterClass):
+ (JSC::WREC::Generator::generateParenthesesAssertion):
+ (JSC::WREC::Generator::generateParenthesesInvertedAssertion):
+ (JSC::WREC::Generator::generateParenthesesNonGreedy):
+ (JSC::WREC::Generator::generateParenthesesResetTrampoline):
+ (JSC::WREC::Generator::generateAssertionBOL):
+ (JSC::WREC::Generator::generateAssertionEOL):
+ (JSC::WREC::Generator::generateAssertionWordBoundary):
+ (JSC::WREC::Generator::generateBackreference):
+ (JSC::WREC::Generator::terminateAlternative):
+ (JSC::WREC::Generator::terminateDisjunction):
+ * wrec/WRECParser.h:
+
+2008-12-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Simplify JIT generated checks for timeout code, by moving more work into the C function.
+ https://bugs.webkit.org/show_bug.cgi?id=22688
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_timeout_check):
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::emitSlowScriptCheck):
+
+2008-12-05 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Encapsulate access to jump tables in the CodeBlock in preparation
+ of moving them to a rare data structure.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::numberOfImmediateSwitchJumpTables):
+ (JSC::CodeBlock::addImmediateSwitchJumpTable):
+ (JSC::CodeBlock::immediateSwitchJumpTable):
+ (JSC::CodeBlock::numberOfCharacterSwitchJumpTables):
+ (JSC::CodeBlock::addCharacterSwitchJumpTable):
+ (JSC::CodeBlock::characterSwitchJumpTable):
+ (JSC::CodeBlock::numberOfStringSwitchJumpTables):
+ (JSC::CodeBlock::addStringSwitchJumpTable):
+ (JSC::CodeBlock::stringSwitchJumpTable):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ (JSC::BytecodeGenerator::endSwitch):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::cti_op_switch_imm):
+ (JSC::Interpreter::cti_op_switch_char):
+ (JSC::Interpreter::cti_op_switch_string):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+
+2008-12-05 Adam Roben <aroben@apple.com>
+
+ Windows build fix after r39020
+
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::restoreArgumentReference):
+ (JSC::JIT::restoreArgumentReferenceForTrampoline):
+ Add some apparently-missing __.
+
+2008-12-04 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22673
+
+ Added support for the assertion (?=) and inverted assertion (?!) atoms
+ in WREC.
+
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateParenthesesAssertion):
+ (JSC::WREC::Generator::generateParenthesesInvertedAssertion): Split the
+ old (unused) generateParentheses into these two functions, with more
+ limited capabilities.
+
+ * wrec/WRECGenerator.h:
+ (JSC::WREC::Generator::): Moved an enum to the top of the class definition,
+ to match the WebKit style, and removed a defunct comment.
+
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::Parser::parseParentheses):
+ (JSC::WREC::Parser::consumeParenthesesType):
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::): Added support for parsing (?=) and (?!).
+
+2008-12-05 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Rubber-stamped by Tor Arne Vestbø.
+
+ Disable the JIT for the Qt build alltogether again, after observing
+ more miscompilations in a wider range of newer gcc versions.
+
+ * JavaScriptCore.pri:
+
+2008-12-05 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Disable the JIT for the Qt build on Linux unless gcc is >= 4.2,
+ due to miscompilations.
+
+ * JavaScriptCore.pri:
+
+2008-12-04 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Start porting the JIT to use the MacroAssembler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22671
+ No change in performance.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::Jump::operator X86Assembler::JmpSrc):
+ (JSC::MacroAssembler::add32):
+ (JSC::MacroAssembler::and32):
+ (JSC::MacroAssembler::lshift32):
+ (JSC::MacroAssembler::rshift32):
+ (JSC::MacroAssembler::storePtr):
+ (JSC::MacroAssembler::store32):
+ (JSC::MacroAssembler::poke):
+ (JSC::MacroAssembler::move):
+ (JSC::MacroAssembler::compareImm32ForBranchEquality):
+ (JSC::MacroAssembler::jnePtr):
+ (JSC::MacroAssembler::jnset32):
+ (JSC::MacroAssembler::jset32):
+ (JSC::MacroAssembler::jzeroSub32):
+ (JSC::MacroAssembler::joverAdd32):
+ (JSC::MacroAssembler::call):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::shll_i8r):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileBinaryArithOp):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitGetVirtualRegister):
+ (JSC::JIT::emitPutCTIArg):
+ (JSC::JIT::emitPutCTIArgConstant):
+ (JSC::JIT::emitGetCTIArg):
+ (JSC::JIT::emitPutCTIArgFromVirtualRegister):
+ (JSC::JIT::emitPutCTIParam):
+ (JSC::JIT::emitGetCTIParam):
+ (JSC::JIT::emitPutToCallFrameHeader):
+ (JSC::JIT::emitPutImmediateToCallFrameHeader):
+ (JSC::JIT::emitGetFromCallFrameHeader):
+ (JSC::JIT::emitPutVirtualRegister):
+ (JSC::JIT::emitInitRegister):
+ (JSC::JIT::emitNakedCall):
+ (JSC::JIT::restoreArgumentReference):
+ (JSC::JIT::restoreArgumentReferenceForTrampoline):
+ (JSC::JIT::emitCTICall):
+ (JSC::JIT::checkStructure):
+ (JSC::JIT::emitJumpSlowCaseIfNotJSCell):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmNum):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmNums):
+ (JSC::JIT::emitFastArithDeTagImmediate):
+ (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::JIT::emitFastArithReTagImmediate):
+ (JSC::JIT::emitFastArithPotentiallyReTagImmediate):
+ (JSC::JIT::emitFastArithImmToInt):
+ (JSC::JIT::emitFastArithIntToImmOrSlowCase):
+ (JSC::JIT::emitFastArithIntToImmNoCheck):
+ (JSC::JIT::emitTagAsBoolImmediate):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+
+2008-12-04 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Some refactoring for generateGreedyQuantifier.
+
+ SunSpider reports no change (possibly a 0.3% speedup).
+
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateGreedyQuantifier): Clarified label
+ meanings and unified some logic to simplify things.
+
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::parseAlternative): Added a version of parseAlternative
+ that can jump to a Label, instead of a JumpList, upon failure. (Eventually,
+ when we have a true Label class, this will be redundant.) This makes
+ things easier for generateGreedyQuantifier, because it can avoid
+ explicitly linking things.
+
+2008-12-04 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Holger Freyther.
+
+ Fix crashes in the Qt build on Linux/i386 with non-executable memory
+ by enabling TCSystemAlloc and the PROT_EXEC flag for mmap.
+
+ * JavaScriptCore.pri: Enable the use of TCSystemAlloc if the JIT is
+ enabled.
+ * wtf/TCSystemAlloc.cpp: Extend the PROT_EXEC permissions to
+ PLATFORM(QT).
+
+2008-12-04 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Enable ENABLE_JIT_OPTIMIZE_CALL, ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS
+ and ENABLE_JIT_OPTIMIZE_ARITHMETIC, as suggested by Niko.
+
+ * JavaScriptCore.pri:
+
+2008-12-04 Kent Hansen <khansen@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ Enable the JSC jit for the Qt build by default for release builds on
+ linux-g++ and win32-msvc.
+
+ * JavaScriptCore.pri:
+
+2008-12-04 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Allow JIT to function without property access repatching and arithmetic optimizations.
+ Controlled by ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS and ENABLE_JIT_OPTIMIZE_ARITHMETIC switches.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22643
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp: Copied from jit/JIT.cpp.
+ (JSC::JIT::compileBinaryArithOp):
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ * jit/JITPropertyAccess.cpp: Copied from jit/JIT.cpp.
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::compilePutByIdSlowCase):
+ (JSC::resizePropertyStorage):
+ (JSC::transitionWillNeedStorageRealloc):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::patchGetByIdSelf):
+ (JSC::JIT::patchPutByIdReplace):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * wtf/Platform.h:
+
+2008-12-03 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Optimized sequences of characters in regular expressions by comparing
+ two characters at a time.
+
+ 1-2% speedup on SunSpider, 19-25% speedup on regexp-dna.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::load32):
+ (JSC::MacroAssembler::jge32): Filled out a few more macro methods.
+
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::movl_mr): Added a verion of movl_mr that operates
+ without an offset, to allow the macro assembler to optmize for that case.
+
+ * wrec/WREC.cpp:
+ (JSC::WREC::Generator::compileRegExp): Test the saved value of index
+ instead of the index register when checking for "end of input." The
+ index register doesn't increment by 1 in an orderly fashion, so testing
+ it for == "end of input" is not valid.
+
+ Also, jump all the way to "return failure" upon reaching "end of input,"
+ instead of executing the next alternative. This is more logical, and
+ it's a slight optimization in the case of an expression with many alternatives.
+
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateIncrementIndex): Added support for
+ jumping to a failure label in the case where the index has reached "end
+ of input."
+
+ (JSC::WREC::Generator::generatePatternCharacterSequence):
+ (JSC::WREC::Generator::generatePatternCharacterPair): This is the
+ optmization. It's basically like generatePatternCharacter, but it runs two
+ characters at a time.
+
+ (JSC::WREC::Generator::generatePatternCharacter): Changed to use isASCII,
+ since it's clearer than comparing to a magic hex value.
+
+ * wrec/WRECGenerator.h:
+
+2008-12-03 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Allow JIT to operate without the call-repatching optimization.
+ Controlled by ENABLE(JIT_OPTIMIZE_CALL), defaults on, disabling
+ this leads to significant performance regression.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22639
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITCall.cpp: Copied from jit/JIT.cpp.
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCallSetupArgs):
+ (JSC::JIT::compileOpCallEvalSetupArgs):
+ (JSC::JIT::compileOpConstructSetupArgs):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ (JSC::unreachable):
+ * jit/JITInlineMethods.h: Copied from jit/JIT.cpp.
+ (JSC::JIT::checkStructure):
+ (JSC::JIT::emitFastArithPotentiallyReTagImmediate):
+ (JSC::JIT::emitTagAsBoolImmediate):
+ * wtf/Platform.h:
+
+2008-12-03 Eric Seidel <eric@webkit.org>
+
+ Rubber-stamped by David Hyatt.
+
+ Make HAVE_ACCESSIBILITY only define if !defined
+
+ * wtf/Platform.h:
+
+2008-12-03 Sam Weinig <sam@webkit.org>
+
+ Fix build.
+
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::orl_i32r):
+
+2008-12-03 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Remove shared AssemblerBuffer 1MB buffer and instead give AssemblerBuffer
+ an 256 byte inline capacity.
+
+ 1% progression on Sunspider.
+
+ * assembler/AssemblerBuffer.h:
+ (JSC::AssemblerBuffer::AssemblerBuffer):
+ (JSC::AssemblerBuffer::~AssemblerBuffer):
+ (JSC::AssemblerBuffer::grow):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::MacroAssembler):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::X86Assembler):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::Interpreter):
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::JIT):
+ * parser/Nodes.cpp:
+ (JSC::RegExpNode::emitBytecode):
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ (JSC::RegExp::create):
+ * runtime/RegExp.h:
+ * runtime/RegExpConstructor.cpp:
+ (JSC::constructRegExp):
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncCompile):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncMatch):
+ (JSC::stringProtoFuncSearch):
+ * wrec/WREC.cpp:
+ (JSC::WREC::Generator::compileRegExp):
+ * wrec/WRECGenerator.h:
+ (JSC::WREC::Generator::Generator):
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::Parser):
+
+2008-12-03 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt, with help from Gavin Barraclough.
+
+ orl_i32r was actually coded as an 8bit OR. So, I renamed orl_i32r to
+ orl_i8r, changed all orl_i32r clients to use orl_i8r, and then added
+ a new orl_i32r that actually does a 32bit OR.
+
+ (32bit OR is currently unused, but a patch I'm working on uses it.)
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::or32): Updated to choose between 8bit and 32bit OR.
+
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::orl_i8r): The old orl_i32r.
+ (JSC::X86Assembler::orl_i32r): The new orl_i32r.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::emitFastArithPotentiallyReTagImmediate):
+ (JSC::JIT::emitTagAsBoolImmediate): Use orl_i8r, since we're ORing 8bit
+ values.
+
+2008-12-03 Dean Jackson <dino@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Helper functions for turn -> degrees.
+ https://bugs.webkit.org/show_bug.cgi?id=22497
+
+ * wtf/MathExtras.h:
+ (turn2deg):
+ (deg2turn):
+
+2008-12-02 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 22504: Crashes during code generation occur due to refing of ignoredResult()
+ <https://bugs.webkit.org/show_bug.cgi?id=22504>
+
+ Since ignoredResult() was implemented by casting 1 to a RegisterID*, any
+ attempt to ref ignoredResult() results in a crash. This will occur in
+ code generation of a function body where a node emits another node with
+ the dst that was passed to it, and then refs the returned RegisterID*.
+
+ To fix this problem, make ignoredResult() a member function of
+ BytecodeGenerator that simply returns a pointe to a fixed RegisterID
+ member of BytecodeGenerator.
+
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::ignoredResult):
+ * bytecompiler/RegisterID.h:
+ * parser/Nodes.cpp:
+ (JSC::NullNode::emitBytecode):
+ (JSC::BooleanNode::emitBytecode):
+ (JSC::NumberNode::emitBytecode):
+ (JSC::StringNode::emitBytecode):
+ (JSC::RegExpNode::emitBytecode):
+ (JSC::ThisNode::emitBytecode):
+ (JSC::ResolveNode::emitBytecode):
+ (JSC::ObjectLiteralNode::emitBytecode):
+ (JSC::PostfixResolveNode::emitBytecode):
+ (JSC::PostfixBracketNode::emitBytecode):
+ (JSC::PostfixDotNode::emitBytecode):
+ (JSC::DeleteValueNode::emitBytecode):
+ (JSC::VoidNode::emitBytecode):
+ (JSC::TypeOfResolveNode::emitBytecode):
+ (JSC::TypeOfValueNode::emitBytecode):
+ (JSC::PrefixResolveNode::emitBytecode):
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::CommaNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::ThrowNode::emitBytecode):
+ (JSC::FunctionBodyNode::emitBytecode):
+ (JSC::FuncDeclNode::emitBytecode):
+
+2008-12-02 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Fixed https://bugs.webkit.org/show_bug.cgi?id=22537
+ REGRESSION (r38745): Assertion failure in jsSubstring() at ge.com
+
+ The bug was that index would become greater than length, so our
+ "end of input" checks, which all check "index == length", would fail.
+
+ The solution is to check for end of input before incrementing index,
+ to ensure that index is always <= length.
+
+ As a side benefit, generateJumpIfEndOfInput can now use je instead of
+ jg, which should be slightly faster.
+
+ * wrec/WREC.cpp:
+ (JSC::WREC::Generator::compileRegExp):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateJumpIfEndOfInput):
+
+2008-12-02 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Plant shift right immediate instructions, which are awesome.
+ https://bugs.webkit.org/show_bug.cgi?id=22610
+ ~5% on the v8-crypto test.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+
+2008-12-02 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Cleaned up SegmentedVector by abstracting segment access into helper
+ functions.
+
+ SunSpider reports no change.
+
+ * bytecompiler/SegmentedVector.h:
+ (JSC::SegmentedVector::SegmentedVector):
+ (JSC::SegmentedVector::~SegmentedVector):
+ (JSC::SegmentedVector::size):
+ (JSC::SegmentedVector::at):
+ (JSC::SegmentedVector::operator[]):
+ (JSC::SegmentedVector::last):
+ (JSC::SegmentedVector::append):
+ (JSC::SegmentedVector::removeLast):
+ (JSC::SegmentedVector::grow):
+ (JSC::SegmentedVector::clear):
+ (JSC::SegmentedVector::deleteAllSegments):
+ (JSC::SegmentedVector::segmentFor):
+ (JSC::SegmentedVector::subscriptFor):
+ (JSC::SegmentedVector::ensureSegmentsFor):
+ (JSC::SegmentedVector::ensureSegment):
+
+2008-12-02 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Geoffrey Garen. (Patch by Cameron Zwarich <zwarich@apple.com>.)
+
+ Fixed https://bugs.webkit.org/show_bug.cgi?id=22482
+ REGRESSION (r37991): Occasionally see "Scene rendered incorrectly"
+ message when running the V8 Raytrace benchmark
+
+ Rolled out r37991. It didn't properly save xmm0, which is caller-save,
+ before calling helper functions.
+
+ SunSpider and v8 benchmarks show little change -- possibly a .2%
+ SunSpider regression, possibly a .2% v8 benchmark speedup.
+
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::):
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Instruction.h:
+ (JSC::Instruction::):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitUnaryOp):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::emitToJSNumber):
+ (JSC::BytecodeGenerator::emitTypeOf):
+ (JSC::BytecodeGenerator::emitGetPropertyNames):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * parser/Nodes.cpp:
+ (JSC::UnaryOpNode::emitBytecode):
+ (JSC::BinaryOpNode::emitBytecode):
+ (JSC::EqualNode::emitBytecode):
+ * parser/ResultType.h:
+ (JSC::ResultType::isReusable):
+ (JSC::ResultType::mightBeNumber):
+ * runtime/JSNumberCell.h:
+
+2008-12-01 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Remove unused (sampling only, and derivable) argument to JIT::emitCTICall.
+ https://bugs.webkit.org/show_bug.cgi?id=22587
+
+ * jit/JIT.cpp:
+ (JSC::JIT::emitCTICall):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::emitSlowScriptCheck):
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+
+2008-12-02 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Fix the inheritance chain for JSFunction.
+
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::info): Add InternalFunction::info as parent class
+
+2008-12-02 Simon Hausmann <hausmann@webkit.org>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Fix ability to include JavaScriptCore.pri from other .pro files.
+
+ * JavaScriptCore.pri: Moved -O3 setting into the .pro files.
+ * JavaScriptCore.pro:
+ * jsc.pro:
+
+2008-12-01 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Cameron Zwarich, with help from Gavin Barraclough.
+
+ Fixed https://bugs.webkit.org/show_bug.cgi?id=22583.
+
+ Refactored regular expression parsing to parse sequences of characters
+ as a single unit, in preparation for optimizing sequences of characters.
+
+ SunSpider reports no change.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wrec/Escapes.h: Added. Set of classes for representing an escaped
+ token in a pattern.
+
+ * wrec/Quantifier.h:
+ (JSC::WREC::Quantifier::Quantifier): Simplified this constructor slightly,
+ to match the new Escape constructor.
+
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generatePatternCharacterSequence):
+ * wrec/WRECGenerator.h: Added an interface for generating a sequence
+ of pattern characters at a time. It doesn't do anything special yet.
+
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::Parser::consumeGreedyQuantifier):
+ (JSC::WREC::Parser::consumeQuantifier): Renamed "parse" to "consume" in
+ these functions, to match "consumeEscape."
+
+ (JSC::WREC::Parser::parsePatternCharacterSequence): New function for
+ iteratively aggregating a sequence of characters in a pattern.
+
+ (JSC::WREC::Parser::parseCharacterClassQuantifier):
+ (JSC::WREC::Parser::parseBackreferenceQuantifier): Renamed "parse" to
+ "consume" in these functions, to match "consumeEscape."
+
+ (JSC::WREC::Parser::parseCharacterClass): Refactored to use the common
+ escape processing code in consumeEscape.
+
+ (JSC::WREC::Parser::parseEscape): Refactored to use the common
+ escape processing code in consumeEscape.
+
+ (JSC::WREC::Parser::consumeEscape): Factored escaped token processing
+ into a common function, since we were doing this in a few places.
+
+ (JSC::WREC::Parser::parseTerm): Refactored to use the common
+ escape processing code in consumeEscape.
+
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::consumeOctal): Refactored to use a helper function
+ for reading a digit.
+
+2008-12-01 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 20340: SegmentedVector segment allocations can lead to unsafe use of temporary registers
+ <https://bugs.webkit.org/show_bug.cgi?id=20340>
+
+ SegmentedVector currently frees segments and reallocates them when used
+ as a stack. This can lead to unsafe use of pointers into freed segments.
+
+ In order to fix this problem, SegmentedVector will be changed to only
+ grow and never shrink. Also, rename the reserveCapacity() member
+ function to grow() to match the actual usage in BytecodeGenerator, where
+ this function is used to allocate a group of registers at once, rather
+ than merely saving space for them.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator): Use grow() instead of
+ reserveCapacity().
+ * bytecompiler/SegmentedVector.h:
+ (JSC::SegmentedVector::SegmentedVector):
+ (JSC::SegmentedVector::last):
+ (JSC::SegmentedVector::append):
+ (JSC::SegmentedVector::removeLast):
+ (JSC::SegmentedVector::grow): Renamed from reserveCapacity().
+ (JSC::SegmentedVector::clear):
+
+2008-12-01 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Anders Carlsson.
+
+ Disable WREC for x86_64 since memory allocated by the system allocator is not marked executable,
+ which causes 64-bit debug builds to crash. Once we have a dedicated allocator for executable
+ memory we can turn this back on.
+
+ * wtf/Platform.h:
+
+2008-12-01 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Restore inline buffer after vector is shrunk back below its inline capacity.
+
+ * wtf/Vector.h:
+ (WTF::):
+ (WTF::VectorBuffer::restoreInlineBufferIfNeeded):
+ (WTF::::shrinkCapacity):
+
+2008-11-30 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Try to return free pages in the current thread cache too.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMallocStats::releaseFastMallocFreeMemory):
+
+2008-12-01 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22567
+ Make HashTable work as expected with respect to threads. Specifically, it has class-level
+ thread safety and constant methods work on constant objects without synchronization.
+
+ No observable change in behavior, so no test. This only affects debug builds.
+
+ * wtf/HashTable.cpp:
+ (WTF::hashTableStatsMutex):
+ (WTF::HashTableStats::~HashTableStats):
+ (WTF::HashTableStats::recordCollisionAtCount):
+ Guarded variable access with a mutex.
+
+ * wtf/HashTable.h:
+ (WTF::::lookup):
+ (WTF::::lookupForWriting):
+ (WTF::::fullLookupForWriting):
+ (WTF::::add):
+ (WTF::::reinsert):
+ (WTF::::remove):
+ (WTF::::rehash):
+ Changed increments of static variables to use atomicIncrement.
+
+ (WTF::::invalidateIterators):
+ (WTF::addIterator):
+ (WTF::removeIterator):
+ Guarded mutable access with a mutex.
+
+2008-11-29 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Enable WREC on PLATFORM(X86_64). This change predominantly requires changes to the
+ WREC::Generator::generateEnter method to support the x86-64 ABI, and addition of
+ support for a limited number of quadword operations in the X86Assembler.
+
+ This patch will cause the JS heap to be allocated with RWX permissions on 64-bit Mac
+ platforms. This is a regression with respect to previous 64-bit behaviour, but is no
+ more permissive than on 32-bit builds. This issue should be addressed at some point.
+ (This is tracked by bug #21783.)
+
+ https://bugs.webkit.org/show_bug.cgi?id=22554
+ Greater than 4x speedup on regexp-dna, on x86-64.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::addPtr):
+ (JSC::MacroAssembler::loadPtr):
+ (JSC::MacroAssembler::storePtr):
+ (JSC::MacroAssembler::pop):
+ (JSC::MacroAssembler::push):
+ (JSC::MacroAssembler::move):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::movq_rr):
+ (JSC::X86Assembler::addl_i8m):
+ (JSC::X86Assembler::addl_i32r):
+ (JSC::X86Assembler::addq_i8r):
+ (JSC::X86Assembler::addq_i32r):
+ (JSC::X86Assembler::movq_mr):
+ (JSC::X86Assembler::movq_rm):
+ * wrec/WREC.h:
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateEnter):
+ (JSC::WREC::Generator::generateReturnSuccess):
+ (JSC::WREC::Generator::generateReturnFailure):
+ * wtf/Platform.h:
+ * wtf/TCSystemAlloc.cpp:
+
+2008-12-01 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Preliminary work for bug 20340: SegmentedVector segment allocations can lead to unsafe use of temporary registers
+ <https://bugs.webkit.org/show_bug.cgi?id=20340>
+
+ SegmentedVector currently frees segments and reallocates them when used
+ as a stack. This can lead to unsafe use of pointers into freed segments.
+
+ In order to fix this problem, SegmentedVector will be changed to only
+ grow and never shrink, with the sole exception of clearing all of its
+ data, a capability that is required by Lexer. This patch changes the
+ public interface to only allow for these capabilities.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator): Use reserveCapacity()
+ instead of resize() for m_globals and m_parameters.
+ * bytecompiler/SegmentedVector.h:
+ (JSC::SegmentedVector::resize): Removed.
+ (JSC::SegmentedVector::reserveCapacity): Added.
+ (JSC::SegmentedVector::clear): Added.
+ (JSC::SegmentedVector::shrink): Removed.
+ (JSC::SegmentedVector::grow): Removed.
+ * parser/Lexer.cpp:
+ (JSC::Lexer::clear): Use clear() instead of resize(0).
+
+2008-11-30 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ Renames jumps to m_jumps in JumpList.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::JumpList::link):
+ (JSC::MacroAssembler::JumpList::linkTo):
+ (JSC::MacroAssembler::JumpList::append):
+
+2008-11-30 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22557
+
+ Report free size in central and thread caches too.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMallocStats::fastMallocStatistics):
+ * wtf/FastMalloc.h:
+
+2008-11-29 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22557
+ Add statistics for JavaScript GC heap.
+
+ * JavaScriptCore.exp:
+ * runtime/Collector.cpp:
+ (JSC::Heap::objectCount):
+ (JSC::addToStatistics):
+ (JSC::Heap::statistics):
+ * runtime/Collector.h:
+
+2008-11-29 Antti Koivisto <antti@apple.com>
+
+ Fix debug build by adding a stub method.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::fastMallocStatistics):
+
+2008-11-29 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22557
+
+ Add function for getting basic statistics from FastMalloc.
+
+ * JavaScriptCore.exp:
+ * wtf/FastMalloc.cpp:
+ (WTF::DLL_Length):
+ (WTF::TCMalloc_PageHeap::ReturnedBytes):
+ (WTF::TCMallocStats::fastMallocStatistics):
+ * wtf/FastMalloc.h:
+
+2008-11-29 Cameron Zwarich <zwarich@apple.com>
+
+ Not reviewed.
+
+ The C++ standard does not automatically grant the friendships of an
+ enclosing class to its nested subclasses, so we should do so explicitly.
+ This fixes the GCC 4.0 build, although both GCC 4.2 and Visual C++ 2005
+ accept the incorrect code as it is.
+
+ * assembler/MacroAssembler.h:
+
+2008-11-29 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Add the class MacroAssembler to provide some abstraction of code generation,
+ and change WREC to make use of this class, rather than directly accessing
+ the X86Assembler.
+
+ This patch also allows WREC to be compiled without the rest of the JIT enabled.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/MacroAssembler.h: Added.
+ (JSC::MacroAssembler::):
+ (JSC::MacroAssembler::MacroAssembler):
+ (JSC::MacroAssembler::copyCode):
+ (JSC::MacroAssembler::Address::Address):
+ (JSC::MacroAssembler::ImplicitAddress::ImplicitAddress):
+ (JSC::MacroAssembler::BaseIndex::BaseIndex):
+ (JSC::MacroAssembler::Label::Label):
+ (JSC::MacroAssembler::Jump::Jump):
+ (JSC::MacroAssembler::Jump::link):
+ (JSC::MacroAssembler::Jump::linkTo):
+ (JSC::MacroAssembler::JumpList::link):
+ (JSC::MacroAssembler::JumpList::linkTo):
+ (JSC::MacroAssembler::JumpList::append):
+ (JSC::MacroAssembler::Imm32::Imm32):
+ (JSC::MacroAssembler::add32):
+ (JSC::MacroAssembler::or32):
+ (JSC::MacroAssembler::sub32):
+ (JSC::MacroAssembler::loadPtr):
+ (JSC::MacroAssembler::load32):
+ (JSC::MacroAssembler::load16):
+ (JSC::MacroAssembler::storePtr):
+ (JSC::MacroAssembler::store32):
+ (JSC::MacroAssembler::pop):
+ (JSC::MacroAssembler::push):
+ (JSC::MacroAssembler::peek):
+ (JSC::MacroAssembler::poke):
+ (JSC::MacroAssembler::move):
+ (JSC::MacroAssembler::compareImm32ForBranch):
+ (JSC::MacroAssembler::compareImm32ForBranchEquality):
+ (JSC::MacroAssembler::jae32):
+ (JSC::MacroAssembler::je32):
+ (JSC::MacroAssembler::je16):
+ (JSC::MacroAssembler::jg32):
+ (JSC::MacroAssembler::jge32):
+ (JSC::MacroAssembler::jl32):
+ (JSC::MacroAssembler::jle32):
+ (JSC::MacroAssembler::jne32):
+ (JSC::MacroAssembler::jump):
+ (JSC::MacroAssembler::breakpoint):
+ (JSC::MacroAssembler::ret):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::cmpw_rm):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::Interpreter):
+ * interpreter/Interpreter.h:
+ (JSC::Interpreter::assemblerBuffer):
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ * wrec/WREC.cpp:
+ (JSC::WREC::Generator::compileRegExp):
+ * wrec/WREC.h:
+ * wrec/WRECFunctors.cpp:
+ (JSC::WREC::GeneratePatternCharacterFunctor::generateAtom):
+ (JSC::WREC::GenerateCharacterClassFunctor::generateAtom):
+ (JSC::WREC::GenerateBackreferenceFunctor::generateAtom):
+ (JSC::WREC::GenerateParenthesesNonGreedyFunctor::generateAtom):
+ * wrec/WRECFunctors.h:
+ (JSC::WREC::GenerateParenthesesNonGreedyFunctor::GenerateParenthesesNonGreedyFunctor):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateEnter):
+ (JSC::WREC::Generator::generateReturnSuccess):
+ (JSC::WREC::Generator::generateSaveIndex):
+ (JSC::WREC::Generator::generateIncrementIndex):
+ (JSC::WREC::Generator::generateLoadCharacter):
+ (JSC::WREC::Generator::generateJumpIfEndOfInput):
+ (JSC::WREC::Generator::generateJumpIfNotEndOfInput):
+ (JSC::WREC::Generator::generateReturnFailure):
+ (JSC::WREC::Generator::generateBacktrack1):
+ (JSC::WREC::Generator::generateBacktrackBackreference):
+ (JSC::WREC::Generator::generateBackreferenceQuantifier):
+ (JSC::WREC::Generator::generateNonGreedyQuantifier):
+ (JSC::WREC::Generator::generateGreedyQuantifier):
+ (JSC::WREC::Generator::generatePatternCharacter):
+ (JSC::WREC::Generator::generateCharacterClassInvertedRange):
+ (JSC::WREC::Generator::generateCharacterClassInverted):
+ (JSC::WREC::Generator::generateCharacterClass):
+ (JSC::WREC::Generator::generateParentheses):
+ (JSC::WREC::Generator::generateParenthesesNonGreedy):
+ (JSC::WREC::Generator::generateParenthesesResetTrampoline):
+ (JSC::WREC::Generator::generateAssertionBOL):
+ (JSC::WREC::Generator::generateAssertionEOL):
+ (JSC::WREC::Generator::generateAssertionWordBoundary):
+ (JSC::WREC::Generator::generateBackreference):
+ (JSC::WREC::Generator::terminateAlternative):
+ (JSC::WREC::Generator::terminateDisjunction):
+ * wrec/WRECGenerator.h:
+ (JSC::WREC::Generator::Generator):
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::Parser::parsePatternCharacterQualifier):
+ (JSC::WREC::Parser::parseCharacterClassQuantifier):
+ (JSC::WREC::Parser::parseBackreferenceQuantifier):
+ (JSC::WREC::Parser::parseParentheses):
+ (JSC::WREC::Parser::parseCharacterClass):
+ (JSC::WREC::Parser::parseOctalEscape):
+ (JSC::WREC::Parser::parseEscape):
+ (JSC::WREC::Parser::parseTerm):
+ (JSC::WREC::Parser::parseDisjunction):
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::Parser):
+ (JSC::WREC::Parser::parsePattern):
+ (JSC::WREC::Parser::parseAlternative):
+ * wtf/Platform.h:
+
+2008-11-28 Simon Hausmann <hausmann@webkit.org>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Fix compilation on Windows CE
+
+ Port away from the use of errno after calling strtol(), instead
+ detect conversion errors by checking the result and the stop
+ position.
+
+ * runtime/DateMath.cpp:
+ (JSC::parseLong):
+ (JSC::parseDate):
+
+2008-11-28 Joerg Bornemann <joerg.bornemann@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ Implement lowResUTCTime() on Windows CE using GetSystemTime as _ftime() is not available.
+
+ * runtime/DateMath.cpp:
+ (JSC::lowResUTCTime):
+
+2008-11-28 Simon Hausmann <hausmann@webkit.org>
+
+ Rubber-stamped by Tor Arne Vestbø.
+
+ Removed unnecessary inclusion of errno.h, which also fixes compilation on Windows CE.
+
+ * runtime/JSGlobalObjectFunctions.cpp:
+
+2008-11-27 Cameron Zwarich <zwarich@apple.com>
+
+ Not reviewed.
+
+ r38825 made JSFunction::m_body private, but some inspector code in
+ WebCore sets the field. Add setters for it.
+
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::setBody):
+
+2008-11-27 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Cameron Zwarich.
+
+ Fix FIXME by adding accessor for JSFunction's m_body property.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_op_call_JSFunction):
+ (JSC::Interpreter::cti_vm_dontLazyLinkCall):
+ (JSC::Interpreter::cti_vm_lazyLinkCall):
+ * profiler/Profiler.cpp:
+ (JSC::createCallIdentifierFromFunctionImp):
+ * runtime/Arguments.h:
+ (JSC::Arguments::getArgumentsData):
+ (JSC::Arguments::Arguments):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncToString):
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::JSFunction):
+ (JSC::JSFunction::body):
+
+2008-11-27 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ Remove unused member variables from ProgramNode.
+
+ * parser/Nodes.h:
+
+2008-11-27 Brent Fulgham <bfulgham@gmail.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Enable mouse panning feaure on Windows Cairo build.
+ See http://bugs.webkit.org/show_bug.cgi?id=22525
+
+ * wtf/Platform.h: Enable mouse panning feaure on Windows Cairo build.
+
+2008-11-27 Alp Toker <alp@nuanti.com>
+
+ Change recently introduced C++ comments in Platform.h to C comments to
+ fix the minidom build with traditional C.
+
+ Build GtkLauncher and minidom with the '-ansi' compiler flag to detect
+ API header breakage at build time.
+
+ * GNUmakefile.am:
+ * wtf/Platform.h:
+
+2008-11-27 Alp Toker <alp@nuanti.com>
+
+ Remove C++ comment from JavaScriptCore API headers (introduced r35449).
+ Fixes build for ANSI C applications using the public API.
+
+ * API/WebKitAvailability.h:
+
+2008-11-26 Eric Seidel <eric@webkit.org>
+
+ No review, build fix only.
+
+ Fix the JSC Chromium Mac build by adding JavaScriptCore/icu into the include path
+
+ * JavaScriptCore.scons:
+
+2008-11-25 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Remove the unused member function JSFunction::getParameterName().
+
+ * runtime/JSFunction.cpp:
+ * runtime/JSFunction.h:
+
+2008-11-24 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Polymorpic caching for get by id chain. Similar to the polymorphic caching already implemented
+ for self and proto accesses (implemented by allowing multiple trampolines to be JIT genertaed,
+ and linked together) - the get by id chain caching is implemented as a genericization of the
+ proto list caching, allowing cached access lists to contain a mix of proto and proto chain
+ accesses (since in JS style inheritance hierarchies you may commonly see a mix of properties
+ being overridden on the direct prototype, or higher up its prototype chain).
+
+ In order to allow this patch to compile there is a fix to appease gcc 4.2 compiler issues
+ (removing the jumps between fall-through cases in privateExecute).
+
+ This patch also removes redundant immediate checking from the reptach code, and fixes a related
+ memory leak (failure to deallocate trampolines).
+
+ ~2% progression on v8 tests (bulk on the win on deltablue)
+
+ * bytecode/Instruction.h:
+ (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::):
+ (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
+ (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
+ (JSC::PolymorphicAccessStructureList::derefStructures):
+ * interpreter/Interpreter.cpp:
+ (JSC::countPrototypeChainEntriesAndCheckForProxies):
+ (JSC::Interpreter::tryCacheGetByID):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::getPolymorphicAccessStructureListSlot):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list):
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * jit/JIT.h:
+ (JSC::JIT::compileGetByIdChainList):
+
+2008-11-25 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Move the collect() call in Heap::heapAllocate() that is conditionally
+ compiled under COLLECT_ON_EVERY_ALLOCATION so that it is before we get
+ information about the heap. This was causing assertion failures for me
+ while I was reducing a bug.
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::heapAllocate):
+
+2008-11-24 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 13790: Function declarations are not treated as statements (used to affect starcraft2.com)
+ <https://bugs.webkit.org/show_bug.cgi?id=13790>
+
+ Modify the parser to treat function declarations as statements,
+ simplifying the grammar in the process. Technically, according to the
+ grammar in the ECMA spec, function declarations are not statements and
+ can not be used everywhere that statements can, but it is not worth the
+ possibility compatibility issues just to stick to the spec in this case.
+
+ * parser/Grammar.y:
+ * parser/Nodes.cpp:
+ (JSC::FuncDeclNode::emitBytecode): Avoid returning ignoredResult()
+ as a result, because it causes a crash in DoWhileNode::emitBytecode().
+
+2008-11-24 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Unroll the regexp matching loop by 1. 10% speedup on simple matching
+ stress test. No change on SunSpider.
+
+ (I decided not to unroll to arbitrary levels because the returns diminsh
+ quickly.)
+
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateJumpIfEndOfInput):
+ (JSC::WREC::Generator::generateJumpIfNotEndOfInput):
+ * wrec/WRECGenerator.h:
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::error):
+ (JSC::WREC::Parser::parsePattern):
+
+2008-11-24 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Removed some unnecessary "Generator::" prefixes.
+
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateEnter):
+ (JSC::WREC::Generator::generateReturnSuccess):
+ (JSC::WREC::Generator::generateSaveIndex):
+ (JSC::WREC::Generator::generateIncrementIndex):
+ (JSC::WREC::Generator::generateLoopIfNotEndOfInput):
+ (JSC::WREC::Generator::generateReturnFailure):
+
+2008-11-24 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Made a bunch of WREC::Parser functions private, and added an explicit
+ "reset()" function, so a parser can be reused.
+
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::Parser):
+ (JSC::WREC::Parser::generator):
+ (JSC::WREC::Parser::ignoreCase):
+ (JSC::WREC::Parser::multiline):
+ (JSC::WREC::Parser::recordSubpattern):
+ (JSC::WREC::Parser::numSubpatterns):
+ (JSC::WREC::Parser::parsePattern):
+ (JSC::WREC::Parser::parseAlternative):
+ (JSC::WREC::Parser::reset):
+
+2008-11-24 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Implement repatching for get by id chain.
+ Previously the access is performed in a function stub, in the repatch form
+ the trampoline is not called to; instead the hot path is relinked to jump
+ directly to the trampoline, if it fails it will jump to the slow case.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22449
+ 3% progression on deltablue.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdChain):
+
+2008-11-24 Joerg Bornemann <joerg.bornemann@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=20746
+
+ Various small compilation fixes to make the Qt port of WebKit
+ compile on Windows CE.
+
+ * config.h: Don't set _CRT_RAND_S for CE, it's not available.
+ * jsc.cpp: Disabled use of debugger includes for CE. It
+ does not have the debugging functions.
+ * runtime/DateMath.cpp: Use localtime() on Windows CE.
+ * wtf/Assertions.cpp: Compile on Windows CE without debugger.
+ * wtf/Assertions.h: Include windows.h before defining ASSERT.
+ * wtf/MathExtras.h: Include stdlib.h instead of xmath.h.
+ * wtf/Platform.h: Disable ERRNO_H and detect endianess based
+ on the Qt endianess. On Qt for Windows CE the endianess is
+ defined by the vendor specific build spec.
+ * wtf/Threading.h: Use the volatile-less atomic functions.
+ * wtf/dtoa.cpp: Compile without errno.
+ * wtf/win/MainThreadWin.cpp: Don't include windows.h on CE after
+ Assertions.h due to the redefinition of ASSERT.
+
+2008-11-22 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Replace accidentally deleted immediate check from get by id chain trampoline.
+ https://bugs.webkit.org/show_bug.cgi?id=22413
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileGetByIdChain):
+
+2008-11-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Add (really) polymorphic caching for get by id self.
+ Very similar to caching of prototype accesses, described below.
+
+ Oh, also, probably shouldn't have been leaking those structure list objects.
+
+ 4% preogression on deltablue.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::derefStructures):
+ (JSC::PrototypeStructureList::derefStructures):
+ * bytecode/Instruction.h:
+ * bytecode/Opcode.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::patchGetByIdSelf):
+ * jit/JIT.h:
+ (JSC::JIT::compileGetByIdSelfList):
+
+2008-11-21 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixed many crashes seen 'round the world (but only in release builds).
+
+ Update outputParameter offset to reflect slight re-ordering of push
+ instructions in r38669.
+
+ * wrec/WRECGenerator.cpp:
+
+2008-11-21 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ A little more RegExp refactoring.
+
+ Deployed a helper function for reading the next character. Used the "link
+ vector of jumps" helper in a place I missed before.
+
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateLoadCharacter):
+ (JSC::WREC::Generator::generatePatternCharacter):
+ (JSC::WREC::Generator::generateCharacterClass):
+ (JSC::WREC::Generator::generateAssertionEOL):
+ (JSC::WREC::Generator::generateAssertionWordBoundary):
+ * wrec/WRECGenerator.h:
+
+2008-11-21 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Dan Bernstein.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22402
+ Replace abort() with CRASH()
+
+ * wtf/Assertions.h: Added a different method to crash, which should work even is 0xbbadbeef
+ is a valid memory address.
+
+ * runtime/Collector.cpp:
+ * wtf/FastMalloc.cpp:
+ * wtf/FastMalloc.h:
+ * wtf/TCSpinLock.h:
+ Replace abort() with CRASH().
+
+2008-11-21 Alexey Proskuryakov <ap@webkit.org>
+
+ Reverted fix for bug 22042 (Replace abort() with CRASH()), because it was breaking
+ FOR_EACH_OPCODE_ID macro somehow, making Safari crash.
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::heapAllocate):
+ (JSC::Heap::collect):
+ * wtf/Assertions.h:
+ * wtf/FastMalloc.cpp:
+ (WTF::fastMalloc):
+ (WTF::fastCalloc):
+ (WTF::fastRealloc):
+ (WTF::InitSizeClasses):
+ (WTF::PageHeapAllocator::New):
+ (WTF::TCMallocStats::do_malloc):
+ * wtf/FastMalloc.h:
+ * wtf/TCSpinLock.h:
+ (TCMalloc_SpinLock::Init):
+ (TCMalloc_SpinLock::Finalize):
+ (TCMalloc_SpinLock::Lock):
+ (TCMalloc_SpinLock::Unlock):
+
+2008-11-21 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ A little more RegExp refactoring.
+
+ Moved all assembly from WREC.cpp into WRECGenerator helper functions.
+ This should help with portability and readability.
+
+ Removed ASSERTs after calls to executableCopy(), and changed
+ executableCopy() to ASSERT instead.
+
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::executableCopy):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateEnter):
+ (JSC::WREC::Generator::generateReturnSuccess):
+ (JSC::WREC::Generator::generateSaveIndex):
+ (JSC::WREC::Generator::generateIncrementIndex):
+ (JSC::WREC::Generator::generateLoopIfNotEndOfInput):
+ (JSC::WREC::Generator::generateReturnFailure):
+ * wrec/WRECGenerator.h:
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::ignoreCase):
+ (JSC::WREC::Parser::generator):
+
+2008-11-21 Alexey Proskuryakov <ap@webkit.org>
+
+ Build fix.
+
+ * wtf/Assertions.h: Use ::abort for C++ code.
+
+2008-11-21 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22402
+ Replace abort() with CRASH()
+
+ * wtf/Assertions.h: Added abort() after an attempt to crash for extra safety.
+
+ * runtime/Collector.cpp:
+ * wtf/FastMalloc.cpp:
+ * wtf/FastMalloc.h:
+ * wtf/TCSpinLock.h:
+ Replace abort() with CRASH().
+
+2008-11-21 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed wrec => generator.
+
+ * wrec/WRECFunctors.cpp:
+ (JSC::WREC::GeneratePatternCharacterFunctor::generateAtom):
+ (JSC::WREC::GeneratePatternCharacterFunctor::backtrack):
+ (JSC::WREC::GenerateCharacterClassFunctor::generateAtom):
+ (JSC::WREC::GenerateCharacterClassFunctor::backtrack):
+ (JSC::WREC::GenerateBackreferenceFunctor::generateAtom):
+ (JSC::WREC::GenerateBackreferenceFunctor::backtrack):
+ (JSC::WREC::GenerateParenthesesNonGreedyFunctor::generateAtom):
+
+2008-11-19 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Add support for (really) polymorphic caching of prototype accesses.
+
+ If a cached prototype access misses, cti_op_get_by_id_proto_list is called.
+ When this occurs the Structure pointers from the instruction stream are copied
+ off into a new ProtoStubInfo object. A second prototype access trampoline is
+ generated, and chained onto the first. Subsequent missed call to
+ cti_op_get_by_id_proto_list_append, which append futher new trampolines, up to
+ PROTOTYPE_LIST_CACHE_SIZE (currently 4). If any of the misses result in an
+ access other than to a direct prototype property, list formation is halted (or
+ for the initial miss, does not take place at all).
+
+ Separate fail case functions are provided for each access since this contributes
+ to the performance progression (enables better processor branch prediction).
+
+ Overall this is a near 5% progression on v8, with around 10% wins on richards
+ and deltablue.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::derefStructures):
+ * bytecode/Instruction.h:
+ (JSC::ProtoStructureList::ProtoStubInfo::set):
+ (JSC::ProtoStructureList::ProtoStructureList):
+ (JSC::Instruction::Instruction):
+ (JSC::Instruction::):
+ * bytecode/Opcode.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::Interpreter::cti_op_put_by_id_fail):
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list_append):
+ (JSC::Interpreter::cti_op_get_by_id_proto_list_full):
+ (JSC::Interpreter::cti_op_get_by_id_proto_fail):
+ (JSC::Interpreter::cti_op_get_by_id_chain_fail):
+ (JSC::Interpreter::cti_op_get_by_id_array_fail):
+ (JSC::Interpreter::cti_op_get_by_id_string_fail):
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * jit/JIT.h:
+ (JSC::JIT::compileGetByIdProtoList):
+
+2008-11-20 Sam Weinig <sam@webkit.org>
+
+ Try and fix the tiger build.
+
+ * parser/Grammar.y:
+
+2008-11-20 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Make JavaScriptCore Chromium build under Windows (cmd only, cygwin almost works)
+ https://bugs.webkit.org/show_bug.cgi?id=22347
+
+ * JavaScriptCore.scons:
+ * parser/Parser.cpp: Add using std::auto_ptr since we use auto_ptr
+
+2008-11-20 Steve Falkenburg <sfalken@apple.com>
+
+ Fix build.
+
+ Reviewed by Sam Weinig.
+
+ * parser/Parser.cpp:
+ (JSC::Parser::reparse):
+
+2008-11-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ A little more RegExp refactoring.
+
+ Created a helper function in the assembler for linking a vector of
+ JmpSrc to a location, and deployed it in a bunch of places.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::link):
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateNonGreedyQuantifier):
+ (JSC::WREC::Generator::generateGreedyQuantifier):
+ (JSC::WREC::Generator::generateCharacterClassInverted):
+ (JSC::WREC::Generator::generateParentheses):
+ (JSC::WREC::Generator::generateParenthesesResetTrampoline):
+ (JSC::WREC::Generator::generateAssertionBOL):
+ (JSC::WREC::Generator::generateAssertionEOL):
+ (JSC::WREC::Generator::generateAssertionWordBoundary):
+ (JSC::WREC::Generator::terminateAlternative):
+ (JSC::WREC::Generator::terminateDisjunction):
+ * wrec/WRECParser.cpp:
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::consumeHex):
+
+2008-11-20 Sam Weinig <sam@webkit.org>
+
+ Fix non-mac builds.
+
+ * parser/Lexer.cpp:
+ * parser/Parser.cpp:
+
+2008-11-20 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Patch for https://bugs.webkit.org/show_bug.cgi?id=22385
+ <rdar://problem/6390179>
+ Lazily reparse FunctionBodyNodes on first execution.
+
+ - Saves 57MB on Membuster head.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate): Remove vector shrinking since this is now
+ handled by destroying the ScopeNodeData after generation.
+
+ * parser/Grammar.y: Add alternate NoNode version of the grammar
+ that does not create nodes. This is used to lazily create FunctionBodyNodes
+ on first execution.
+
+ * parser/Lexer.cpp:
+ (JSC::Lexer::setCode): Fix bug where on reparse, the Lexer was confused about
+ what position and length meant. Position is the current position in the original
+ data buffer (important for getting correct line/column information) and length
+ the end offset in the original buffer.
+ * parser/Lexer.h:
+ (JSC::Lexer::sourceCode): Positions are relative to the beginning of the buffer.
+
+ * parser/Nodes.cpp:
+ (JSC::ScopeNodeData::ScopeNodeData): Move initialization of ScopeNode data here.
+ (JSC::ScopeNode::ScopeNode): Add constructor that only sets the JSGlobalData
+ for FunctionBodyNode stubs.
+ (JSC::ScopeNode::~ScopeNode): Release m_children now that we don't inherit from
+ BlockNode.
+ (JSC::ScopeNode::releaseNodes): Ditto.
+ (JSC::EvalNode::generateBytecode): Only shrink m_children, as we need to keep around
+ the rest of the data.
+ (JSC::FunctionBodyNode::FunctionBodyNode): Add constructor that only sets the
+ JSGlobalData.
+ (JSC::FunctionBodyNode::create): Ditto.
+ (JSC::FunctionBodyNode::generateBytecode): If we don't have the data, do a reparse
+ to construct it. Then after generation, destroy the data.
+ (JSC::ProgramNode::generateBytecode): After generation, destroy the AST data.
+ * parser/Nodes.h:
+ (JSC::ExpressionNode::): Add isFuncExprNode for FunctionConstructor.
+ (JSC::StatementNode::): Add isExprStatementNode for FunctionConstructor.
+ (JSC::ExprStatementNode::): Ditto.
+ (JSC::ExprStatementNode::expr): Add accessor for FunctionConstructor.
+ (JSC::FuncExprNode::): Add isFuncExprNode for FunctionConstructor
+
+ (JSC::ScopeNode::adoptData): Adopts a ScopeNodeData.
+ (JSC::ScopeNode::data): Accessor for ScopeNodeData.
+ (JSC::ScopeNode::destroyData): Deletes the ScopeNodeData.
+ (JSC::ScopeNode::setFeatures): Added.
+ (JSC::ScopeNode::varStack): Added assert.
+ (JSC::ScopeNode::functionStack): Ditto.
+ (JSC::ScopeNode::children): Ditto.
+ (JSC::ScopeNode::neededConstants): Ditto.
+ Factor m_varStack, m_functionStack, m_children and m_numConstants into ScopeNodeData.
+
+ * parser/Parser.cpp:
+ (JSC::Parser::reparse): Reparse the SourceCode in the FunctionBodyNode and set
+ set up the ScopeNodeData for it.
+ * parser/Parser.h:
+
+ * parser/SourceCode.h:
+ (JSC::SourceCode::endOffset): Added for use in the lexer.
+
+ * runtime/FunctionConstructor.cpp:
+ (JSC::getFunctionBody): Assuming a ProgramNode with one FunctionExpression in it,
+ get the FunctionBodyNode. Any issues signifies a parse failure in constructFunction.
+ (JSC::constructFunction): Make parsing functions in the form new Function(""), easier
+ by concatenating the strings together (with some glue) and parsing the function expression
+ as a ProgramNode from which we can receive the FunctionBodyNode. This has the added benefit
+ of not having special parsing code for the arguments and lazily constructing the
+ FunctionBodyNode's AST on first execution.
+
+ * runtime/Identifier.h:
+ (JSC::operator!=): Added.
+
+2008-11-20 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Speedup the lexer to offset coming re-parsing patch.
+
+ - .6% progression on Sunspider.
+
+ * bytecompiler/SegmentedVector.h:
+ (JSC::SegmentedVector::shrink): Fixed bug where m_size would not be
+ set when shrinking to 0.
+
+ * parser/Lexer.cpp:
+ (JSC::Lexer::Lexer):
+ (JSC::Lexer::isIdentStart): Use isASCIIAlpha and isASCII to avoid going into ICU in the common cases.
+ (JSC::Lexer::isIdentPart): Use isASCIIAlphanumeric and isASCII to avoid going into ICU in the common cases
+ (JSC::isDecimalDigit): Use version in ASCIICType.h. Inlining it was a regression.
+ (JSC::Lexer::isHexDigit): Ditto.
+ (JSC::Lexer::isOctalDigit): Ditto.
+ (JSC::Lexer::clear): Resize the m_identifiers SegmentedVector to initial
+ capacity
+ * parser/Lexer.h: Remove unused m_strings vector. Make m_identifiers
+ a SegmentedVector<Identifier> to avoid allocating a new Identifier* for
+ each identifier found. The SegmentedVector is need so we can passes
+ references to the Identifier to the parser, which remain valid even when
+ the vector is resized.
+ (JSC::Lexer::makeIdentifier): Inline and return a reference to the added
+ Identifier.
+
+2008-11-20 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Add isASCII to ASCIICType. Use coming soon!
+
+ * wtf/ASCIICType.h:
+ (WTF::isASCII):
+
+2008-11-20 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Add OwnPtr constructor and OwnPtr::adopt that take an auto_ptr.
+
+ * wtf/OwnPtr.h:
+ (WTF::OwnPtr::OwnPtr):
+ (WTF::OwnPtr::adopt):
+
+2008-11-20 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22364
+ Crashes seen on Tiger buildbots due to worker threads exhausting pthread keys
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::Heap):
+ (JSC::Heap::destroy):
+ (JSC::Heap::makeUsableFromMultipleThreads):
+ (JSC::Heap::registerThread):
+ * runtime/Collector.h:
+ Pthread key for tracking threads is only created on request now, because this is a limited
+ resource, and thread tracking is not needed for worker heaps, or for WebCore heap.
+
+ * API/JSContextRef.cpp: (JSGlobalContextCreateInGroup): Call makeUsableFromMultipleThreads().
+
+ * runtime/JSGlobalData.cpp: (JSC::JSGlobalData::sharedInstance): Ditto.
+
+ * runtime/JSGlobalData.h: (JSC::JSGlobalData::makeUsableFromMultipleThreads): Just forward
+ the call to Heap, which clients need not know about, ideally.
+
+2008-11-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ A little more WREC refactoring.
+
+ Removed the "Register" suffix from register names in WREC, and renamed:
+ currentPosition => index
+ currentValue => character
+ quantifierCount => repeatCount
+
+ Added a top-level parsePattern function to the WREC parser, which
+ allowed me to remove the error() and atEndOfPattern() accessors.
+
+ Factored out an MSVC customization into a constant.
+
+ Renamed nextLabel => beginPattern.
+
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateBacktrack1):
+ (JSC::WREC::Generator::generateBacktrackBackreference):
+ (JSC::WREC::Generator::generateBackreferenceQuantifier):
+ (JSC::WREC::Generator::generateNonGreedyQuantifier):
+ (JSC::WREC::Generator::generateGreedyQuantifier):
+ (JSC::WREC::Generator::generatePatternCharacter):
+ (JSC::WREC::Generator::generateCharacterClassInvertedRange):
+ (JSC::WREC::Generator::generateCharacterClassInverted):
+ (JSC::WREC::Generator::generateCharacterClass):
+ (JSC::WREC::Generator::generateParentheses):
+ (JSC::WREC::Generator::generateParenthesesResetTrampoline):
+ (JSC::WREC::Generator::generateAssertionBOL):
+ (JSC::WREC::Generator::generateAssertionEOL):
+ (JSC::WREC::Generator::generateAssertionWordBoundary):
+ (JSC::WREC::Generator::generateBackreference):
+ (JSC::WREC::Generator::generateDisjunction):
+ (JSC::WREC::Generator::terminateDisjunction):
+ * wrec/WRECGenerator.h:
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::parsePattern):
+
+2008-11-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22361
+ A little more RegExp refactoring.
+
+ Consistently named variables holding the starting position at which
+ regexp matching should begin to "startOffset".
+
+ A few more "regExpObject" => "regExpConstructor" changes.
+
+ Refactored RegExpObject::match for clarity, and replaced a slow "get"
+ of the "global" property with a fast access to the global bit.
+
+ Made the error message you see when RegExpObject::match has no input a
+ little more informative, as in Firefox.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::match):
+ * runtime/RegExp.h:
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::match):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncReplace):
+ (JSC::stringProtoFuncMatch):
+ (JSC::stringProtoFuncSearch):
+
+2008-11-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ A little more refactoring.
+
+ Removed the "emit" and "emitUnlinked" prefixes from the assembler.
+
+ Moved the JmpSrc and JmpDst class definitions to the top of the X86
+ assembler class, in accordance with WebKit style guidelines.
+
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::JmpSrc::JmpSrc):
+ (JSC::X86Assembler::JmpDst::JmpDst):
+ (JSC::X86Assembler::int3):
+ (JSC::X86Assembler::pushl_m):
+ (JSC::X86Assembler::popl_m):
+ (JSC::X86Assembler::movl_rr):
+ (JSC::X86Assembler::addl_rr):
+ (JSC::X86Assembler::addl_i8r):
+ (JSC::X86Assembler::addl_i8m):
+ (JSC::X86Assembler::addl_i32r):
+ (JSC::X86Assembler::addl_mr):
+ (JSC::X86Assembler::andl_rr):
+ (JSC::X86Assembler::andl_i32r):
+ (JSC::X86Assembler::cmpl_i8r):
+ (JSC::X86Assembler::cmpl_rr):
+ (JSC::X86Assembler::cmpl_rm):
+ (JSC::X86Assembler::cmpl_mr):
+ (JSC::X86Assembler::cmpl_i32r):
+ (JSC::X86Assembler::cmpl_i32m):
+ (JSC::X86Assembler::cmpl_i8m):
+ (JSC::X86Assembler::cmpw_rm):
+ (JSC::X86Assembler::orl_rr):
+ (JSC::X86Assembler::orl_mr):
+ (JSC::X86Assembler::orl_i32r):
+ (JSC::X86Assembler::subl_rr):
+ (JSC::X86Assembler::subl_i8r):
+ (JSC::X86Assembler::subl_i8m):
+ (JSC::X86Assembler::subl_i32r):
+ (JSC::X86Assembler::subl_mr):
+ (JSC::X86Assembler::testl_i32r):
+ (JSC::X86Assembler::testl_i32m):
+ (JSC::X86Assembler::testl_rr):
+ (JSC::X86Assembler::xorl_i8r):
+ (JSC::X86Assembler::xorl_rr):
+ (JSC::X86Assembler::sarl_i8r):
+ (JSC::X86Assembler::sarl_CLr):
+ (JSC::X86Assembler::shl_i8r):
+ (JSC::X86Assembler::shll_CLr):
+ (JSC::X86Assembler::imull_rr):
+ (JSC::X86Assembler::imull_i32r):
+ (JSC::X86Assembler::idivl_r):
+ (JSC::X86Assembler::negl_r):
+ (JSC::X86Assembler::movl_mr):
+ (JSC::X86Assembler::movzbl_rr):
+ (JSC::X86Assembler::movzwl_mr):
+ (JSC::X86Assembler::movl_rm):
+ (JSC::X86Assembler::movl_i32r):
+ (JSC::X86Assembler::movl_i32m):
+ (JSC::X86Assembler::leal_mr):
+ (JSC::X86Assembler::jmp_r):
+ (JSC::X86Assembler::jmp_m):
+ (JSC::X86Assembler::movsd_mr):
+ (JSC::X86Assembler::xorpd_mr):
+ (JSC::X86Assembler::movsd_rm):
+ (JSC::X86Assembler::movd_rr):
+ (JSC::X86Assembler::cvtsi2sd_rr):
+ (JSC::X86Assembler::cvttsd2si_rr):
+ (JSC::X86Assembler::addsd_mr):
+ (JSC::X86Assembler::subsd_mr):
+ (JSC::X86Assembler::mulsd_mr):
+ (JSC::X86Assembler::addsd_rr):
+ (JSC::X86Assembler::subsd_rr):
+ (JSC::X86Assembler::mulsd_rr):
+ (JSC::X86Assembler::ucomis_rr):
+ (JSC::X86Assembler::pextrw_irr):
+ (JSC::X86Assembler::call):
+ (JSC::X86Assembler::jmp):
+ (JSC::X86Assembler::jne):
+ (JSC::X86Assembler::jnz):
+ (JSC::X86Assembler::je):
+ (JSC::X86Assembler::jl):
+ (JSC::X86Assembler::jb):
+ (JSC::X86Assembler::jle):
+ (JSC::X86Assembler::jbe):
+ (JSC::X86Assembler::jge):
+ (JSC::X86Assembler::jg):
+ (JSC::X86Assembler::ja):
+ (JSC::X86Assembler::jae):
+ (JSC::X86Assembler::jo):
+ (JSC::X86Assembler::jp):
+ (JSC::X86Assembler::js):
+ (JSC::X86Assembler::predictNotTaken):
+ (JSC::X86Assembler::convertToFastCall):
+ (JSC::X86Assembler::restoreArgumentReference):
+ (JSC::X86Assembler::restoreArgumentReferenceForTrampoline):
+ (JSC::X86Assembler::modRm_rr):
+ (JSC::X86Assembler::modRm_rr_Unchecked):
+ (JSC::X86Assembler::modRm_rm):
+ (JSC::X86Assembler::modRm_rm_Unchecked):
+ (JSC::X86Assembler::modRm_rmsib):
+ (JSC::X86Assembler::modRm_opr):
+ (JSC::X86Assembler::modRm_opr_Unchecked):
+ (JSC::X86Assembler::modRm_opm):
+ (JSC::X86Assembler::modRm_opm_Unchecked):
+ (JSC::X86Assembler::modRm_opmsib):
+ * jit/JIT.cpp:
+ (JSC::JIT::emitNakedCall):
+ (JSC::JIT::emitNakedFastCall):
+ (JSC::JIT::emitCTICall):
+ (JSC::JIT::emitJumpSlowCaseIfNotJSCell):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmNum):
+ (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::JIT::emitFastArithIntToImmOrSlowCase):
+ (JSC::JIT::emitArithIntToImmWithJump):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emitSlowScriptCheck):
+ (JSC::JIT::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::JIT::compileBinaryArithOp):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateBackreferenceQuantifier):
+ (JSC::WREC::Generator::generateNonGreedyQuantifier):
+ (JSC::WREC::Generator::generateGreedyQuantifier):
+ (JSC::WREC::Generator::generatePatternCharacter):
+ (JSC::WREC::Generator::generateCharacterClassInvertedRange):
+ (JSC::WREC::Generator::generateCharacterClassInverted):
+ (JSC::WREC::Generator::generateCharacterClass):
+ (JSC::WREC::Generator::generateParentheses):
+ (JSC::WREC::Generator::generateParenthesesNonGreedy):
+ (JSC::WREC::Generator::generateParenthesesResetTrampoline):
+ (JSC::WREC::Generator::generateAssertionBOL):
+ (JSC::WREC::Generator::generateAssertionEOL):
+ (JSC::WREC::Generator::generateAssertionWordBoundary):
+ (JSC::WREC::Generator::generateBackreference):
+ (JSC::WREC::Generator::generateDisjunction):
+
+2008-11-19 Simon Hausmann <hausmann@webkit.org>
+
+ Sun CC build fix, removed trailing comman for last enum value.
+
+ * wtf/unicode/qt4/UnicodeQt4.h:
+ (WTF::Unicode::):
+
+2008-11-19 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Expand the workaround for Apple GCC compiler bug <rdar://problem/6354696> to all versions of GCC 4.0.1.
+ It has been observed with builds 5465 (Xcode 3.0) and 5484 (Xcode 3.1), and there is no evidence
+ that it has been fixed in newer builds of GCC 4.0.1.
+
+ This addresses <https://bugs.webkit.org/show_bug.cgi?id=22351> (WebKit nightly crashes on launch on 10.4.11).
+
+ * wtf/StdLibExtras.h:
+
+2008-11-18 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Maciej Stachowiak and Geoff Garen.
+
+ Bug 22287: ASSERTION FAILED: Not enough jumps linked in slow case codegen in CTI::privateCompileSlowCases())
+ <https://bugs.webkit.org/show_bug.cgi?id=22287>
+
+ Fix a typo in the number cell reuse code where the first and second
+ operands are sometimes confused.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+
+2008-11-18 Dan Bernstein <mitz@apple.com>
+
+ - try to fix the Windows build
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2008-11-18 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Minor RegExp cleanup.
+
+ SunSpider says no change.
+
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::match): Renamed "regExpObj" to "regExpConstructor".
+
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp): Instead of checking for a NULL output vector,
+ ASSERT that the output vector is not NULL. (The rest of WREC is not
+ safe to use with a NULL output vector, and we probably don't want to
+ spend the time and/or performance to make it safe.)
+
+2008-11-18 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ A little more renaming and refactoring.
+
+ VM_CHECK_EXCEPTION() => CHECK_FOR_EXCEPTION().
+ NEXT_INSTRUCTION => NEXT_INSTRUCTION().
+
+ Removed the "Error_" and "TempError_" prefixes from WREC error types.
+
+ Refactored the WREC parser so it doesn't need a "setError" function,
+ and changed "isEndOfPattern" and its use -- they read kind of backwards
+ before.
+
+ Changed our "TODO:" error messages at least to say something, since you
+ can't say "TODO:" in shipping software.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::cti_op_convert_this):
+ (JSC::Interpreter::cti_op_add):
+ (JSC::Interpreter::cti_op_pre_inc):
+ (JSC::Interpreter::cti_op_loop_if_less):
+ (JSC::Interpreter::cti_op_loop_if_lesseq):
+ (JSC::Interpreter::cti_op_put_by_id):
+ (JSC::Interpreter::cti_op_put_by_id_second):
+ (JSC::Interpreter::cti_op_put_by_id_generic):
+ (JSC::Interpreter::cti_op_put_by_id_fail):
+ (JSC::Interpreter::cti_op_get_by_id):
+ (JSC::Interpreter::cti_op_get_by_id_second):
+ (JSC::Interpreter::cti_op_get_by_id_generic):
+ (JSC::Interpreter::cti_op_get_by_id_fail):
+ (JSC::Interpreter::cti_op_instanceof):
+ (JSC::Interpreter::cti_op_del_by_id):
+ (JSC::Interpreter::cti_op_mul):
+ (JSC::Interpreter::cti_op_call_NotJSFunction):
+ (JSC::Interpreter::cti_op_resolve):
+ (JSC::Interpreter::cti_op_construct_NotJSConstruct):
+ (JSC::Interpreter::cti_op_get_by_val):
+ (JSC::Interpreter::cti_op_resolve_func):
+ (JSC::Interpreter::cti_op_sub):
+ (JSC::Interpreter::cti_op_put_by_val):
+ (JSC::Interpreter::cti_op_put_by_val_array):
+ (JSC::Interpreter::cti_op_lesseq):
+ (JSC::Interpreter::cti_op_loop_if_true):
+ (JSC::Interpreter::cti_op_negate):
+ (JSC::Interpreter::cti_op_resolve_skip):
+ (JSC::Interpreter::cti_op_resolve_global):
+ (JSC::Interpreter::cti_op_div):
+ (JSC::Interpreter::cti_op_pre_dec):
+ (JSC::Interpreter::cti_op_jless):
+ (JSC::Interpreter::cti_op_not):
+ (JSC::Interpreter::cti_op_jtrue):
+ (JSC::Interpreter::cti_op_post_inc):
+ (JSC::Interpreter::cti_op_eq):
+ (JSC::Interpreter::cti_op_lshift):
+ (JSC::Interpreter::cti_op_bitand):
+ (JSC::Interpreter::cti_op_rshift):
+ (JSC::Interpreter::cti_op_bitnot):
+ (JSC::Interpreter::cti_op_resolve_with_base):
+ (JSC::Interpreter::cti_op_mod):
+ (JSC::Interpreter::cti_op_less):
+ (JSC::Interpreter::cti_op_neq):
+ (JSC::Interpreter::cti_op_post_dec):
+ (JSC::Interpreter::cti_op_urshift):
+ (JSC::Interpreter::cti_op_bitxor):
+ (JSC::Interpreter::cti_op_bitor):
+ (JSC::Interpreter::cti_op_push_scope):
+ (JSC::Interpreter::cti_op_to_jsnumber):
+ (JSC::Interpreter::cti_op_in):
+ (JSC::Interpreter::cti_op_del_by_val):
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp):
+ * wrec/WRECParser.cpp:
+ (JSC::WREC::Parser::parseGreedyQuantifier):
+ (JSC::WREC::Parser::parseParentheses):
+ (JSC::WREC::Parser::parseCharacterClass):
+ (JSC::WREC::Parser::parseEscape):
+ * wrec/WRECParser.h:
+ (JSC::WREC::Parser::):
+ (JSC::WREC::Parser::atEndOfPattern):
+
+2008-11-18 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22337
+ Enable workers by default
+
+ * Configurations/JavaScriptCore.xcconfig: Define ENABLE_WORKERS.
+
+2008-11-18 Alexey Proskuryakov <ap@webkit.org>
+
+ - Windows build fix
+
+ * wrec/WRECFunctors.h:
+ * wrec/WRECGenerator.h:
+ * wrec/WRECParser.h:
+ CharacterClass is a struct, not a class, fix forward declarations.
+
+2008-11-18 Dan Bernstein <mitz@apple.com>
+
+ - Windows build fix
+
+ * assembler/X86Assembler.h:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix gtk build.
+
+ * wrec/Quantifier.h:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix gtk build.
+
+ * assembler/AssemblerBuffer.h:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Split WREC classes out into individual files, with a few modifications
+ to more closely match the WebKit coding style.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/X86Assembler.h:
+ * runtime/RegExp.cpp:
+ * wrec/CharacterClass.cpp: Copied from wrec/CharacterClassConstructor.cpp.
+ (JSC::WREC::CharacterClass::newline):
+ (JSC::WREC::CharacterClass::digits):
+ (JSC::WREC::CharacterClass::spaces):
+ (JSC::WREC::CharacterClass::wordchar):
+ (JSC::WREC::CharacterClass::nondigits):
+ (JSC::WREC::CharacterClass::nonspaces):
+ (JSC::WREC::CharacterClass::nonwordchar):
+ * wrec/CharacterClass.h: Copied from wrec/CharacterClassConstructor.h.
+ * wrec/CharacterClassConstructor.cpp:
+ (JSC::WREC::CharacterClassConstructor::addSortedRange):
+ (JSC::WREC::CharacterClassConstructor::append):
+ * wrec/CharacterClassConstructor.h:
+ * wrec/Quantifier.h: Copied from wrec/WREC.h.
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp):
+ * wrec/WREC.h:
+ * wrec/WRECFunctors.cpp: Copied from wrec/WREC.cpp.
+ * wrec/WRECFunctors.h: Copied from wrec/WREC.cpp.
+ (JSC::WREC::GenerateAtomFunctor::~GenerateAtomFunctor):
+ (JSC::WREC::GeneratePatternCharacterFunctor::GeneratePatternCharacterFunctor):
+ (JSC::WREC::GenerateCharacterClassFunctor::GenerateCharacterClassFunctor):
+ (JSC::WREC::GenerateBackreferenceFunctor::GenerateBackreferenceFunctor):
+ (JSC::WREC::GenerateParenthesesNonGreedyFunctor::GenerateParenthesesNonGreedyFunctor):
+ * wrec/WRECGenerator.cpp: Copied from wrec/WREC.cpp.
+ (JSC::WREC::Generator::generatePatternCharacter):
+ (JSC::WREC::Generator::generateCharacterClassInvertedRange):
+ (JSC::WREC::Generator::generateCharacterClassInverted):
+ (JSC::WREC::Generator::generateCharacterClass):
+ (JSC::WREC::Generator::generateParentheses):
+ (JSC::WREC::Generator::generateAssertionBOL):
+ (JSC::WREC::Generator::generateAssertionEOL):
+ (JSC::WREC::Generator::generateAssertionWordBoundary):
+ * wrec/WRECGenerator.h: Copied from wrec/WREC.h.
+ * wrec/WRECParser.cpp: Copied from wrec/WREC.cpp.
+ (JSC::WREC::Parser::parseGreedyQuantifier):
+ (JSC::WREC::Parser::parseCharacterClassQuantifier):
+ (JSC::WREC::Parser::parseParentheses):
+ (JSC::WREC::Parser::parseCharacterClass):
+ (JSC::WREC::Parser::parseEscape):
+ (JSC::WREC::Parser::parseTerm):
+ * wrec/WRECParser.h: Copied from wrec/WREC.h.
+ (JSC::WREC::Parser::):
+ (JSC::WREC::Parser::Parser):
+ (JSC::WREC::Parser::setError):
+ (JSC::WREC::Parser::error):
+ (JSC::WREC::Parser::recordSubpattern):
+ (JSC::WREC::Parser::numSubpatterns):
+ (JSC::WREC::Parser::ignoreCase):
+ (JSC::WREC::Parser::multiline):
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix a few builds.
+
+ * JavaScriptCoreSources.bkl:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix a few builds.
+
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved VM/CTI.* => jit/JIT.*.
+
+ Removed VM.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * VM/CTI.cpp: Removed.
+ * VM/CTI.h: Removed.
+ * bytecode/CodeBlock.cpp:
+ * interpreter/Interpreter.cpp:
+ * jit: Added.
+ * jit/JIT.cpp: Copied from VM/CTI.cpp.
+ * jit/JIT.h: Copied from VM/CTI.h.
+ * runtime/RegExp.cpp:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved runtime/ExecState.* => interpreter/CallFrame.*.
+
+ * API/JSBase.cpp:
+ * API/OpaqueJSString.cpp:
+ * GNUmakefile.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * debugger/DebuggerCallFrame.h:
+ * interpreter/CallFrame.cpp: Copied from runtime/ExecState.cpp.
+ * interpreter/CallFrame.h: Copied from runtime/ExecState.h.
+ * interpreter/Interpreter.cpp:
+ * parser/Nodes.cpp:
+ * profiler/ProfileGenerator.cpp:
+ * profiler/Profiler.cpp:
+ * runtime/ClassInfo.h:
+ * runtime/Collector.cpp:
+ * runtime/Completion.cpp:
+ * runtime/ExceptionHelpers.cpp:
+ * runtime/ExecState.cpp: Removed.
+ * runtime/ExecState.h: Removed.
+ * runtime/Identifier.cpp:
+ * runtime/JSFunction.cpp:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ * runtime/JSLock.cpp:
+ * runtime/JSNumberCell.h:
+ * runtime/JSObject.h:
+ * runtime/JSString.h:
+ * runtime/Lookup.h:
+ * runtime/PropertyNameArray.h:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * API/APICast.h:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * API/APICast.h:
+ * runtime/ExecState.h:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved VM/SamplingTool.* => bytecode/SamplingTool.*.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * VM/SamplingTool.cpp: Removed.
+ * VM/SamplingTool.h: Removed.
+ * bytecode/SamplingTool.cpp: Copied from VM/SamplingTool.cpp.
+ * bytecode/SamplingTool.h: Copied from VM/SamplingTool.h.
+ * jsc.cpp:
+ (runWithScripts):
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * runtime/ExecState.h:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved VM/ExceptionHelpers.cpp => runtime/ExceptionHelpers.cpp.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * VM/ExceptionHelpers.cpp: Removed.
+ * runtime/ExceptionHelpers.cpp: Copied from VM/ExceptionHelpers.cpp.
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved VM/RegisterFile.cpp => interpreter/RegisterFile.cpp.
+
+ * AllInOneFile.cpp:
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * VM/RegisterFile.cpp: Removed.
+ * interpreter/RegisterFile.cpp: Copied from VM/RegisterFile.cpp.
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved:
+ VM/ExceptionHelpers.h => runtime/ExceptionHelpers.h
+ VM/Register.h => interpreter/Register.h
+ VM/RegisterFile.h => interpreter/RegisterFile.h
+
+
+ * GNUmakefile.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * VM/ExceptionHelpers.h: Removed.
+ * VM/Register.h: Removed.
+ * VM/RegisterFile.h: Removed.
+ * interpreter/Register.h: Copied from VM/Register.h.
+ * interpreter/RegisterFile.h: Copied from VM/RegisterFile.h.
+ * runtime/ExceptionHelpers.h: Copied from VM/ExceptionHelpers.h.
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Qt build.
+
+ * JavaScriptCore.pri:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved VM/Machine.cpp => interpreter/Interpreter.cpp.
+
+ * DerivedSources.make:
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * VM/Machine.cpp: Removed.
+ * interpreter/Interpreter.cpp: Copied from VM/Machine.cpp.
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved VM/Machine.h => interpreter/Interpreter.h
+
+ * GNUmakefile.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * VM/CTI.cpp:
+ * VM/CTI.h:
+ * VM/ExceptionHelpers.cpp:
+ * VM/Machine.cpp:
+ * VM/Machine.h: Removed.
+ * VM/SamplingTool.cpp:
+ * bytecode/CodeBlock.cpp:
+ * bytecompiler/BytecodeGenerator.cpp:
+ * bytecompiler/BytecodeGenerator.h:
+ * debugger/DebuggerCallFrame.cpp:
+ * interpreter: Added.
+ * interpreter/Interpreter.h: Copied from VM/Machine.h.
+ * profiler/ProfileGenerator.cpp:
+ * runtime/Arguments.h:
+ * runtime/ArrayPrototype.cpp:
+ * runtime/Collector.cpp:
+ * runtime/Completion.cpp:
+ * runtime/ExecState.h:
+ * runtime/FunctionPrototype.cpp:
+ * runtime/JSActivation.cpp:
+ * runtime/JSFunction.cpp:
+ * runtime/JSGlobalData.cpp:
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ * wrec/WREC.cpp:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved runtime/Interpreter.cpp => runtime/Completion.cpp.
+
+ Moved functions from Interpreter.h to Completion.h, and removed
+ Interpreter.h from the project.
+
+ * API/JSBase.cpp:
+ * AllInOneFile.cpp:
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * jsc.cpp:
+ * runtime/Completion.cpp: Copied from runtime/Interpreter.cpp.
+ * runtime/Completion.h:
+ * runtime/Interpreter.cpp: Removed.
+ * runtime/Interpreter.h: Removed.
+
+2008-11-17 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Darin Adler.
+
+ <https://bugs.webkit.org/show_bug.cgi?id=22312>
+ Fix PCRE include path problem on Qt-port
+
+ * JavaScriptCore.pri:
+ * pcre/pcre.pri:
+
+2008-11-17 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Darin Adler.
+
+ <https://bugs.webkit.org/show_bug.cgi?id=22313>
+ Add missing CTI source to the build system on Qt-port
+
+ * JavaScriptCore.pri:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix JSGlue build.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Qt build.
+
+ * jsc.pro:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Qt build.
+
+ * JavaScriptCore.pri:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Qt build.
+
+ * JavaScriptCore.pri:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ More file moves:
+
+ VM/CodeBlock.* => bytecode/CodeBlock.*
+ VM/EvalCodeCache.h => bytecode/EvalCodeCache.h
+ VM/Instruction.h => bytecode/Instruction.h
+ VM/Opcode.* => bytecode/Opcode.*
+
+ * GNUmakefile.am:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * VM/CodeBlock.cpp: Removed.
+ * VM/CodeBlock.h: Removed.
+ * VM/EvalCodeCache.h: Removed.
+ * VM/Instruction.h: Removed.
+ * VM/Opcode.cpp: Removed.
+ * VM/Opcode.h: Removed.
+ * bytecode: Added.
+ * bytecode/CodeBlock.cpp: Copied from VM/CodeBlock.cpp.
+ * bytecode/CodeBlock.h: Copied from VM/CodeBlock.h.
+ * bytecode/EvalCodeCache.h: Copied from VM/EvalCodeCache.h.
+ * bytecode/Instruction.h: Copied from VM/Instruction.h.
+ * bytecode/Opcode.cpp: Copied from VM/Opcode.cpp.
+ * bytecode/Opcode.h: Copied from VM/Opcode.h.
+ * jsc.pro:
+ * jscore.bkl:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix a few more builds.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCoreSources.bkl:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix gtk build.
+
+ * GNUmakefile.am:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Some file moves:
+
+ VM/LabelID.h => bytecompiler/Label.h
+ VM/RegisterID.h => bytecompiler/RegisterID.h
+ VM/SegmentedVector.h => bytecompiler/SegmentedVector.h
+ bytecompiler/CodeGenerator.* => bytecompiler/BytecodeGenerator.*
+
+ * AllInOneFile.cpp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * VM/LabelID.h: Removed.
+ * VM/RegisterID.h: Removed.
+ * VM/SegmentedVector.h: Removed.
+ * bytecompiler/BytecodeGenerator.cpp: Copied from bytecompiler/CodeGenerator.cpp.
+ * bytecompiler/BytecodeGenerator.h: Copied from bytecompiler/CodeGenerator.h.
+ * bytecompiler/CodeGenerator.cpp: Removed.
+ * bytecompiler/CodeGenerator.h: Removed.
+ * bytecompiler/Label.h: Copied from VM/LabelID.h.
+ * bytecompiler/LabelScope.h:
+ * bytecompiler/RegisterID.h: Copied from VM/RegisterID.h.
+ * bytecompiler/SegmentedVector.h: Copied from VM/SegmentedVector.h.
+ * jsc.cpp:
+ * parser/Nodes.cpp:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2008-11-17 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved masm => assembler and split "AssemblerBuffer.h" out of "X86Assembler.h".
+
+ Also renamed ENABLE_MASM to ENABLE_ASSEMBLER.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler: Added.
+ * assembler/AssemblerBuffer.h: Copied from masm/X86Assembler.h.
+ (JSC::AssemblerBuffer::AssemblerBuffer):
+ (JSC::AssemblerBuffer::~AssemblerBuffer):
+ (JSC::AssemblerBuffer::ensureSpace):
+ (JSC::AssemblerBuffer::isAligned):
+ (JSC::AssemblerBuffer::putByteUnchecked):
+ (JSC::AssemblerBuffer::putByte):
+ (JSC::AssemblerBuffer::putShortUnchecked):
+ (JSC::AssemblerBuffer::putShort):
+ (JSC::AssemblerBuffer::putIntUnchecked):
+ (JSC::AssemblerBuffer::putInt):
+ (JSC::AssemblerBuffer::data):
+ (JSC::AssemblerBuffer::size):
+ (JSC::AssemblerBuffer::reset):
+ (JSC::AssemblerBuffer::executableCopy):
+ (JSC::AssemblerBuffer::grow):
+ * assembler/X86Assembler.h: Copied from masm/X86Assembler.h.
+ * masm: Removed.
+ * masm/X86Assembler.h: Removed.
+ * wtf/Platform.h:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix gtk build.
+
+ * GNUmakefile.am:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Fixed tyop.
+
+ * VM/CTI.cpp:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix windows build.
+
+ * VM/CTI.cpp:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix gtk build.
+
+ * GNUmakefile.am:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed ENABLE_CTI and ENABLE(CTI) to ENABLE_JIT and ENABLE(JIT).
+
+ * VM/CTI.cpp:
+ * VM/CTI.h:
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::~CodeBlock):
+ * VM/CodeBlock.h:
+ (JSC::CodeBlock::CodeBlock):
+ * VM/Machine.cpp:
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::initialize):
+ (JSC::Interpreter::~Interpreter):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::privateExecute):
+ * VM/Machine.h:
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::prepareJumpTableForStringSwitch):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::~JSFunction):
+ * runtime/JSGlobalData.h:
+ * wrec/WREC.h:
+ * wtf/Platform.h:
+ * wtf/TCSystemAlloc.cpp:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix gtk build.
+
+ * VM/CTI.cpp:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by a few people on squirrelfish-dev.
+
+ Renamed CTI => JIT.
+
+ * VM/CTI.cpp:
+ (JSC::JIT::killLastResultRegister):
+ (JSC::JIT::emitGetVirtualRegister):
+ (JSC::JIT::emitGetVirtualRegisters):
+ (JSC::JIT::emitPutCTIArgFromVirtualRegister):
+ (JSC::JIT::emitPutCTIArg):
+ (JSC::JIT::emitGetCTIArg):
+ (JSC::JIT::emitPutCTIArgConstant):
+ (JSC::JIT::getConstantImmediateNumericArg):
+ (JSC::JIT::emitPutCTIParam):
+ (JSC::JIT::emitGetCTIParam):
+ (JSC::JIT::emitPutToCallFrameHeader):
+ (JSC::JIT::emitGetFromCallFrameHeader):
+ (JSC::JIT::emitPutVirtualRegister):
+ (JSC::JIT::emitInitRegister):
+ (JSC::JIT::printBytecodeOperandTypes):
+ (JSC::JIT::emitAllocateNumber):
+ (JSC::JIT::emitNakedCall):
+ (JSC::JIT::emitNakedFastCall):
+ (JSC::JIT::emitCTICall):
+ (JSC::JIT::emitJumpSlowCaseIfNotJSCell):
+ (JSC::JIT::linkSlowCaseIfNotJSCell):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmNum):
+ (JSC::JIT::emitJumpSlowCaseIfNotImmNums):
+ (JSC::JIT::getDeTaggedConstantImmediate):
+ (JSC::JIT::emitFastArithDeTagImmediate):
+ (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::JIT::emitFastArithReTagImmediate):
+ (JSC::JIT::emitFastArithPotentiallyReTagImmediate):
+ (JSC::JIT::emitFastArithImmToInt):
+ (JSC::JIT::emitFastArithIntToImmOrSlowCase):
+ (JSC::JIT::emitFastArithIntToImmNoCheck):
+ (JSC::JIT::emitArithIntToImmWithJump):
+ (JSC::JIT::emitTagAsBoolImmediate):
+ (JSC::JIT::JIT):
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCallSetupArgs):
+ (JSC::JIT::compileOpCallEvalSetupArgs):
+ (JSC::JIT::compileOpConstructSetupArgs):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emitSlowScriptCheck):
+ (JSC::JIT::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::JIT::compileBinaryArithOp):
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileLinkPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::unlinkCall):
+ (JSC::JIT::linkCall):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::freeCTIMachineTrampolines):
+ (JSC::JIT::patchGetByIdSelf):
+ (JSC::JIT::patchPutByIdReplace):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::emitGetVariableObjectRegister):
+ (JSC::JIT::emitPutVariableObjectRegister):
+ * VM/CTI.h:
+ (JSC::JIT::compile):
+ (JSC::JIT::compileGetByIdSelf):
+ (JSC::JIT::compileGetByIdProto):
+ (JSC::JIT::compileGetByIdChain):
+ (JSC::JIT::compilePutByIdReplace):
+ (JSC::JIT::compilePutByIdTransition):
+ (JSC::JIT::compileCTIMachineTrampolines):
+ (JSC::JIT::compilePatchGetArrayLength):
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::unlinkCallers):
+ * VM/Machine.cpp:
+ (JSC::Interpreter::initialize):
+ (JSC::Interpreter::~Interpreter):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::tryCTICachePutByID):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::Interpreter::cti_op_call_JSFunction):
+ (JSC::Interpreter::cti_vm_dontLazyLinkCall):
+ (JSC::Interpreter::cti_vm_lazyLinkCall):
+ * VM/Machine.h:
+ * VM/RegisterFile.h:
+ * parser/Nodes.h:
+ * runtime/JSArray.h:
+ * runtime/JSCell.h:
+ * runtime/JSFunction.h:
+ * runtime/JSImmediate.h:
+ * runtime/JSNumberCell.h:
+ * runtime/JSObject.h:
+ * runtime/JSString.h:
+ * runtime/JSVariableObject.h:
+ * runtime/ScopeChain.h:
+ * runtime/Structure.h:
+ * runtime/TypeInfo.h:
+ * runtime/UString.h:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix wx build.
+
+ * jscore.bkl:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Nixed X86:: and X86Assembler:: prefixes in a lot of places using typedefs.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitGetVirtualRegister):
+ (JSC::CTI::emitGetVirtualRegisters):
+ (JSC::CTI::emitPutCTIArgFromVirtualRegister):
+ (JSC::CTI::emitPutCTIArg):
+ (JSC::CTI::emitGetCTIArg):
+ (JSC::CTI::emitPutCTIParam):
+ (JSC::CTI::emitGetCTIParam):
+ (JSC::CTI::emitPutToCallFrameHeader):
+ (JSC::CTI::emitGetFromCallFrameHeader):
+ (JSC::CTI::emitPutVirtualRegister):
+ (JSC::CTI::emitNakedCall):
+ (JSC::CTI::emitNakedFastCall):
+ (JSC::CTI::emitCTICall):
+ (JSC::CTI::emitJumpSlowCaseIfNotJSCell):
+ (JSC::CTI::emitJumpSlowCaseIfNotImmNum):
+ (JSC::CTI::emitJumpSlowCaseIfNotImmNums):
+ (JSC::CTI::emitFastArithDeTagImmediate):
+ (JSC::CTI::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::CTI::emitFastArithReTagImmediate):
+ (JSC::CTI::emitFastArithPotentiallyReTagImmediate):
+ (JSC::CTI::emitFastArithImmToInt):
+ (JSC::CTI::emitFastArithIntToImmOrSlowCase):
+ (JSC::CTI::emitFastArithIntToImmNoCheck):
+ (JSC::CTI::emitArithIntToImmWithJump):
+ (JSC::CTI::emitTagAsBoolImmediate):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::compileOpStrictEq):
+ (JSC::CTI::emitSlowScriptCheck):
+ (JSC::CTI::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::compileBinaryArithOpSlowCase):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompile):
+ (JSC::CTI::privateCompileGetByIdSelf):
+ (JSC::CTI::privateCompileGetByIdProto):
+ (JSC::CTI::privateCompileGetByIdChain):
+ (JSC::CTI::privateCompilePutByIdReplace):
+ (JSC::CTI::privateCompilePutByIdTransition):
+ (JSC::CTI::privateCompileCTIMachineTrampolines):
+ (JSC::CTI::privateCompilePatchGetArrayLength):
+ (JSC::CTI::emitGetVariableObjectRegister):
+ (JSC::CTI::emitPutVariableObjectRegister):
+ * VM/CTI.h:
+ (JSC::CallRecord::CallRecord):
+ (JSC::JmpTable::JmpTable):
+ (JSC::SlowCaseEntry::SlowCaseEntry):
+ (JSC::CTI::JSRInfo::JSRInfo):
+ * wrec/WREC.h:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Try to fix Qt build.
+
+ * JavaScriptCore.pri:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed OBJECT_OFFSET => FIELD_OFFSET
+
+ Nixed use of OBJECT_OFFSET outside of CTI.cpp by making CTI a friend in
+ more places.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::compileOpCallInitializeCallFrame):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::emitSlowScriptCheck):
+ (JSC::CTI::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompile):
+ (JSC::CTI::privateCompileGetByIdSelf):
+ (JSC::CTI::privateCompileGetByIdProto):
+ (JSC::CTI::privateCompileGetByIdChain):
+ (JSC::CTI::privateCompilePutByIdReplace):
+ (JSC::CTI::privateCompilePutByIdTransition):
+ (JSC::CTI::privateCompileCTIMachineTrampolines):
+ (JSC::CTI::privateCompilePatchGetArrayLength):
+ (JSC::CTI::emitGetVariableObjectRegister):
+ (JSC::CTI::emitPutVariableObjectRegister):
+ * runtime/JSValue.h:
+ * runtime/JSVariableObject.h:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renames:
+
+ X86Assembler::copy => X86Assembler::executableCopy
+ AssemblerBuffer::copy => AssemblerBuffer::executableCopy
+
+ * VM/CTI.cpp:
+ (JSC::CTI::privateCompile):
+ (JSC::CTI::privateCompileGetByIdSelf):
+ (JSC::CTI::privateCompileGetByIdProto):
+ (JSC::CTI::privateCompileGetByIdChain):
+ (JSC::CTI::privateCompilePutByIdReplace):
+ (JSC::CTI::privateCompilePutByIdTransition):
+ (JSC::CTI::privateCompileCTIMachineTrampolines):
+ (JSC::CTI::privateCompilePatchGetArrayLength):
+ * masm/X86Assembler.h:
+ (JSC::AssemblerBuffer::executableCopy):
+ (JSC::X86Assembler::executableCopy):
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp):
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed WREC => JSC::WREC, removing JSC:: prefix in a lot of places.
+ Renamed WRECFunction => WREC::CompiledRegExp, and deployed this type
+ name in place of a few casts.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ (JSC::RegExp::~RegExp):
+ (JSC::RegExp::match):
+ * runtime/RegExp.h:
+ * wrec/CharacterClassConstructor.cpp:
+ * wrec/CharacterClassConstructor.h:
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp):
+ * wrec/WREC.h:
+ (JSC::WREC::Generator::Generator):
+ (JSC::WREC::Parser::Parser):
+ (JSC::WREC::Parser::parseAlternative):
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed BytecodeInterpreter => Interpreter.
+
+ * JavaScriptCore.exp:
+ * VM/CTI.cpp:
+ (JSC::):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::emitSlowScriptCheck):
+ (JSC::CTI::compileBinaryArithOpSlowCase):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompile):
+ (JSC::CTI::privateCompileGetByIdSelf):
+ (JSC::CTI::privateCompileGetByIdProto):
+ (JSC::CTI::privateCompileGetByIdChain):
+ (JSC::CTI::privateCompilePutByIdReplace):
+ (JSC::CTI::privateCompilePutByIdTransition):
+ (JSC::CTI::privateCompileCTIMachineTrampolines):
+ (JSC::CTI::freeCTIMachineTrampolines):
+ (JSC::CTI::patchGetByIdSelf):
+ (JSC::CTI::patchPutByIdReplace):
+ (JSC::CTI::privateCompilePatchGetArrayLength):
+ * VM/CTI.h:
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::derefStructures):
+ (JSC::CodeBlock::refStructures):
+ * VM/Machine.cpp:
+ (JSC::jsLess):
+ (JSC::jsLessEq):
+ (JSC::Interpreter::resolve):
+ (JSC::Interpreter::resolveSkip):
+ (JSC::Interpreter::resolveGlobal):
+ (JSC::Interpreter::resolveBase):
+ (JSC::Interpreter::resolveBaseAndProperty):
+ (JSC::Interpreter::resolveBaseAndFunc):
+ (JSC::Interpreter::slideRegisterWindowForCall):
+ (JSC::Interpreter::callEval):
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::initialize):
+ (JSC::Interpreter::~Interpreter):
+ (JSC::Interpreter::dumpCallFrame):
+ (JSC::Interpreter::dumpRegisters):
+ (JSC::Interpreter::isOpcode):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::debug):
+ (JSC::Interpreter::resetTimeoutCheck):
+ (JSC::Interpreter::checkTimeout):
+ (JSC::Interpreter::createExceptionScope):
+ (JSC::Interpreter::tryCachePutByID):
+ (JSC::Interpreter::uncachePutByID):
+ (JSC::Interpreter::tryCacheGetByID):
+ (JSC::Interpreter::uncacheGetByID):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::retrieveArguments):
+ (JSC::Interpreter::retrieveCaller):
+ (JSC::Interpreter::retrieveLastCaller):
+ (JSC::Interpreter::findFunctionCallFrame):
+ (JSC::Interpreter::tryCTICachePutByID):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::Interpreter::cti_op_convert_this):
+ (JSC::Interpreter::cti_op_end):
+ (JSC::Interpreter::cti_op_add):
+ (JSC::Interpreter::cti_op_pre_inc):
+ (JSC::Interpreter::cti_timeout_check):
+ (JSC::Interpreter::cti_register_file_check):
+ (JSC::Interpreter::cti_op_loop_if_less):
+ (JSC::Interpreter::cti_op_loop_if_lesseq):
+ (JSC::Interpreter::cti_op_new_object):
+ (JSC::Interpreter::cti_op_put_by_id):
+ (JSC::Interpreter::cti_op_put_by_id_second):
+ (JSC::Interpreter::cti_op_put_by_id_generic):
+ (JSC::Interpreter::cti_op_put_by_id_fail):
+ (JSC::Interpreter::cti_op_get_by_id):
+ (JSC::Interpreter::cti_op_get_by_id_second):
+ (JSC::Interpreter::cti_op_get_by_id_generic):
+ (JSC::Interpreter::cti_op_get_by_id_fail):
+ (JSC::Interpreter::cti_op_instanceof):
+ (JSC::Interpreter::cti_op_del_by_id):
+ (JSC::Interpreter::cti_op_mul):
+ (JSC::Interpreter::cti_op_new_func):
+ (JSC::Interpreter::cti_op_call_JSFunction):
+ (JSC::Interpreter::cti_op_call_arityCheck):
+ (JSC::Interpreter::cti_vm_dontLazyLinkCall):
+ (JSC::Interpreter::cti_vm_lazyLinkCall):
+ (JSC::Interpreter::cti_op_push_activation):
+ (JSC::Interpreter::cti_op_call_NotJSFunction):
+ (JSC::Interpreter::cti_op_create_arguments):
+ (JSC::Interpreter::cti_op_create_arguments_no_params):
+ (JSC::Interpreter::cti_op_tear_off_activation):
+ (JSC::Interpreter::cti_op_tear_off_arguments):
+ (JSC::Interpreter::cti_op_profile_will_call):
+ (JSC::Interpreter::cti_op_profile_did_call):
+ (JSC::Interpreter::cti_op_ret_scopeChain):
+ (JSC::Interpreter::cti_op_new_array):
+ (JSC::Interpreter::cti_op_resolve):
+ (JSC::Interpreter::cti_op_construct_JSConstruct):
+ (JSC::Interpreter::cti_op_construct_NotJSConstruct):
+ (JSC::Interpreter::cti_op_get_by_val):
+ (JSC::Interpreter::cti_op_resolve_func):
+ (JSC::Interpreter::cti_op_sub):
+ (JSC::Interpreter::cti_op_put_by_val):
+ (JSC::Interpreter::cti_op_put_by_val_array):
+ (JSC::Interpreter::cti_op_lesseq):
+ (JSC::Interpreter::cti_op_loop_if_true):
+ (JSC::Interpreter::cti_op_negate):
+ (JSC::Interpreter::cti_op_resolve_base):
+ (JSC::Interpreter::cti_op_resolve_skip):
+ (JSC::Interpreter::cti_op_resolve_global):
+ (JSC::Interpreter::cti_op_div):
+ (JSC::Interpreter::cti_op_pre_dec):
+ (JSC::Interpreter::cti_op_jless):
+ (JSC::Interpreter::cti_op_not):
+ (JSC::Interpreter::cti_op_jtrue):
+ (JSC::Interpreter::cti_op_post_inc):
+ (JSC::Interpreter::cti_op_eq):
+ (JSC::Interpreter::cti_op_lshift):
+ (JSC::Interpreter::cti_op_bitand):
+ (JSC::Interpreter::cti_op_rshift):
+ (JSC::Interpreter::cti_op_bitnot):
+ (JSC::Interpreter::cti_op_resolve_with_base):
+ (JSC::Interpreter::cti_op_new_func_exp):
+ (JSC::Interpreter::cti_op_mod):
+ (JSC::Interpreter::cti_op_less):
+ (JSC::Interpreter::cti_op_neq):
+ (JSC::Interpreter::cti_op_post_dec):
+ (JSC::Interpreter::cti_op_urshift):
+ (JSC::Interpreter::cti_op_bitxor):
+ (JSC::Interpreter::cti_op_new_regexp):
+ (JSC::Interpreter::cti_op_bitor):
+ (JSC::Interpreter::cti_op_call_eval):
+ (JSC::Interpreter::cti_op_throw):
+ (JSC::Interpreter::cti_op_get_pnames):
+ (JSC::Interpreter::cti_op_next_pname):
+ (JSC::Interpreter::cti_op_push_scope):
+ (JSC::Interpreter::cti_op_pop_scope):
+ (JSC::Interpreter::cti_op_typeof):
+ (JSC::Interpreter::cti_op_is_undefined):
+ (JSC::Interpreter::cti_op_is_boolean):
+ (JSC::Interpreter::cti_op_is_number):
+ (JSC::Interpreter::cti_op_is_string):
+ (JSC::Interpreter::cti_op_is_object):
+ (JSC::Interpreter::cti_op_is_function):
+ (JSC::Interpreter::cti_op_stricteq):
+ (JSC::Interpreter::cti_op_nstricteq):
+ (JSC::Interpreter::cti_op_to_jsnumber):
+ (JSC::Interpreter::cti_op_in):
+ (JSC::Interpreter::cti_op_push_new_scope):
+ (JSC::Interpreter::cti_op_jmp_scopes):
+ (JSC::Interpreter::cti_op_put_by_index):
+ (JSC::Interpreter::cti_op_switch_imm):
+ (JSC::Interpreter::cti_op_switch_char):
+ (JSC::Interpreter::cti_op_switch_string):
+ (JSC::Interpreter::cti_op_del_by_val):
+ (JSC::Interpreter::cti_op_put_getter):
+ (JSC::Interpreter::cti_op_put_setter):
+ (JSC::Interpreter::cti_op_new_error):
+ (JSC::Interpreter::cti_op_debug):
+ (JSC::Interpreter::cti_vm_throw):
+ * VM/Machine.h:
+ * VM/Register.h:
+ * VM/SamplingTool.h:
+ (JSC::SamplingTool::SamplingTool):
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * jsc.cpp:
+ (runWithScripts):
+ * runtime/ExecState.h:
+ (JSC::ExecState::interpreter):
+ * runtime/JSCell.h:
+ * runtime/JSFunction.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * runtime/JSString.h:
+ * wrec/WREC.cpp:
+ (WREC::compileRegExp):
+ * wrec/WREC.h:
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Roll out r38461 (my last patch) because it broke the world.
+
+2008-11-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ A few more renames:
+
+ BytecodeInterpreter => Interpreter
+ WREC => JSC::WREC, removing JSC:: prefix in a lot of places
+ X86Assembler::copy => X86Assembler::executableCopy
+ AssemblerBuffer::copy => AssemblerBuffer::executableCopy
+ WRECFunction => WREC::RegExpFunction
+ OBJECT_OFFSET => FIELD_OFFSET
+
+ Also:
+
+ Nixed use of OBJECT_OFFSET outside of CTI.cpp by making CTI a friend in more places.
+ Nixed X86:: and X86Assembler:: prefixes in a lot of places using typedefs
+
+ * JavaScriptCore.exp:
+ * VM/CTI.cpp:
+ (JSC::):
+ (JSC::CTI::emitGetVirtualRegister):
+ (JSC::CTI::emitGetVirtualRegisters):
+ (JSC::CTI::emitPutCTIArgFromVirtualRegister):
+ (JSC::CTI::emitPutCTIArg):
+ (JSC::CTI::emitGetCTIArg):
+ (JSC::CTI::emitPutCTIParam):
+ (JSC::CTI::emitGetCTIParam):
+ (JSC::CTI::emitPutToCallFrameHeader):
+ (JSC::CTI::emitGetFromCallFrameHeader):
+ (JSC::CTI::emitPutVirtualRegister):
+ (JSC::CTI::emitNakedCall):
+ (JSC::CTI::emitNakedFastCall):
+ (JSC::CTI::emitCTICall):
+ (JSC::CTI::emitJumpSlowCaseIfNotJSCell):
+ (JSC::CTI::emitJumpSlowCaseIfNotImmNum):
+ (JSC::CTI::emitJumpSlowCaseIfNotImmNums):
+ (JSC::CTI::emitFastArithDeTagImmediate):
+ (JSC::CTI::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::CTI::emitFastArithReTagImmediate):
+ (JSC::CTI::emitFastArithPotentiallyReTagImmediate):
+ (JSC::CTI::emitFastArithImmToInt):
+ (JSC::CTI::emitFastArithIntToImmOrSlowCase):
+ (JSC::CTI::emitFastArithIntToImmNoCheck):
+ (JSC::CTI::emitArithIntToImmWithJump):
+ (JSC::CTI::emitTagAsBoolImmediate):
+ (JSC::CTI::compileOpCallInitializeCallFrame):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::compileOpStrictEq):
+ (JSC::CTI::emitSlowScriptCheck):
+ (JSC::CTI::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::compileBinaryArithOpSlowCase):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompile):
+ (JSC::CTI::privateCompileGetByIdSelf):
+ (JSC::CTI::privateCompileGetByIdProto):
+ (JSC::CTI::privateCompileGetByIdChain):
+ (JSC::CTI::privateCompilePutByIdReplace):
+ (JSC::CTI::privateCompilePutByIdTransition):
+ (JSC::CTI::privateCompileCTIMachineTrampolines):
+ (JSC::CTI::freeCTIMachineTrampolines):
+ (JSC::CTI::patchGetByIdSelf):
+ (JSC::CTI::patchPutByIdReplace):
+ (JSC::CTI::privateCompilePatchGetArrayLength):
+ (JSC::CTI::emitGetVariableObjectRegister):
+ (JSC::CTI::emitPutVariableObjectRegister):
+ * VM/CTI.h:
+ (JSC::CallRecord::CallRecord):
+ (JSC::JmpTable::JmpTable):
+ (JSC::SlowCaseEntry::SlowCaseEntry):
+ (JSC::CTI::JSRInfo::JSRInfo):
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::derefStructures):
+ (JSC::CodeBlock::refStructures):
+ * VM/Machine.cpp:
+ (JSC::jsLess):
+ (JSC::jsLessEq):
+ (JSC::Interpreter::resolve):
+ (JSC::Interpreter::resolveSkip):
+ (JSC::Interpreter::resolveGlobal):
+ (JSC::Interpreter::resolveBase):
+ (JSC::Interpreter::resolveBaseAndProperty):
+ (JSC::Interpreter::resolveBaseAndFunc):
+ (JSC::Interpreter::slideRegisterWindowForCall):
+ (JSC::Interpreter::callEval):
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::initialize):
+ (JSC::Interpreter::~Interpreter):
+ (JSC::Interpreter::dumpCallFrame):
+ (JSC::Interpreter::dumpRegisters):
+ (JSC::Interpreter::isOpcode):
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::debug):
+ (JSC::Interpreter::resetTimeoutCheck):
+ (JSC::Interpreter::checkTimeout):
+ (JSC::Interpreter::createExceptionScope):
+ (JSC::Interpreter::tryCachePutByID):
+ (JSC::Interpreter::uncachePutByID):
+ (JSC::Interpreter::tryCacheGetByID):
+ (JSC::Interpreter::uncacheGetByID):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::retrieveArguments):
+ (JSC::Interpreter::retrieveCaller):
+ (JSC::Interpreter::retrieveLastCaller):
+ (JSC::Interpreter::findFunctionCallFrame):
+ (JSC::Interpreter::tryCTICachePutByID):
+ (JSC::Interpreter::tryCTICacheGetByID):
+ (JSC::):
+ (JSC::Interpreter::cti_op_convert_this):
+ (JSC::Interpreter::cti_op_end):
+ (JSC::Interpreter::cti_op_add):
+ (JSC::Interpreter::cti_op_pre_inc):
+ (JSC::Interpreter::cti_timeout_check):
+ (JSC::Interpreter::cti_register_file_check):
+ (JSC::Interpreter::cti_op_loop_if_less):
+ (JSC::Interpreter::cti_op_loop_if_lesseq):
+ (JSC::Interpreter::cti_op_new_object):
+ (JSC::Interpreter::cti_op_put_by_id):
+ (JSC::Interpreter::cti_op_put_by_id_second):
+ (JSC::Interpreter::cti_op_put_by_id_generic):
+ (JSC::Interpreter::cti_op_put_by_id_fail):
+ (JSC::Interpreter::cti_op_get_by_id):
+ (JSC::Interpreter::cti_op_get_by_id_second):
+ (JSC::Interpreter::cti_op_get_by_id_generic):
+ (JSC::Interpreter::cti_op_get_by_id_fail):
+ (JSC::Interpreter::cti_op_instanceof):
+ (JSC::Interpreter::cti_op_del_by_id):
+ (JSC::Interpreter::cti_op_mul):
+ (JSC::Interpreter::cti_op_new_func):
+ (JSC::Interpreter::cti_op_call_JSFunction):
+ (JSC::Interpreter::cti_op_call_arityCheck):
+ (JSC::Interpreter::cti_vm_dontLazyLinkCall):
+ (JSC::Interpreter::cti_vm_lazyLinkCall):
+ (JSC::Interpreter::cti_op_push_activation):
+ (JSC::Interpreter::cti_op_call_NotJSFunction):
+ (JSC::Interpreter::cti_op_create_arguments):
+ (JSC::Interpreter::cti_op_create_arguments_no_params):
+ (JSC::Interpreter::cti_op_tear_off_activation):
+ (JSC::Interpreter::cti_op_tear_off_arguments):
+ (JSC::Interpreter::cti_op_profile_will_call):
+ (JSC::Interpreter::cti_op_profile_did_call):
+ (JSC::Interpreter::cti_op_ret_scopeChain):
+ (JSC::Interpreter::cti_op_new_array):
+ (JSC::Interpreter::cti_op_resolve):
+ (JSC::Interpreter::cti_op_construct_JSConstruct):
+ (JSC::Interpreter::cti_op_construct_NotJSConstruct):
+ (JSC::Interpreter::cti_op_get_by_val):
+ (JSC::Interpreter::cti_op_resolve_func):
+ (JSC::Interpreter::cti_op_sub):
+ (JSC::Interpreter::cti_op_put_by_val):
+ (JSC::Interpreter::cti_op_put_by_val_array):
+ (JSC::Interpreter::cti_op_lesseq):
+ (JSC::Interpreter::cti_op_loop_if_true):
+ (JSC::Interpreter::cti_op_negate):
+ (JSC::Interpreter::cti_op_resolve_base):
+ (JSC::Interpreter::cti_op_resolve_skip):
+ (JSC::Interpreter::cti_op_resolve_global):
+ (JSC::Interpreter::cti_op_div):
+ (JSC::Interpreter::cti_op_pre_dec):
+ (JSC::Interpreter::cti_op_jless):
+ (JSC::Interpreter::cti_op_not):
+ (JSC::Interpreter::cti_op_jtrue):
+ (JSC::Interpreter::cti_op_post_inc):
+ (JSC::Interpreter::cti_op_eq):
+ (JSC::Interpreter::cti_op_lshift):
+ (JSC::Interpreter::cti_op_bitand):
+ (JSC::Interpreter::cti_op_rshift):
+ (JSC::Interpreter::cti_op_bitnot):
+ (JSC::Interpreter::cti_op_resolve_with_base):
+ (JSC::Interpreter::cti_op_new_func_exp):
+ (JSC::Interpreter::cti_op_mod):
+ (JSC::Interpreter::cti_op_less):
+ (JSC::Interpreter::cti_op_neq):
+ (JSC::Interpreter::cti_op_post_dec):
+ (JSC::Interpreter::cti_op_urshift):
+ (JSC::Interpreter::cti_op_bitxor):
+ (JSC::Interpreter::cti_op_new_regexp):
+ (JSC::Interpreter::cti_op_bitor):
+ (JSC::Interpreter::cti_op_call_eval):
+ (JSC::Interpreter::cti_op_throw):
+ (JSC::Interpreter::cti_op_get_pnames):
+ (JSC::Interpreter::cti_op_next_pname):
+ (JSC::Interpreter::cti_op_push_scope):
+ (JSC::Interpreter::cti_op_pop_scope):
+ (JSC::Interpreter::cti_op_typeof):
+ (JSC::Interpreter::cti_op_is_undefined):
+ (JSC::Interpreter::cti_op_is_boolean):
+ (JSC::Interpreter::cti_op_is_number):
+ (JSC::Interpreter::cti_op_is_string):
+ (JSC::Interpreter::cti_op_is_object):
+ (JSC::Interpreter::cti_op_is_function):
+ (JSC::Interpreter::cti_op_stricteq):
+ (JSC::Interpreter::cti_op_nstricteq):
+ (JSC::Interpreter::cti_op_to_jsnumber):
+ (JSC::Interpreter::cti_op_in):
+ (JSC::Interpreter::cti_op_push_new_scope):
+ (JSC::Interpreter::cti_op_jmp_scopes):
+ (JSC::Interpreter::cti_op_put_by_index):
+ (JSC::Interpreter::cti_op_switch_imm):
+ (JSC::Interpreter::cti_op_switch_char):
+ (JSC::Interpreter::cti_op_switch_string):
+ (JSC::Interpreter::cti_op_del_by_val):
+ (JSC::Interpreter::cti_op_put_getter):
+ (JSC::Interpreter::cti_op_put_setter):
+ (JSC::Interpreter::cti_op_new_error):
+ (JSC::Interpreter::cti_op_debug):
+ (JSC::Interpreter::cti_vm_throw):
+ * VM/Machine.h:
+ * VM/Register.h:
+ * VM/SamplingTool.cpp:
+ (JSC::SamplingTool::dump):
+ * VM/SamplingTool.h:
+ (JSC::SamplingTool::SamplingTool):
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * jsc.cpp:
+ (runWithScripts):
+ * masm/X86Assembler.h:
+ (JSC::AssemblerBuffer::executableCopy):
+ (JSC::X86Assembler::executableCopy):
+ * runtime/ExecState.h:
+ (JSC::ExecState::interpreter):
+ * runtime/JSCell.h:
+ * runtime/JSFunction.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * runtime/JSImmediate.h:
+ * runtime/JSString.h:
+ * runtime/JSValue.h:
+ * runtime/JSVariableObject.h:
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ (JSC::RegExp::~RegExp):
+ (JSC::RegExp::match):
+ * runtime/RegExp.h:
+ * wrec/CharacterClassConstructor.cpp:
+ * wrec/CharacterClassConstructor.h:
+ * wrec/WREC.cpp:
+ (JSC::WREC::compileRegExp):
+ * wrec/WREC.h:
+ (JSC::WREC::Generator::Generator):
+ (JSC::WREC::Parser::):
+ (JSC::WREC::Parser::Parser):
+ (JSC::WREC::Parser::parseAlternative):
+
+2008-11-16 Greg Bolsinga <bolsinga@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=21810
+ Remove use of static C++ objects that are destroyed at exit time (destructors)
+
+ Conditionally have the DEFINE_STATIC_LOCAL workaround <rdar://problem/6354696>
+ (Codegen issue with C++ static reference in gcc build 5465) based upon the compiler
+ build versions. It will use the:
+ static T& = *new T;
+ style for all other compilers.
+
+ * wtf/StdLibExtras.h:
+
+2008-11-16 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Dan Bernstein.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22290
+ Remove cross-heap GC and MessagePort multi-threading support
+
+ It is broken (and may not be implementable at all), and no longer needed, as we
+ don't use MessagePorts for communication with workers any more.
+
+ * JavaScriptCore.exp:
+ * runtime/Collector.cpp:
+ (JSC::Heap::collect):
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSGlobalObject.h:
+ Remove hooks for cross-heap GC.
+
+2008-11-15 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Cameron Zwarich.
+
+ Cleanup jsc command line code a little.
+
+ * jsc.cpp:
+ (functionQuit):
+ (main): Use standard exit status macros
+ (cleanupGlobalData): Factor out cleanup code into this function.
+ (printUsageStatement): Use standard exit status macros.
+
+2008-11-15 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Cameron Zwarich.
+
+ Cleanup BytecodeGenerator constructors.
+
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * bytecompiler/CodeGenerator.h:
+ * parser/Nodes.cpp:
+ (JSC::ProgramNode::generateBytecode):
+
+2008-11-15 Darin Adler <darin@apple.com>
+
+ Rubber stamped by Geoff Garen.
+
+ - do the long-planned StructureID -> Structure rename
+
+ * API/JSCallbackConstructor.cpp:
+ (JSC::JSCallbackConstructor::JSCallbackConstructor):
+ * API/JSCallbackConstructor.h:
+ (JSC::JSCallbackConstructor::createStructure):
+ * API/JSCallbackFunction.h:
+ (JSC::JSCallbackFunction::createStructure):
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObject::createStructure):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::JSCallbackObject):
+ * API/JSValueRef.cpp:
+ (JSValueIsInstanceOfConstructor):
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * VM/CTI.cpp:
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileGetByIdSelf):
+ (JSC::CTI::privateCompileGetByIdProto):
+ (JSC::CTI::privateCompileGetByIdChain):
+ (JSC::CTI::privateCompilePutByIdReplace):
+ (JSC::transitionWillNeedStorageRealloc):
+ (JSC::CTI::privateCompilePutByIdTransition):
+ (JSC::CTI::patchGetByIdSelf):
+ (JSC::CTI::patchPutByIdReplace):
+ * VM/CTI.h:
+ (JSC::CTI::compileGetByIdSelf):
+ (JSC::CTI::compileGetByIdProto):
+ (JSC::CTI::compileGetByIdChain):
+ (JSC::CTI::compilePutByIdReplace):
+ (JSC::CTI::compilePutByIdTransition):
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::printStructure):
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::~CodeBlock):
+ (JSC::CodeBlock::derefStructures):
+ (JSC::CodeBlock::refStructures):
+ * VM/CodeBlock.h:
+ * VM/Instruction.h:
+ (JSC::Instruction::Instruction):
+ (JSC::Instruction::):
+ * VM/Machine.cpp:
+ (JSC::jsTypeStringForValue):
+ (JSC::jsIsObjectType):
+ (JSC::BytecodeInterpreter::resolveGlobal):
+ (JSC::BytecodeInterpreter::BytecodeInterpreter):
+ (JSC::cachePrototypeChain):
+ (JSC::BytecodeInterpreter::tryCachePutByID):
+ (JSC::BytecodeInterpreter::uncachePutByID):
+ (JSC::BytecodeInterpreter::tryCacheGetByID):
+ (JSC::BytecodeInterpreter::uncacheGetByID):
+ (JSC::BytecodeInterpreter::privateExecute):
+ (JSC::BytecodeInterpreter::tryCTICachePutByID):
+ (JSC::BytecodeInterpreter::tryCTICacheGetByID):
+ (JSC::BytecodeInterpreter::cti_op_instanceof):
+ (JSC::BytecodeInterpreter::cti_op_construct_JSConstruct):
+ (JSC::BytecodeInterpreter::cti_op_resolve_global):
+ (JSC::BytecodeInterpreter::cti_op_is_undefined):
+ * runtime/Arguments.h:
+ (JSC::Arguments::createStructure):
+ * runtime/ArrayConstructor.cpp:
+ (JSC::ArrayConstructor::ArrayConstructor):
+ * runtime/ArrayConstructor.h:
+ * runtime/ArrayPrototype.cpp:
+ (JSC::ArrayPrototype::ArrayPrototype):
+ * runtime/ArrayPrototype.h:
+ * runtime/BatchedTransitionOptimizer.h:
+ (JSC::BatchedTransitionOptimizer::BatchedTransitionOptimizer):
+ (JSC::BatchedTransitionOptimizer::~BatchedTransitionOptimizer):
+ * runtime/BooleanConstructor.cpp:
+ (JSC::BooleanConstructor::BooleanConstructor):
+ * runtime/BooleanConstructor.h:
+ * runtime/BooleanObject.cpp:
+ (JSC::BooleanObject::BooleanObject):
+ * runtime/BooleanObject.h:
+ * runtime/BooleanPrototype.cpp:
+ (JSC::BooleanPrototype::BooleanPrototype):
+ * runtime/BooleanPrototype.h:
+ * runtime/DateConstructor.cpp:
+ (JSC::DateConstructor::DateConstructor):
+ * runtime/DateConstructor.h:
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::DateInstance):
+ * runtime/DateInstance.h:
+ * runtime/DatePrototype.cpp:
+ (JSC::DatePrototype::DatePrototype):
+ * runtime/DatePrototype.h:
+ (JSC::DatePrototype::createStructure):
+ * runtime/ErrorConstructor.cpp:
+ (JSC::ErrorConstructor::ErrorConstructor):
+ * runtime/ErrorConstructor.h:
+ * runtime/ErrorInstance.cpp:
+ (JSC::ErrorInstance::ErrorInstance):
+ * runtime/ErrorInstance.h:
+ * runtime/ErrorPrototype.cpp:
+ (JSC::ErrorPrototype::ErrorPrototype):
+ * runtime/ErrorPrototype.h:
+ * runtime/FunctionConstructor.cpp:
+ (JSC::FunctionConstructor::FunctionConstructor):
+ * runtime/FunctionConstructor.h:
+ * runtime/FunctionPrototype.cpp:
+ (JSC::FunctionPrototype::FunctionPrototype):
+ (JSC::FunctionPrototype::addFunctionProperties):
+ * runtime/FunctionPrototype.h:
+ (JSC::FunctionPrototype::createStructure):
+ * runtime/GlobalEvalFunction.cpp:
+ (JSC::GlobalEvalFunction::GlobalEvalFunction):
+ * runtime/GlobalEvalFunction.h:
+ * runtime/Identifier.h:
+ * runtime/InternalFunction.cpp:
+ (JSC::InternalFunction::InternalFunction):
+ * runtime/InternalFunction.h:
+ (JSC::InternalFunction::createStructure):
+ (JSC::InternalFunction::InternalFunction):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::JSActivation):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::createStructure):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::JSArray):
+ * runtime/JSArray.h:
+ (JSC::JSArray::createStructure):
+ * runtime/JSCell.h:
+ (JSC::JSCell::JSCell):
+ (JSC::JSCell::isObject):
+ (JSC::JSCell::isString):
+ (JSC::JSCell::structure):
+ (JSC::JSValue::needsThisConversion):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::construct):
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::JSFunction):
+ (JSC::JSFunction::createStructure):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::createLeaked):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::markIfNeeded):
+ (JSC::JSGlobalObject::reset):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::JSGlobalObject):
+ (JSC::JSGlobalObject::argumentsStructure):
+ (JSC::JSGlobalObject::arrayStructure):
+ (JSC::JSGlobalObject::booleanObjectStructure):
+ (JSC::JSGlobalObject::callbackConstructorStructure):
+ (JSC::JSGlobalObject::callbackFunctionStructure):
+ (JSC::JSGlobalObject::callbackObjectStructure):
+ (JSC::JSGlobalObject::dateStructure):
+ (JSC::JSGlobalObject::emptyObjectStructure):
+ (JSC::JSGlobalObject::errorStructure):
+ (JSC::JSGlobalObject::functionStructure):
+ (JSC::JSGlobalObject::numberObjectStructure):
+ (JSC::JSGlobalObject::prototypeFunctionStructure):
+ (JSC::JSGlobalObject::regExpMatchesArrayStructure):
+ (JSC::JSGlobalObject::regExpStructure):
+ (JSC::JSGlobalObject::stringObjectStructure):
+ (JSC::JSGlobalObject::createStructure):
+ (JSC::Structure::prototypeForLookup):
+ * runtime/JSNotAnObject.h:
+ (JSC::JSNotAnObject::createStructure):
+ * runtime/JSNumberCell.h:
+ (JSC::JSNumberCell::createStructure):
+ (JSC::JSNumberCell::JSNumberCell):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::mark):
+ (JSC::JSObject::put):
+ (JSC::JSObject::deleteProperty):
+ (JSC::JSObject::defineGetter):
+ (JSC::JSObject::defineSetter):
+ (JSC::JSObject::getPropertyAttributes):
+ (JSC::JSObject::getPropertyNames):
+ (JSC::JSObject::removeDirect):
+ (JSC::JSObject::createInheritorID):
+ * runtime/JSObject.h:
+ (JSC::JSObject::getDirect):
+ (JSC::JSObject::getDirectLocation):
+ (JSC::JSObject::hasCustomProperties):
+ (JSC::JSObject::hasGetterSetterProperties):
+ (JSC::JSObject::createStructure):
+ (JSC::JSObject::JSObject):
+ (JSC::JSObject::~JSObject):
+ (JSC::JSObject::prototype):
+ (JSC::JSObject::setPrototype):
+ (JSC::JSObject::setStructure):
+ (JSC::JSObject::inheritorID):
+ (JSC::JSObject::inlineGetOwnPropertySlot):
+ (JSC::JSObject::getOwnPropertySlotForWrite):
+ (JSC::JSCell::fastGetOwnPropertySlot):
+ (JSC::JSObject::putDirect):
+ (JSC::JSObject::putDirectWithoutTransition):
+ (JSC::JSObject::transitionTo):
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::next):
+ * runtime/JSStaticScopeObject.h:
+ (JSC::JSStaticScopeObject::JSStaticScopeObject):
+ (JSC::JSStaticScopeObject::createStructure):
+ * runtime/JSString.h:
+ (JSC::JSString::JSString):
+ (JSC::JSString::createStructure):
+ * runtime/JSVariableObject.h:
+ (JSC::JSVariableObject::JSVariableObject):
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::JSWrapperObject):
+ * runtime/MathObject.cpp:
+ (JSC::MathObject::MathObject):
+ * runtime/MathObject.h:
+ (JSC::MathObject::createStructure):
+ * runtime/NativeErrorConstructor.cpp:
+ (JSC::NativeErrorConstructor::NativeErrorConstructor):
+ * runtime/NativeErrorConstructor.h:
+ * runtime/NativeErrorPrototype.cpp:
+ (JSC::NativeErrorPrototype::NativeErrorPrototype):
+ * runtime/NativeErrorPrototype.h:
+ * runtime/NumberConstructor.cpp:
+ (JSC::NumberConstructor::NumberConstructor):
+ * runtime/NumberConstructor.h:
+ (JSC::NumberConstructor::createStructure):
+ * runtime/NumberObject.cpp:
+ (JSC::NumberObject::NumberObject):
+ * runtime/NumberObject.h:
+ * runtime/NumberPrototype.cpp:
+ (JSC::NumberPrototype::NumberPrototype):
+ * runtime/NumberPrototype.h:
+ * runtime/ObjectConstructor.cpp:
+ (JSC::ObjectConstructor::ObjectConstructor):
+ * runtime/ObjectConstructor.h:
+ * runtime/ObjectPrototype.cpp:
+ (JSC::ObjectPrototype::ObjectPrototype):
+ * runtime/ObjectPrototype.h:
+ * runtime/Operations.h:
+ (JSC::equalSlowCaseInline):
+ * runtime/PropertyNameArray.h:
+ (JSC::PropertyNameArrayData::setCachedStructure):
+ (JSC::PropertyNameArrayData::cachedStructure):
+ (JSC::PropertyNameArrayData::setCachedPrototypeChain):
+ (JSC::PropertyNameArrayData::cachedPrototypeChain):
+ (JSC::PropertyNameArrayData::PropertyNameArrayData):
+ * runtime/PrototypeFunction.cpp:
+ (JSC::PrototypeFunction::PrototypeFunction):
+ * runtime/PrototypeFunction.h:
+ * runtime/RegExpConstructor.cpp:
+ (JSC::RegExpConstructor::RegExpConstructor):
+ * runtime/RegExpConstructor.h:
+ (JSC::RegExpConstructor::createStructure):
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::RegExpObject):
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::createStructure):
+ * runtime/RegExpPrototype.cpp:
+ (JSC::RegExpPrototype::RegExpPrototype):
+ * runtime/RegExpPrototype.h:
+ * runtime/StringConstructor.cpp:
+ (JSC::StringConstructor::StringConstructor):
+ * runtime/StringConstructor.h:
+ * runtime/StringObject.cpp:
+ (JSC::StringObject::StringObject):
+ * runtime/StringObject.h:
+ (JSC::StringObject::createStructure):
+ * runtime/StringObjectThatMasqueradesAsUndefined.h:
+ (JSC::StringObjectThatMasqueradesAsUndefined::create):
+ (JSC::StringObjectThatMasqueradesAsUndefined::StringObjectThatMasqueradesAsUndefined):
+ (JSC::StringObjectThatMasqueradesAsUndefined::createStructure):
+ * runtime/StringPrototype.cpp:
+ (JSC::StringPrototype::StringPrototype):
+ * runtime/StringPrototype.h:
+ * runtime/Structure.cpp: Copied from JavaScriptCore/runtime/StructureID.cpp.
+ (JSC::Structure::dumpStatistics):
+ (JSC::Structure::Structure):
+ (JSC::Structure::~Structure):
+ (JSC::Structure::startIgnoringLeaks):
+ (JSC::Structure::stopIgnoringLeaks):
+ (JSC::Structure::materializePropertyMap):
+ (JSC::Structure::getEnumerablePropertyNames):
+ (JSC::Structure::clearEnumerationCache):
+ (JSC::Structure::growPropertyStorageCapacity):
+ (JSC::Structure::addPropertyTransitionToExistingStructure):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::removePropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::getterSetterTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::fromDictionaryTransition):
+ (JSC::Structure::addPropertyWithoutTransition):
+ (JSC::Structure::removePropertyWithoutTransition):
+ (JSC::Structure::createCachedPrototypeChain):
+ (JSC::Structure::checkConsistency):
+ (JSC::Structure::copyPropertyTable):
+ (JSC::Structure::get):
+ (JSC::Structure::put):
+ (JSC::Structure::remove):
+ (JSC::Structure::insertIntoPropertyMapHashTable):
+ (JSC::Structure::createPropertyMapHashTable):
+ (JSC::Structure::expandPropertyMapHashTable):
+ (JSC::Structure::rehashPropertyMapHashTable):
+ (JSC::Structure::getEnumerablePropertyNamesInternal):
+ * runtime/Structure.h: Copied from JavaScriptCore/runtime/StructureID.h.
+ (JSC::Structure::create):
+ (JSC::Structure::previousID):
+ (JSC::Structure::setCachedPrototypeChain):
+ (JSC::Structure::cachedPrototypeChain):
+ (JSC::Structure::):
+ (JSC::Structure::get):
+ * runtime/StructureChain.cpp: Copied from JavaScriptCore/runtime/StructureIDChain.cpp.
+ (JSC::StructureChain::StructureChain):
+ (JSC::structureChainsAreEqual):
+ * runtime/StructureChain.h: Copied from JavaScriptCore/runtime/StructureIDChain.h.
+ (JSC::StructureChain::create):
+ (JSC::StructureChain::head):
+ * runtime/StructureID.cpp: Removed.
+ * runtime/StructureID.h: Removed.
+ * runtime/StructureIDChain.cpp: Removed.
+ * runtime/StructureIDChain.h: Removed.
+ * runtime/StructureIDTransitionTable.h: Removed.
+ * runtime/StructureTransitionTable.h: Copied from JavaScriptCore/runtime/StructureIDTransitionTable.h.
+
+2008-11-15 Darin Adler <darin@apple.com>
+
+ - fix non-WREC build
+
+ * runtime/RegExp.cpp: Put "using namespace WREC" inside #if ENABLE(WREC).
+
+2008-11-15 Kevin Ollivier <kevino@theolliviers.com>
+
+ Reviewed by Timothy Hatcher.
+
+ As ThreadingNone doesn't implement threads, isMainThread should return true,
+ not false.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22285
+
+ * wtf/ThreadingNone.cpp:
+ (WTF::isMainThread):
+
+2008-11-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Moved all WREC-related code into WREC.cpp and put it in a WREC namespace.
+ Removed the WREC prefix from class names.
+
+ * VM/CTI.cpp:
+ * VM/CTI.h:
+ * VM/Machine.h:
+ (JSC::BytecodeInterpreter::assemblerBuffer):
+ * masm/X86Assembler.h:
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ * wrec/CharacterClassConstructor.cpp:
+ * wrec/CharacterClassConstructor.h:
+ * wrec/WREC.cpp:
+ (WREC::GenerateParenthesesNonGreedyFunctor::GenerateParenthesesNonGreedyFunctor):
+ (WREC::GeneratePatternCharacterFunctor::generateAtom):
+ (WREC::GeneratePatternCharacterFunctor::backtrack):
+ (WREC::GenerateCharacterClassFunctor::generateAtom):
+ (WREC::GenerateCharacterClassFunctor::backtrack):
+ (WREC::GenerateBackreferenceFunctor::generateAtom):
+ (WREC::GenerateBackreferenceFunctor::backtrack):
+ (WREC::GenerateParenthesesNonGreedyFunctor::generateAtom):
+ (WREC::GenerateParenthesesNonGreedyFunctor::backtrack):
+ (WREC::Generator::generateBacktrack1):
+ (WREC::Generator::generateBacktrackBackreference):
+ (WREC::Generator::generateBackreferenceQuantifier):
+ (WREC::Generator::generateNonGreedyQuantifier):
+ (WREC::Generator::generateGreedyQuantifier):
+ (WREC::Generator::generatePatternCharacter):
+ (WREC::Generator::generateCharacterClassInvertedRange):
+ (WREC::Generator::generateCharacterClassInverted):
+ (WREC::Generator::generateCharacterClass):
+ (WREC::Generator::generateParentheses):
+ (WREC::Generator::generateParenthesesNonGreedy):
+ (WREC::Generator::generateParenthesesResetTrampoline):
+ (WREC::Generator::generateAssertionBOL):
+ (WREC::Generator::generateAssertionEOL):
+ (WREC::Generator::generateAssertionWordBoundary):
+ (WREC::Generator::generateBackreference):
+ (WREC::Generator::generateDisjunction):
+ (WREC::Generator::terminateDisjunction):
+ (WREC::Parser::parseGreedyQuantifier):
+ (WREC::Parser::parseQuantifier):
+ (WREC::Parser::parsePatternCharacterQualifier):
+ (WREC::Parser::parseCharacterClassQuantifier):
+ (WREC::Parser::parseBackreferenceQuantifier):
+ (WREC::Parser::parseParentheses):
+ (WREC::Parser::parseCharacterClass):
+ (WREC::Parser::parseOctalEscape):
+ (WREC::Parser::parseEscape):
+ (WREC::Parser::parseTerm):
+ (WREC::Parser::parseDisjunction):
+ (WREC::compileRegExp):
+ * wrec/WREC.h:
+ (WREC::Generator::Generator):
+ (WREC::Parser::Parser):
+ (WREC::Parser::parseAlternative):
+
+2008-11-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Changed another case of "m_jit" to "m_assembler".
+
+ * VM/CTI.cpp:
+ * wrec/WREC.cpp:
+ * wrec/WREC.h:
+ (JSC::WRECGenerator::WRECGenerator):
+ (JSC::WRECParser::WRECParser):
+
+2008-11-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed "jit" to "assembler" and, for brevity, replaced *jit.* with __
+ using a macro.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitGetVirtualRegister):
+ (JSC::CTI::emitPutCTIArgFromVirtualRegister):
+ (JSC::CTI::emitPutCTIArg):
+ (JSC::CTI::emitGetCTIArg):
+ (JSC::CTI::emitPutCTIArgConstant):
+ (JSC::CTI::emitPutCTIParam):
+ (JSC::CTI::emitGetCTIParam):
+ (JSC::CTI::emitPutToCallFrameHeader):
+ (JSC::CTI::emitGetFromCallFrameHeader):
+ (JSC::CTI::emitPutVirtualRegister):
+ (JSC::CTI::emitInitRegister):
+ (JSC::CTI::emitAllocateNumber):
+ (JSC::CTI::emitNakedCall):
+ (JSC::CTI::emitNakedFastCall):
+ (JSC::CTI::emitCTICall):
+ (JSC::CTI::emitJumpSlowCaseIfNotJSCell):
+ (JSC::CTI::linkSlowCaseIfNotJSCell):
+ (JSC::CTI::emitJumpSlowCaseIfNotImmNum):
+ (JSC::CTI::emitJumpSlowCaseIfNotImmNums):
+ (JSC::CTI::emitFastArithDeTagImmediate):
+ (JSC::CTI::emitFastArithDeTagImmediateJumpIfZero):
+ (JSC::CTI::emitFastArithReTagImmediate):
+ (JSC::CTI::emitFastArithPotentiallyReTagImmediate):
+ (JSC::CTI::emitFastArithImmToInt):
+ (JSC::CTI::emitFastArithIntToImmOrSlowCase):
+ (JSC::CTI::emitFastArithIntToImmNoCheck):
+ (JSC::CTI::emitArithIntToImmWithJump):
+ (JSC::CTI::emitTagAsBoolImmediate):
+ (JSC::CTI::CTI):
+ (JSC::CTI::compileOpCallInitializeCallFrame):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::compileOpStrictEq):
+ (JSC::CTI::emitSlowScriptCheck):
+ (JSC::CTI::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::compileBinaryArithOpSlowCase):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileLinkPass):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompile):
+ (JSC::CTI::privateCompileGetByIdSelf):
+ (JSC::CTI::privateCompileGetByIdProto):
+ (JSC::CTI::privateCompileGetByIdChain):
+ (JSC::CTI::privateCompilePutByIdReplace):
+ (JSC::CTI::privateCompilePutByIdTransition):
+ (JSC::CTI::privateCompileCTIMachineTrampolines):
+ (JSC::CTI::privateCompilePatchGetArrayLength):
+ (JSC::CTI::emitGetVariableObjectRegister):
+ (JSC::CTI::emitPutVariableObjectRegister):
+ (JSC::CTI::compileRegExp):
+ * VM/CTI.h:
+ * wrec/WREC.cpp:
+ (JSC::WRECGenerator::generateBacktrack1):
+ (JSC::WRECGenerator::generateBacktrackBackreference):
+ (JSC::WRECGenerator::generateBackreferenceQuantifier):
+ (JSC::WRECGenerator::generateNonGreedyQuantifier):
+ (JSC::WRECGenerator::generateGreedyQuantifier):
+ (JSC::WRECGenerator::generatePatternCharacter):
+ (JSC::WRECGenerator::generateCharacterClassInvertedRange):
+ (JSC::WRECGenerator::generateCharacterClassInverted):
+ (JSC::WRECGenerator::generateCharacterClass):
+ (JSC::WRECGenerator::generateParentheses):
+ (JSC::WRECGenerator::generateParenthesesNonGreedy):
+ (JSC::WRECGenerator::generateParenthesesResetTrampoline):
+ (JSC::WRECGenerator::generateAssertionBOL):
+ (JSC::WRECGenerator::generateAssertionEOL):
+ (JSC::WRECGenerator::generateAssertionWordBoundary):
+ (JSC::WRECGenerator::generateBackreference):
+ (JSC::WRECGenerator::generateDisjunction):
+ (JSC::WRECGenerator::terminateDisjunction):
+
+2008-11-15 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Remove dead method declaration.
+
+ * bytecompiler/CodeGenerator.h:
+
+2008-11-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed LabelID to Label, Label::isForwardLabel to Label::isForward.
+
+ * VM/LabelID.h:
+ (JSC::Label::Label):
+ (JSC::Label::isForward):
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::BytecodeGenerator::newLabel):
+ (JSC::BytecodeGenerator::emitLabel):
+ (JSC::BytecodeGenerator::emitJump):
+ (JSC::BytecodeGenerator::emitJumpIfTrue):
+ (JSC::BytecodeGenerator::emitJumpIfFalse):
+ (JSC::BytecodeGenerator::pushFinallyContext):
+ (JSC::BytecodeGenerator::emitComplexJumpScopes):
+ (JSC::BytecodeGenerator::emitJumpScopes):
+ (JSC::BytecodeGenerator::emitNextPropertyName):
+ (JSC::BytecodeGenerator::emitCatch):
+ (JSC::BytecodeGenerator::emitJumpSubroutine):
+ (JSC::prepareJumpTableForImmediateSwitch):
+ (JSC::prepareJumpTableForCharacterSwitch):
+ (JSC::prepareJumpTableForStringSwitch):
+ (JSC::BytecodeGenerator::endSwitch):
+ * bytecompiler/CodeGenerator.h:
+ * bytecompiler/LabelScope.h:
+ (JSC::LabelScope::LabelScope):
+ (JSC::LabelScope::breakTarget):
+ (JSC::LabelScope::continueTarget):
+ * parser/Nodes.cpp:
+ (JSC::LogicalOpNode::emitBytecode):
+ (JSC::ConditionalNode::emitBytecode):
+ (JSC::IfNode::emitBytecode):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::CaseBlockNode::emitBytecodeForBlock):
+ (JSC::TryNode::emitBytecode):
+
+2008-11-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed JITCodeBuffer to AssemblerBuffer and renamed its data members
+ to be more like the rest of our buffer classes, with a size and a
+ capacity.
+
+ Added an assert in the unchecked put case to match the test in the checked
+ put case.
+
+ Changed a C-style cast to a C++-style cast.
+
+ Renamed MAX_INSTRUCTION_SIZE to maxInstructionSize.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::CTI):
+ (JSC::CTI::compileRegExp):
+ * VM/Machine.cpp:
+ (JSC::BytecodeInterpreter::BytecodeInterpreter):
+ * VM/Machine.h:
+ (JSC::BytecodeInterpreter::assemblerBuffer):
+ * masm/X86Assembler.h:
+ (JSC::AssemblerBuffer::AssemblerBuffer):
+ (JSC::AssemblerBuffer::~AssemblerBuffer):
+ (JSC::AssemblerBuffer::ensureSpace):
+ (JSC::AssemblerBuffer::isAligned):
+ (JSC::AssemblerBuffer::putByteUnchecked):
+ (JSC::AssemblerBuffer::putByte):
+ (JSC::AssemblerBuffer::putShortUnchecked):
+ (JSC::AssemblerBuffer::putShort):
+ (JSC::AssemblerBuffer::putIntUnchecked):
+ (JSC::AssemblerBuffer::putInt):
+ (JSC::AssemblerBuffer::data):
+ (JSC::AssemblerBuffer::size):
+ (JSC::AssemblerBuffer::reset):
+ (JSC::AssemblerBuffer::copy):
+ (JSC::AssemblerBuffer::grow):
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::X86Assembler):
+ (JSC::X86Assembler::testl_i32r):
+ (JSC::X86Assembler::movl_mr):
+ (JSC::X86Assembler::movl_rm):
+ (JSC::X86Assembler::movl_i32m):
+ (JSC::X86Assembler::emitCall):
+ (JSC::X86Assembler::label):
+ (JSC::X86Assembler::emitUnlinkedJmp):
+ (JSC::X86Assembler::emitUnlinkedJne):
+ (JSC::X86Assembler::emitUnlinkedJe):
+ (JSC::X86Assembler::emitUnlinkedJl):
+ (JSC::X86Assembler::emitUnlinkedJb):
+ (JSC::X86Assembler::emitUnlinkedJle):
+ (JSC::X86Assembler::emitUnlinkedJbe):
+ (JSC::X86Assembler::emitUnlinkedJge):
+ (JSC::X86Assembler::emitUnlinkedJg):
+ (JSC::X86Assembler::emitUnlinkedJa):
+ (JSC::X86Assembler::emitUnlinkedJae):
+ (JSC::X86Assembler::emitUnlinkedJo):
+ (JSC::X86Assembler::emitUnlinkedJp):
+ (JSC::X86Assembler::emitUnlinkedJs):
+ (JSC::X86Assembler::link):
+ (JSC::X86Assembler::emitModRm_rr):
+ (JSC::X86Assembler::emitModRm_rm):
+ (JSC::X86Assembler::emitModRm_opr):
+
+2008-11-15 Geoffrey Garen <ggaren@apple.com>
+
+ Suggested by Maciej Stachowiak.
+
+ Reverted most "opcode" => "bytecode" renames. We use "bytecode" as a
+ mass noun to refer to a stream of instructions. Each instruction may be
+ an opcode or an operand.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitCTICall):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::compileBinaryArithOpSlowCase):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompile):
+ * VM/CTI.h:
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::printStructureIDs):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::derefStructureIDs):
+ (JSC::CodeBlock::refStructureIDs):
+ * VM/CodeBlock.h:
+ * VM/ExceptionHelpers.cpp:
+ (JSC::createNotAnObjectError):
+ * VM/Instruction.h:
+ (JSC::Instruction::Instruction):
+ (JSC::Instruction::):
+ * VM/Machine.cpp:
+ (JSC::BytecodeInterpreter::isOpcode):
+ (JSC::BytecodeInterpreter::throwException):
+ (JSC::BytecodeInterpreter::tryCachePutByID):
+ (JSC::BytecodeInterpreter::uncachePutByID):
+ (JSC::BytecodeInterpreter::tryCacheGetByID):
+ (JSC::BytecodeInterpreter::uncacheGetByID):
+ (JSC::BytecodeInterpreter::privateExecute):
+ (JSC::BytecodeInterpreter::tryCTICachePutByID):
+ (JSC::BytecodeInterpreter::tryCTICacheGetByID):
+ * VM/Machine.h:
+ (JSC::BytecodeInterpreter::getOpcode):
+ (JSC::BytecodeInterpreter::getOpcodeID):
+ (JSC::BytecodeInterpreter::isCallBytecode):
+ * VM/Opcode.cpp:
+ (JSC::):
+ (JSC::OpcodeStats::OpcodeStats):
+ (JSC::compareOpcodeIndices):
+ (JSC::compareOpcodePairIndices):
+ (JSC::OpcodeStats::~OpcodeStats):
+ (JSC::OpcodeStats::recordInstruction):
+ (JSC::OpcodeStats::resetLastInstruction):
+ * VM/Opcode.h:
+ (JSC::):
+ (JSC::padOpcodeName):
+ * VM/SamplingTool.cpp:
+ (JSC::ScopeSampleRecord::sample):
+ (JSC::SamplingTool::run):
+ (JSC::compareOpcodeIndicesSampling):
+ (JSC::SamplingTool::dump):
+ * VM/SamplingTool.h:
+ (JSC::ScopeSampleRecord::ScopeSampleRecord):
+ (JSC::SamplingTool::SamplingTool):
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::emitLabel):
+ (JSC::BytecodeGenerator::emitOpcode):
+ (JSC::BytecodeGenerator::emitJump):
+ (JSC::BytecodeGenerator::emitJumpIfTrue):
+ (JSC::BytecodeGenerator::emitJumpIfFalse):
+ (JSC::BytecodeGenerator::emitMove):
+ (JSC::BytecodeGenerator::emitUnaryOp):
+ (JSC::BytecodeGenerator::emitPreInc):
+ (JSC::BytecodeGenerator::emitPreDec):
+ (JSC::BytecodeGenerator::emitPostInc):
+ (JSC::BytecodeGenerator::emitPostDec):
+ (JSC::BytecodeGenerator::emitBinaryOp):
+ (JSC::BytecodeGenerator::emitEqualityOp):
+ (JSC::BytecodeGenerator::emitUnexpectedLoad):
+ (JSC::BytecodeGenerator::emitInstanceOf):
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitGetScopedVar):
+ (JSC::BytecodeGenerator::emitPutScopedVar):
+ (JSC::BytecodeGenerator::emitResolveBase):
+ (JSC::BytecodeGenerator::emitResolveWithBase):
+ (JSC::BytecodeGenerator::emitResolveFunction):
+ (JSC::BytecodeGenerator::emitGetById):
+ (JSC::BytecodeGenerator::emitPutById):
+ (JSC::BytecodeGenerator::emitPutGetter):
+ (JSC::BytecodeGenerator::emitPutSetter):
+ (JSC::BytecodeGenerator::emitDeleteById):
+ (JSC::BytecodeGenerator::emitGetByVal):
+ (JSC::BytecodeGenerator::emitPutByVal):
+ (JSC::BytecodeGenerator::emitDeleteByVal):
+ (JSC::BytecodeGenerator::emitPutByIndex):
+ (JSC::BytecodeGenerator::emitNewObject):
+ (JSC::BytecodeGenerator::emitNewArray):
+ (JSC::BytecodeGenerator::emitNewFunction):
+ (JSC::BytecodeGenerator::emitNewRegExp):
+ (JSC::BytecodeGenerator::emitNewFunctionExpression):
+ (JSC::BytecodeGenerator::emitCall):
+ (JSC::BytecodeGenerator::emitReturn):
+ (JSC::BytecodeGenerator::emitUnaryNoDstOp):
+ (JSC::BytecodeGenerator::emitConstruct):
+ (JSC::BytecodeGenerator::emitPopScope):
+ (JSC::BytecodeGenerator::emitDebugHook):
+ (JSC::BytecodeGenerator::emitComplexJumpScopes):
+ (JSC::BytecodeGenerator::emitJumpScopes):
+ (JSC::BytecodeGenerator::emitNextPropertyName):
+ (JSC::BytecodeGenerator::emitCatch):
+ (JSC::BytecodeGenerator::emitNewError):
+ (JSC::BytecodeGenerator::emitJumpSubroutine):
+ (JSC::BytecodeGenerator::emitSubroutineReturn):
+ (JSC::BytecodeGenerator::emitPushNewScope):
+ (JSC::BytecodeGenerator::beginSwitch):
+ * bytecompiler/CodeGenerator.h:
+ * jsc.cpp:
+ (runWithScripts):
+ * masm/X86Assembler.h:
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::emitModRm_opr):
+ (JSC::X86Assembler::emitModRm_opr_Unchecked):
+ (JSC::X86Assembler::emitModRm_opm):
+ (JSC::X86Assembler::emitModRm_opm_Unchecked):
+ (JSC::X86Assembler::emitModRm_opmsib):
+ * parser/Nodes.cpp:
+ (JSC::UnaryOpNode::emitBytecode):
+ (JSC::BinaryOpNode::emitBytecode):
+ (JSC::ReverseBinaryOpNode::emitBytecode):
+ (JSC::ThrowableBinaryOpNode::emitBytecode):
+ (JSC::emitReadModifyAssignment):
+ (JSC::ScopeNode::ScopeNode):
+ * parser/Nodes.h:
+ (JSC::UnaryPlusNode::):
+ (JSC::NegateNode::):
+ (JSC::BitwiseNotNode::):
+ (JSC::LogicalNotNode::):
+ (JSC::MultNode::):
+ (JSC::DivNode::):
+ (JSC::ModNode::):
+ (JSC::AddNode::):
+ (JSC::SubNode::):
+ (JSC::LeftShiftNode::):
+ (JSC::RightShiftNode::):
+ (JSC::UnsignedRightShiftNode::):
+ (JSC::LessNode::):
+ (JSC::GreaterNode::):
+ (JSC::LessEqNode::):
+ (JSC::GreaterEqNode::):
+ (JSC::InstanceOfNode::):
+ (JSC::InNode::):
+ (JSC::EqualNode::):
+ (JSC::NotEqualNode::):
+ (JSC::StrictEqualNode::):
+ (JSC::NotStrictEqualNode::):
+ (JSC::BitAndNode::):
+ (JSC::BitOrNode::):
+ (JSC::BitXOrNode::):
+ * runtime/StructureID.cpp:
+ (JSC::StructureID::fromDictionaryTransition):
+ * wtf/Platform.h:
+
+2008-11-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renames:
+
+ CodeGenerator => BytecodeGenerator
+ emitCodeForBlock => emitBytecodeForBlock
+ generatedByteCode => generatedBytecode
+ generateCode => generateBytecode
+
+ * JavaScriptCore.exp:
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::BytecodeGenerator::setDumpsGeneratedCode):
+ (JSC::BytecodeGenerator::generate):
+ (JSC::BytecodeGenerator::addVar):
+ (JSC::BytecodeGenerator::addGlobalVar):
+ (JSC::BytecodeGenerator::allocateConstants):
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ (JSC::BytecodeGenerator::addParameter):
+ (JSC::BytecodeGenerator::registerFor):
+ (JSC::BytecodeGenerator::constRegisterFor):
+ (JSC::BytecodeGenerator::isLocal):
+ (JSC::BytecodeGenerator::isLocalConstant):
+ (JSC::BytecodeGenerator::newRegister):
+ (JSC::BytecodeGenerator::newTemporary):
+ (JSC::BytecodeGenerator::highestUsedRegister):
+ (JSC::BytecodeGenerator::newLabelScope):
+ (JSC::BytecodeGenerator::newLabel):
+ (JSC::BytecodeGenerator::emitLabel):
+ (JSC::BytecodeGenerator::emitBytecode):
+ (JSC::BytecodeGenerator::retrieveLastBinaryOp):
+ (JSC::BytecodeGenerator::retrieveLastUnaryOp):
+ (JSC::BytecodeGenerator::rewindBinaryOp):
+ (JSC::BytecodeGenerator::rewindUnaryOp):
+ (JSC::BytecodeGenerator::emitJump):
+ (JSC::BytecodeGenerator::emitJumpIfTrue):
+ (JSC::BytecodeGenerator::emitJumpIfFalse):
+ (JSC::BytecodeGenerator::addConstant):
+ (JSC::BytecodeGenerator::addUnexpectedConstant):
+ (JSC::BytecodeGenerator::addRegExp):
+ (JSC::BytecodeGenerator::emitMove):
+ (JSC::BytecodeGenerator::emitUnaryOp):
+ (JSC::BytecodeGenerator::emitPreInc):
+ (JSC::BytecodeGenerator::emitPreDec):
+ (JSC::BytecodeGenerator::emitPostInc):
+ (JSC::BytecodeGenerator::emitPostDec):
+ (JSC::BytecodeGenerator::emitBinaryOp):
+ (JSC::BytecodeGenerator::emitEqualityOp):
+ (JSC::BytecodeGenerator::emitLoad):
+ (JSC::BytecodeGenerator::emitUnexpectedLoad):
+ (JSC::BytecodeGenerator::findScopedProperty):
+ (JSC::BytecodeGenerator::emitInstanceOf):
+ (JSC::BytecodeGenerator::emitResolve):
+ (JSC::BytecodeGenerator::emitGetScopedVar):
+ (JSC::BytecodeGenerator::emitPutScopedVar):
+ (JSC::BytecodeGenerator::emitResolveBase):
+ (JSC::BytecodeGenerator::emitResolveWithBase):
+ (JSC::BytecodeGenerator::emitResolveFunction):
+ (JSC::BytecodeGenerator::emitGetById):
+ (JSC::BytecodeGenerator::emitPutById):
+ (JSC::BytecodeGenerator::emitPutGetter):
+ (JSC::BytecodeGenerator::emitPutSetter):
+ (JSC::BytecodeGenerator::emitDeleteById):
+ (JSC::BytecodeGenerator::emitGetByVal):
+ (JSC::BytecodeGenerator::emitPutByVal):
+ (JSC::BytecodeGenerator::emitDeleteByVal):
+ (JSC::BytecodeGenerator::emitPutByIndex):
+ (JSC::BytecodeGenerator::emitNewObject):
+ (JSC::BytecodeGenerator::emitNewArray):
+ (JSC::BytecodeGenerator::emitNewFunction):
+ (JSC::BytecodeGenerator::emitNewRegExp):
+ (JSC::BytecodeGenerator::emitNewFunctionExpression):
+ (JSC::BytecodeGenerator::emitCall):
+ (JSC::BytecodeGenerator::emitCallEval):
+ (JSC::BytecodeGenerator::emitReturn):
+ (JSC::BytecodeGenerator::emitUnaryNoDstOp):
+ (JSC::BytecodeGenerator::emitConstruct):
+ (JSC::BytecodeGenerator::emitPushScope):
+ (JSC::BytecodeGenerator::emitPopScope):
+ (JSC::BytecodeGenerator::emitDebugHook):
+ (JSC::BytecodeGenerator::pushFinallyContext):
+ (JSC::BytecodeGenerator::popFinallyContext):
+ (JSC::BytecodeGenerator::breakTarget):
+ (JSC::BytecodeGenerator::continueTarget):
+ (JSC::BytecodeGenerator::emitComplexJumpScopes):
+ (JSC::BytecodeGenerator::emitJumpScopes):
+ (JSC::BytecodeGenerator::emitNextPropertyName):
+ (JSC::BytecodeGenerator::emitCatch):
+ (JSC::BytecodeGenerator::emitNewError):
+ (JSC::BytecodeGenerator::emitJumpSubroutine):
+ (JSC::BytecodeGenerator::emitSubroutineReturn):
+ (JSC::BytecodeGenerator::emitPushNewScope):
+ (JSC::BytecodeGenerator::beginSwitch):
+ (JSC::BytecodeGenerator::endSwitch):
+ (JSC::BytecodeGenerator::emitThrowExpressionTooDeepException):
+ * bytecompiler/CodeGenerator.h:
+ * jsc.cpp:
+ (runWithScripts):
+ * parser/Nodes.cpp:
+ (JSC::ThrowableExpressionData::emitThrowError):
+ (JSC::NullNode::emitBytecode):
+ (JSC::BooleanNode::emitBytecode):
+ (JSC::NumberNode::emitBytecode):
+ (JSC::StringNode::emitBytecode):
+ (JSC::RegExpNode::emitBytecode):
+ (JSC::ThisNode::emitBytecode):
+ (JSC::ResolveNode::isPure):
+ (JSC::ResolveNode::emitBytecode):
+ (JSC::ArrayNode::emitBytecode):
+ (JSC::ObjectLiteralNode::emitBytecode):
+ (JSC::PropertyListNode::emitBytecode):
+ (JSC::BracketAccessorNode::emitBytecode):
+ (JSC::DotAccessorNode::emitBytecode):
+ (JSC::ArgumentListNode::emitBytecode):
+ (JSC::NewExprNode::emitBytecode):
+ (JSC::EvalFunctionCallNode::emitBytecode):
+ (JSC::FunctionCallValueNode::emitBytecode):
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::FunctionCallBracketNode::emitBytecode):
+ (JSC::FunctionCallDotNode::emitBytecode):
+ (JSC::emitPreIncOrDec):
+ (JSC::emitPostIncOrDec):
+ (JSC::PostfixResolveNode::emitBytecode):
+ (JSC::PostfixBracketNode::emitBytecode):
+ (JSC::PostfixDotNode::emitBytecode):
+ (JSC::PostfixErrorNode::emitBytecode):
+ (JSC::DeleteResolveNode::emitBytecode):
+ (JSC::DeleteBracketNode::emitBytecode):
+ (JSC::DeleteDotNode::emitBytecode):
+ (JSC::DeleteValueNode::emitBytecode):
+ (JSC::VoidNode::emitBytecode):
+ (JSC::TypeOfResolveNode::emitBytecode):
+ (JSC::TypeOfValueNode::emitBytecode):
+ (JSC::PrefixResolveNode::emitBytecode):
+ (JSC::PrefixBracketNode::emitBytecode):
+ (JSC::PrefixDotNode::emitBytecode):
+ (JSC::PrefixErrorNode::emitBytecode):
+ (JSC::UnaryOpNode::emitBytecode):
+ (JSC::BinaryOpNode::emitBytecode):
+ (JSC::EqualNode::emitBytecode):
+ (JSC::StrictEqualNode::emitBytecode):
+ (JSC::ReverseBinaryOpNode::emitBytecode):
+ (JSC::ThrowableBinaryOpNode::emitBytecode):
+ (JSC::InstanceOfNode::emitBytecode):
+ (JSC::LogicalOpNode::emitBytecode):
+ (JSC::ConditionalNode::emitBytecode):
+ (JSC::emitReadModifyAssignment):
+ (JSC::ReadModifyResolveNode::emitBytecode):
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::AssignDotNode::emitBytecode):
+ (JSC::ReadModifyDotNode::emitBytecode):
+ (JSC::AssignErrorNode::emitBytecode):
+ (JSC::AssignBracketNode::emitBytecode):
+ (JSC::ReadModifyBracketNode::emitBytecode):
+ (JSC::CommaNode::emitBytecode):
+ (JSC::ConstDeclNode::emitCodeSingle):
+ (JSC::ConstDeclNode::emitBytecode):
+ (JSC::ConstStatementNode::emitBytecode):
+ (JSC::statementListEmitCode):
+ (JSC::BlockNode::emitBytecode):
+ (JSC::EmptyStatementNode::emitBytecode):
+ (JSC::DebuggerStatementNode::emitBytecode):
+ (JSC::ExprStatementNode::emitBytecode):
+ (JSC::VarStatementNode::emitBytecode):
+ (JSC::IfNode::emitBytecode):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::ContinueNode::emitBytecode):
+ (JSC::BreakNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::WithNode::emitBytecode):
+ (JSC::CaseBlockNode::emitBytecodeForBlock):
+ (JSC::SwitchNode::emitBytecode):
+ (JSC::LabelNode::emitBytecode):
+ (JSC::ThrowNode::emitBytecode):
+ (JSC::TryNode::emitBytecode):
+ (JSC::EvalNode::emitBytecode):
+ (JSC::EvalNode::generateBytecode):
+ (JSC::FunctionBodyNode::generateBytecode):
+ (JSC::FunctionBodyNode::emitBytecode):
+ (JSC::ProgramNode::emitBytecode):
+ (JSC::ProgramNode::generateBytecode):
+ (JSC::FuncDeclNode::emitBytecode):
+ (JSC::FuncExprNode::emitBytecode):
+ * parser/Nodes.h:
+ (JSC::ExpressionNode::):
+ (JSC::BooleanNode::):
+ (JSC::NumberNode::):
+ (JSC::StringNode::):
+ (JSC::ProgramNode::):
+ (JSC::EvalNode::):
+ (JSC::FunctionBodyNode::):
+ * runtime/Arguments.h:
+ (JSC::Arguments::getArgumentsData):
+ (JSC::JSActivation::copyRegisters):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::mark):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::JSActivationData::JSActivationData):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::~JSFunction):
+
+2008-11-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed all forms of "byte code" "opcode" "op code" "code" "bitcode"
+ etc. to "bytecode".
+
+ * VM/CTI.cpp:
+ (JSC::CTI::printBytecodeOperandTypes):
+ (JSC::CTI::emitAllocateNumber):
+ (JSC::CTI::emitNakedCall):
+ (JSC::CTI::emitNakedFastCall):
+ (JSC::CTI::emitCTICall):
+ (JSC::CTI::emitJumpSlowCaseIfNotJSCell):
+ (JSC::CTI::emitJumpSlowCaseIfNotImmNum):
+ (JSC::CTI::emitJumpSlowCaseIfNotImmNums):
+ (JSC::CTI::emitFastArithIntToImmOrSlowCase):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::emitSlowScriptCheck):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::compileBinaryArithOpSlowCase):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompile):
+ * VM/CTI.h:
+ (JSC::CallRecord::CallRecord):
+ (JSC::SwitchRecord::SwitchRecord):
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::printStructureIDs):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::~CodeBlock):
+ (JSC::CodeBlock::derefStructureIDs):
+ (JSC::CodeBlock::refStructureIDs):
+ * VM/CodeBlock.h:
+ (JSC::StructureStubInfo::StructureStubInfo):
+ * VM/ExceptionHelpers.cpp:
+ (JSC::createNotAnObjectError):
+ * VM/Instruction.h:
+ (JSC::Instruction::Instruction):
+ (JSC::Instruction::):
+ * VM/Machine.cpp:
+ (JSC::BytecodeInterpreter::isBytecode):
+ (JSC::BytecodeInterpreter::throwException):
+ (JSC::BytecodeInterpreter::execute):
+ (JSC::BytecodeInterpreter::tryCachePutByID):
+ (JSC::BytecodeInterpreter::uncachePutByID):
+ (JSC::BytecodeInterpreter::tryCacheGetByID):
+ (JSC::BytecodeInterpreter::uncacheGetByID):
+ (JSC::BytecodeInterpreter::privateExecute):
+ (JSC::BytecodeInterpreter::tryCTICachePutByID):
+ (JSC::BytecodeInterpreter::tryCTICacheGetByID):
+ (JSC::BytecodeInterpreter::cti_op_call_JSFunction):
+ (JSC::BytecodeInterpreter::cti_vm_dontLazyLinkCall):
+ (JSC::BytecodeInterpreter::cti_vm_lazyLinkCall):
+ * VM/Machine.h:
+ (JSC::BytecodeInterpreter::getBytecode):
+ (JSC::BytecodeInterpreter::getBytecodeID):
+ (JSC::BytecodeInterpreter::isCallBytecode):
+ * VM/Opcode.cpp:
+ (JSC::):
+ (JSC::BytecodeStats::BytecodeStats):
+ (JSC::compareBytecodeIndices):
+ (JSC::compareBytecodePairIndices):
+ (JSC::BytecodeStats::~BytecodeStats):
+ (JSC::BytecodeStats::recordInstruction):
+ (JSC::BytecodeStats::resetLastInstruction):
+ * VM/Opcode.h:
+ (JSC::):
+ (JSC::padBytecodeName):
+ * VM/SamplingTool.cpp:
+ (JSC::ScopeSampleRecord::sample):
+ (JSC::SamplingTool::run):
+ (JSC::compareBytecodeIndicesSampling):
+ (JSC::SamplingTool::dump):
+ * VM/SamplingTool.h:
+ (JSC::ScopeSampleRecord::ScopeSampleRecord):
+ (JSC::SamplingTool::SamplingTool):
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::generate):
+ (JSC::CodeGenerator::CodeGenerator):
+ (JSC::CodeGenerator::emitLabel):
+ (JSC::CodeGenerator::emitBytecode):
+ (JSC::CodeGenerator::emitJump):
+ (JSC::CodeGenerator::emitJumpIfTrue):
+ (JSC::CodeGenerator::emitJumpIfFalse):
+ (JSC::CodeGenerator::emitMove):
+ (JSC::CodeGenerator::emitUnaryOp):
+ (JSC::CodeGenerator::emitPreInc):
+ (JSC::CodeGenerator::emitPreDec):
+ (JSC::CodeGenerator::emitPostInc):
+ (JSC::CodeGenerator::emitPostDec):
+ (JSC::CodeGenerator::emitBinaryOp):
+ (JSC::CodeGenerator::emitEqualityOp):
+ (JSC::CodeGenerator::emitUnexpectedLoad):
+ (JSC::CodeGenerator::emitInstanceOf):
+ (JSC::CodeGenerator::emitResolve):
+ (JSC::CodeGenerator::emitGetScopedVar):
+ (JSC::CodeGenerator::emitPutScopedVar):
+ (JSC::CodeGenerator::emitResolveBase):
+ (JSC::CodeGenerator::emitResolveWithBase):
+ (JSC::CodeGenerator::emitResolveFunction):
+ (JSC::CodeGenerator::emitGetById):
+ (JSC::CodeGenerator::emitPutById):
+ (JSC::CodeGenerator::emitPutGetter):
+ (JSC::CodeGenerator::emitPutSetter):
+ (JSC::CodeGenerator::emitDeleteById):
+ (JSC::CodeGenerator::emitGetByVal):
+ (JSC::CodeGenerator::emitPutByVal):
+ (JSC::CodeGenerator::emitDeleteByVal):
+ (JSC::CodeGenerator::emitPutByIndex):
+ (JSC::CodeGenerator::emitNewObject):
+ (JSC::CodeGenerator::emitNewArray):
+ (JSC::CodeGenerator::emitNewFunction):
+ (JSC::CodeGenerator::emitNewRegExp):
+ (JSC::CodeGenerator::emitNewFunctionExpression):
+ (JSC::CodeGenerator::emitCall):
+ (JSC::CodeGenerator::emitReturn):
+ (JSC::CodeGenerator::emitUnaryNoDstOp):
+ (JSC::CodeGenerator::emitConstruct):
+ (JSC::CodeGenerator::emitPopScope):
+ (JSC::CodeGenerator::emitDebugHook):
+ (JSC::CodeGenerator::emitComplexJumpScopes):
+ (JSC::CodeGenerator::emitJumpScopes):
+ (JSC::CodeGenerator::emitNextPropertyName):
+ (JSC::CodeGenerator::emitCatch):
+ (JSC::CodeGenerator::emitNewError):
+ (JSC::CodeGenerator::emitJumpSubroutine):
+ (JSC::CodeGenerator::emitSubroutineReturn):
+ (JSC::CodeGenerator::emitPushNewScope):
+ (JSC::CodeGenerator::beginSwitch):
+ (JSC::CodeGenerator::endSwitch):
+ * bytecompiler/CodeGenerator.h:
+ (JSC::CodeGenerator::emitNode):
+ * jsc.cpp:
+ (runWithScripts):
+ * masm/X86Assembler.h:
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::emitModRm_opr):
+ (JSC::X86Assembler::emitModRm_opr_Unchecked):
+ (JSC::X86Assembler::emitModRm_opm):
+ (JSC::X86Assembler::emitModRm_opm_Unchecked):
+ (JSC::X86Assembler::emitModRm_opmsib):
+ * parser/Nodes.cpp:
+ (JSC::NullNode::emitBytecode):
+ (JSC::BooleanNode::emitBytecode):
+ (JSC::NumberNode::emitBytecode):
+ (JSC::StringNode::emitBytecode):
+ (JSC::RegExpNode::emitBytecode):
+ (JSC::ThisNode::emitBytecode):
+ (JSC::ResolveNode::emitBytecode):
+ (JSC::ArrayNode::emitBytecode):
+ (JSC::ObjectLiteralNode::emitBytecode):
+ (JSC::PropertyListNode::emitBytecode):
+ (JSC::BracketAccessorNode::emitBytecode):
+ (JSC::DotAccessorNode::emitBytecode):
+ (JSC::ArgumentListNode::emitBytecode):
+ (JSC::NewExprNode::emitBytecode):
+ (JSC::EvalFunctionCallNode::emitBytecode):
+ (JSC::FunctionCallValueNode::emitBytecode):
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::FunctionCallBracketNode::emitBytecode):
+ (JSC::FunctionCallDotNode::emitBytecode):
+ (JSC::PostfixResolveNode::emitBytecode):
+ (JSC::PostfixBracketNode::emitBytecode):
+ (JSC::PostfixDotNode::emitBytecode):
+ (JSC::PostfixErrorNode::emitBytecode):
+ (JSC::DeleteResolveNode::emitBytecode):
+ (JSC::DeleteBracketNode::emitBytecode):
+ (JSC::DeleteDotNode::emitBytecode):
+ (JSC::DeleteValueNode::emitBytecode):
+ (JSC::VoidNode::emitBytecode):
+ (JSC::TypeOfResolveNode::emitBytecode):
+ (JSC::TypeOfValueNode::emitBytecode):
+ (JSC::PrefixResolveNode::emitBytecode):
+ (JSC::PrefixBracketNode::emitBytecode):
+ (JSC::PrefixDotNode::emitBytecode):
+ (JSC::PrefixErrorNode::emitBytecode):
+ (JSC::UnaryOpNode::emitBytecode):
+ (JSC::BinaryOpNode::emitBytecode):
+ (JSC::EqualNode::emitBytecode):
+ (JSC::StrictEqualNode::emitBytecode):
+ (JSC::ReverseBinaryOpNode::emitBytecode):
+ (JSC::ThrowableBinaryOpNode::emitBytecode):
+ (JSC::InstanceOfNode::emitBytecode):
+ (JSC::LogicalOpNode::emitBytecode):
+ (JSC::ConditionalNode::emitBytecode):
+ (JSC::emitReadModifyAssignment):
+ (JSC::ReadModifyResolveNode::emitBytecode):
+ (JSC::AssignResolveNode::emitBytecode):
+ (JSC::AssignDotNode::emitBytecode):
+ (JSC::ReadModifyDotNode::emitBytecode):
+ (JSC::AssignErrorNode::emitBytecode):
+ (JSC::AssignBracketNode::emitBytecode):
+ (JSC::ReadModifyBracketNode::emitBytecode):
+ (JSC::CommaNode::emitBytecode):
+ (JSC::ConstDeclNode::emitBytecode):
+ (JSC::ConstStatementNode::emitBytecode):
+ (JSC::BlockNode::emitBytecode):
+ (JSC::EmptyStatementNode::emitBytecode):
+ (JSC::DebuggerStatementNode::emitBytecode):
+ (JSC::ExprStatementNode::emitBytecode):
+ (JSC::VarStatementNode::emitBytecode):
+ (JSC::IfNode::emitBytecode):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::ContinueNode::emitBytecode):
+ (JSC::BreakNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::WithNode::emitBytecode):
+ (JSC::SwitchNode::emitBytecode):
+ (JSC::LabelNode::emitBytecode):
+ (JSC::ThrowNode::emitBytecode):
+ (JSC::TryNode::emitBytecode):
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::EvalNode::emitBytecode):
+ (JSC::FunctionBodyNode::emitBytecode):
+ (JSC::ProgramNode::emitBytecode):
+ (JSC::FuncDeclNode::emitBytecode):
+ (JSC::FuncExprNode::emitBytecode):
+ * parser/Nodes.h:
+ (JSC::UnaryPlusNode::):
+ (JSC::NegateNode::):
+ (JSC::BitwiseNotNode::):
+ (JSC::LogicalNotNode::):
+ (JSC::MultNode::):
+ (JSC::DivNode::):
+ (JSC::ModNode::):
+ (JSC::AddNode::):
+ (JSC::SubNode::):
+ (JSC::LeftShiftNode::):
+ (JSC::RightShiftNode::):
+ (JSC::UnsignedRightShiftNode::):
+ (JSC::LessNode::):
+ (JSC::GreaterNode::):
+ (JSC::LessEqNode::):
+ (JSC::GreaterEqNode::):
+ (JSC::InstanceOfNode::):
+ (JSC::InNode::):
+ (JSC::EqualNode::):
+ (JSC::NotEqualNode::):
+ (JSC::StrictEqualNode::):
+ (JSC::NotStrictEqualNode::):
+ (JSC::BitAndNode::):
+ (JSC::BitOrNode::):
+ (JSC::BitXOrNode::):
+ (JSC::ProgramNode::):
+ (JSC::EvalNode::):
+ (JSC::FunctionBodyNode::):
+ * runtime/JSNotAnObject.h:
+ * runtime/StructureID.cpp:
+ (JSC::StructureID::fromDictionaryTransition):
+ * wtf/Platform.h:
+
+2008-11-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Renamed Machine to BytecodeInterpreter.
+
+ Nixed the Interpreter class, and changed its two functions to stand-alone
+ functions.
+
+ * JavaScriptCore.exp:
+ * VM/CTI.cpp:
+ (JSC::):
+ (JSC::CTI::emitCTICall):
+ (JSC::CTI::CTI):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::emitSlowScriptCheck):
+ (JSC::CTI::compileBinaryArithOpSlowCase):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompile):
+ (JSC::CTI::privateCompileGetByIdSelf):
+ (JSC::CTI::privateCompileGetByIdProto):
+ (JSC::CTI::privateCompileGetByIdChain):
+ (JSC::CTI::privateCompilePutByIdReplace):
+ (JSC::CTI::privateCompilePutByIdTransition):
+ (JSC::CTI::privateCompileCTIMachineTrampolines):
+ (JSC::CTI::freeCTIMachineTrampolines):
+ (JSC::CTI::patchGetByIdSelf):
+ (JSC::CTI::patchPutByIdReplace):
+ (JSC::CTI::privateCompilePatchGetArrayLength):
+ (JSC::CTI::compileRegExp):
+ * VM/CTI.h:
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::printStructureIDs):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::derefStructureIDs):
+ (JSC::CodeBlock::refStructureIDs):
+ * VM/ExceptionHelpers.cpp:
+ (JSC::createNotAnObjectError):
+ * VM/Machine.cpp:
+ (JSC::jsLess):
+ (JSC::jsLessEq):
+ (JSC::BytecodeInterpreter::resolve):
+ (JSC::BytecodeInterpreter::resolveSkip):
+ (JSC::BytecodeInterpreter::resolveGlobal):
+ (JSC::BytecodeInterpreter::resolveBase):
+ (JSC::BytecodeInterpreter::resolveBaseAndProperty):
+ (JSC::BytecodeInterpreter::resolveBaseAndFunc):
+ (JSC::BytecodeInterpreter::slideRegisterWindowForCall):
+ (JSC::BytecodeInterpreter::callEval):
+ (JSC::BytecodeInterpreter::BytecodeInterpreter):
+ (JSC::BytecodeInterpreter::initialize):
+ (JSC::BytecodeInterpreter::~BytecodeInterpreter):
+ (JSC::BytecodeInterpreter::dumpCallFrame):
+ (JSC::BytecodeInterpreter::dumpRegisters):
+ (JSC::BytecodeInterpreter::isOpcode):
+ (JSC::BytecodeInterpreter::unwindCallFrame):
+ (JSC::BytecodeInterpreter::throwException):
+ (JSC::BytecodeInterpreter::execute):
+ (JSC::BytecodeInterpreter::debug):
+ (JSC::BytecodeInterpreter::resetTimeoutCheck):
+ (JSC::BytecodeInterpreter::checkTimeout):
+ (JSC::BytecodeInterpreter::createExceptionScope):
+ (JSC::BytecodeInterpreter::tryCachePutByID):
+ (JSC::BytecodeInterpreter::uncachePutByID):
+ (JSC::BytecodeInterpreter::tryCacheGetByID):
+ (JSC::BytecodeInterpreter::uncacheGetByID):
+ (JSC::BytecodeInterpreter::privateExecute):
+ (JSC::BytecodeInterpreter::retrieveArguments):
+ (JSC::BytecodeInterpreter::retrieveCaller):
+ (JSC::BytecodeInterpreter::retrieveLastCaller):
+ (JSC::BytecodeInterpreter::findFunctionCallFrame):
+ (JSC::BytecodeInterpreter::tryCTICachePutByID):
+ (JSC::BytecodeInterpreter::tryCTICacheGetByID):
+ (JSC::BytecodeInterpreter::cti_op_convert_this):
+ (JSC::BytecodeInterpreter::cti_op_end):
+ (JSC::BytecodeInterpreter::cti_op_add):
+ (JSC::BytecodeInterpreter::cti_op_pre_inc):
+ (JSC::BytecodeInterpreter::cti_timeout_check):
+ (JSC::BytecodeInterpreter::cti_register_file_check):
+ (JSC::BytecodeInterpreter::cti_op_loop_if_less):
+ (JSC::BytecodeInterpreter::cti_op_loop_if_lesseq):
+ (JSC::BytecodeInterpreter::cti_op_new_object):
+ (JSC::BytecodeInterpreter::cti_op_put_by_id):
+ (JSC::BytecodeInterpreter::cti_op_put_by_id_second):
+ (JSC::BytecodeInterpreter::cti_op_put_by_id_generic):
+ (JSC::BytecodeInterpreter::cti_op_put_by_id_fail):
+ (JSC::BytecodeInterpreter::cti_op_get_by_id):
+ (JSC::BytecodeInterpreter::cti_op_get_by_id_second):
+ (JSC::BytecodeInterpreter::cti_op_get_by_id_generic):
+ (JSC::BytecodeInterpreter::cti_op_get_by_id_fail):
+ (JSC::BytecodeInterpreter::cti_op_instanceof):
+ (JSC::BytecodeInterpreter::cti_op_del_by_id):
+ (JSC::BytecodeInterpreter::cti_op_mul):
+ (JSC::BytecodeInterpreter::cti_op_new_func):
+ (JSC::BytecodeInterpreter::cti_op_call_JSFunction):
+ (JSC::BytecodeInterpreter::cti_op_call_arityCheck):
+ (JSC::BytecodeInterpreter::cti_vm_dontLazyLinkCall):
+ (JSC::BytecodeInterpreter::cti_vm_lazyLinkCall):
+ (JSC::BytecodeInterpreter::cti_op_push_activation):
+ (JSC::BytecodeInterpreter::cti_op_call_NotJSFunction):
+ (JSC::BytecodeInterpreter::cti_op_create_arguments):
+ (JSC::BytecodeInterpreter::cti_op_create_arguments_no_params):
+ (JSC::BytecodeInterpreter::cti_op_tear_off_activation):
+ (JSC::BytecodeInterpreter::cti_op_tear_off_arguments):
+ (JSC::BytecodeInterpreter::cti_op_profile_will_call):
+ (JSC::BytecodeInterpreter::cti_op_profile_did_call):
+ (JSC::BytecodeInterpreter::cti_op_ret_scopeChain):
+ (JSC::BytecodeInterpreter::cti_op_new_array):
+ (JSC::BytecodeInterpreter::cti_op_resolve):
+ (JSC::BytecodeInterpreter::cti_op_construct_JSConstruct):
+ (JSC::BytecodeInterpreter::cti_op_construct_NotJSConstruct):
+ (JSC::BytecodeInterpreter::cti_op_get_by_val):
+ (JSC::BytecodeInterpreter::cti_op_resolve_func):
+ (JSC::BytecodeInterpreter::cti_op_sub):
+ (JSC::BytecodeInterpreter::cti_op_put_by_val):
+ (JSC::BytecodeInterpreter::cti_op_put_by_val_array):
+ (JSC::BytecodeInterpreter::cti_op_lesseq):
+ (JSC::BytecodeInterpreter::cti_op_loop_if_true):
+ (JSC::BytecodeInterpreter::cti_op_negate):
+ (JSC::BytecodeInterpreter::cti_op_resolve_base):
+ (JSC::BytecodeInterpreter::cti_op_resolve_skip):
+ (JSC::BytecodeInterpreter::cti_op_resolve_global):
+ (JSC::BytecodeInterpreter::cti_op_div):
+ (JSC::BytecodeInterpreter::cti_op_pre_dec):
+ (JSC::BytecodeInterpreter::cti_op_jless):
+ (JSC::BytecodeInterpreter::cti_op_not):
+ (JSC::BytecodeInterpreter::cti_op_jtrue):
+ (JSC::BytecodeInterpreter::cti_op_post_inc):
+ (JSC::BytecodeInterpreter::cti_op_eq):
+ (JSC::BytecodeInterpreter::cti_op_lshift):
+ (JSC::BytecodeInterpreter::cti_op_bitand):
+ (JSC::BytecodeInterpreter::cti_op_rshift):
+ (JSC::BytecodeInterpreter::cti_op_bitnot):
+ (JSC::BytecodeInterpreter::cti_op_resolve_with_base):
+ (JSC::BytecodeInterpreter::cti_op_new_func_exp):
+ (JSC::BytecodeInterpreter::cti_op_mod):
+ (JSC::BytecodeInterpreter::cti_op_less):
+ (JSC::BytecodeInterpreter::cti_op_neq):
+ (JSC::BytecodeInterpreter::cti_op_post_dec):
+ (JSC::BytecodeInterpreter::cti_op_urshift):
+ (JSC::BytecodeInterpreter::cti_op_bitxor):
+ (JSC::BytecodeInterpreter::cti_op_new_regexp):
+ (JSC::BytecodeInterpreter::cti_op_bitor):
+ (JSC::BytecodeInterpreter::cti_op_call_eval):
+ (JSC::BytecodeInterpreter::cti_op_throw):
+ (JSC::BytecodeInterpreter::cti_op_get_pnames):
+ (JSC::BytecodeInterpreter::cti_op_next_pname):
+ (JSC::BytecodeInterpreter::cti_op_push_scope):
+ (JSC::BytecodeInterpreter::cti_op_pop_scope):
+ (JSC::BytecodeInterpreter::cti_op_typeof):
+ (JSC::BytecodeInterpreter::cti_op_is_undefined):
+ (JSC::BytecodeInterpreter::cti_op_is_boolean):
+ (JSC::BytecodeInterpreter::cti_op_is_number):
+ (JSC::BytecodeInterpreter::cti_op_is_string):
+ (JSC::BytecodeInterpreter::cti_op_is_object):
+ (JSC::BytecodeInterpreter::cti_op_is_function):
+ (JSC::BytecodeInterpreter::cti_op_stricteq):
+ (JSC::BytecodeInterpreter::cti_op_nstricteq):
+ (JSC::BytecodeInterpreter::cti_op_to_jsnumber):
+ (JSC::BytecodeInterpreter::cti_op_in):
+ (JSC::BytecodeInterpreter::cti_op_push_new_scope):
+ (JSC::BytecodeInterpreter::cti_op_jmp_scopes):
+ (JSC::BytecodeInterpreter::cti_op_put_by_index):
+ (JSC::BytecodeInterpreter::cti_op_switch_imm):
+ (JSC::BytecodeInterpreter::cti_op_switch_char):
+ (JSC::BytecodeInterpreter::cti_op_switch_string):
+ (JSC::BytecodeInterpreter::cti_op_del_by_val):
+ (JSC::BytecodeInterpreter::cti_op_put_getter):
+ (JSC::BytecodeInterpreter::cti_op_put_setter):
+ (JSC::BytecodeInterpreter::cti_op_new_error):
+ (JSC::BytecodeInterpreter::cti_op_debug):
+ (JSC::BytecodeInterpreter::cti_vm_throw):
+ * VM/Machine.h:
+ * VM/Register.h:
+ * VM/SamplingTool.cpp:
+ (JSC::SamplingTool::run):
+ * VM/SamplingTool.h:
+ (JSC::SamplingTool::SamplingTool):
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::generate):
+ (JSC::CodeGenerator::CodeGenerator):
+ (JSC::CodeGenerator::emitOpcode):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::evaluate):
+ * jsc.cpp:
+ (runWithScripts):
+ * parser/Nodes.cpp:
+ (JSC::ScopeNode::ScopeNode):
+ * profiler/ProfileGenerator.cpp:
+ (JSC::ProfileGenerator::addParentForConsoleStart):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncPop):
+ (JSC::arrayProtoFuncPush):
+ * runtime/Collector.cpp:
+ (JSC::Heap::collect):
+ * runtime/ExecState.h:
+ (JSC::ExecState::interpreter):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncApply):
+ * runtime/Interpreter.cpp:
+ (JSC::Interpreter::evaluate):
+ * runtime/JSCell.h:
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::call):
+ (JSC::JSFunction::argumentsGetter):
+ (JSC::JSFunction::callerGetter):
+ (JSC::JSFunction::construct):
+ * runtime/JSFunction.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::~JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::~JSGlobalObject):
+ (JSC::JSGlobalObject::setTimeoutTime):
+ (JSC::JSGlobalObject::startTimeoutCheck):
+ (JSC::JSGlobalObject::stopTimeoutCheck):
+ (JSC::JSGlobalObject::mark):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncEval):
+ * runtime/JSString.h:
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+
+2008-11-15 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ - Remove SymbolTable from FunctionBodyNode and move it to CodeBlock
+
+ It's not needed for functions that have never been executed, so no
+ need to waste the memory. Saves ~4M on membuster after 30 pages.
+
+ * VM/CodeBlock.h:
+ * VM/Machine.cpp:
+ (JSC::Machine::retrieveArguments):
+ * parser/Nodes.cpp:
+ (JSC::EvalNode::generateCode):
+ (JSC::FunctionBodyNode::generateCode):
+ * parser/Nodes.h:
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::JSActivationData::JSActivationData):
+
+2008-11-14 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Bug 22259: Make all opcodes use eax as their final result register
+ <https://bugs.webkit.org/show_bug.cgi?id=22259>
+
+ Change one case of op_add (and the corresponding slow case) to use eax
+ rather than edx. Also, change the order in which the two results of
+ resolve_func and resolve_base are emitted so that the retrieved value is
+ put last into eax.
+
+ This gives no performance change on SunSpider or the V8 benchmark suite
+ when run in either harness.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+
+2008-11-14 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Geoff has this wacky notion that emitGetArg and emitPutArg should be related to
+ doing the same thing. Crazy.
+
+ Rename the methods for accessing virtual registers to say 'VirtualRegister' in the
+ name, and those for setting up the arguments for CTI methods to contain 'CTIArg'.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitGetVirtualRegister):
+ (JSC::CTI::emitGetVirtualRegisters):
+ (JSC::CTI::emitPutCTIArgFromVirtualRegister):
+ (JSC::CTI::emitPutCTIArg):
+ (JSC::CTI::emitGetCTIArg):
+ (JSC::CTI::emitPutCTIArgConstant):
+ (JSC::CTI::emitPutVirtualRegister):
+ (JSC::CTI::compileOpCallSetupArgs):
+ (JSC::CTI::compileOpCallEvalSetupArgs):
+ (JSC::CTI::compileOpConstructSetupArgs):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::compileOpStrictEq):
+ (JSC::CTI::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::compileBinaryArithOpSlowCase):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompileCTIMachineTrampolines):
+ * VM/CTI.h:
+
+2008-11-14 Greg Bolsinga <bolsinga@apple.com>
+
+ Reviewed by Antti Koivisto
+
+ Fix potential build break by adding StdLibExtras.h
+
+ * GNUmakefile.am:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+
+2008-11-14 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Generate less code for the slow cases of op_call and op_construct.
+ https://bugs.webkit.org/show_bug.cgi?id=22272
+
+ 1% progression on v8 tests.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitRetrieveArg):
+ (JSC::CTI::emitNakedCall):
+ (JSC::CTI::compileOpCallInitializeCallFrame):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompileCTIMachineTrampolines):
+ * VM/CTI.h:
+ * VM/CodeBlock.h:
+ (JSC::getCallLinkInfoReturnLocation):
+ (JSC::CodeBlock::getCallLinkInfo):
+ * VM/Machine.cpp:
+ (JSC::Machine::Machine):
+ (JSC::Machine::cti_vm_dontLazyLinkCall):
+ (JSC::Machine::cti_vm_lazyLinkCall):
+ * VM/Machine.h:
+
+2008-11-14 Greg Bolsinga <bolsinga@apple.com>
+
+ Reviewed by Darin Alder.
+
+ https://bugs.webkit.org/show_bug.cgi?id=21810
+ Remove use of static C++ objects that are destroyed at exit time (destructors)
+
+ Create DEFINE_STATIC_LOCAL macro. Change static local objects to leak to avoid
+ exit-time destructor. Update code that was changed to fix this issue that ran
+ into a gcc bug (<rdar://problem/6354696> Codegen issue with C++ static reference
+ in gcc build 5465). Also typdefs for template types needed to be added in some
+ cases so the type could make it through the macro successfully.
+
+ Basically code of the form:
+ static T m;
+ becomes:
+ DEFINE_STATIC_LOCAL(T, m, ());
+
+ Also any code of the form:
+ static T& m = *new T;
+ also becomes:
+ DEFINE_STATIC_LOCAL(T, m, ());
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/MainThread.cpp:
+ (WTF::mainThreadFunctionQueueMutex):
+ (WTF::functionQueue):
+ * wtf/StdLibExtras.h: Added. Add DEFINE_STATIC_LOCAL macro
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::threadMapMutex):
+ (WTF::threadMap):
+ (WTF::identifierByPthreadHandle):
+
+2008-11-13 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=22269
+ Reduce PropertyMap usage
+
+ From observation of StructureID statistics, it became clear that many
+ StructureID's were not being used as StructureIDs themselves, but rather
+ only being necessary as links in the transition chain. Acknowledging this
+ and that PropertyMaps stored in StructureIDs can be treated as caches, that
+ is that they can be reconstructed on demand, it became clear that we could
+ reduce the memory consumption of StructureIDs by only keeping PropertyMaps
+ for the StructureIDs that need them the most.
+
+ The specific strategy used to reduce the number of StructureIDs with
+ PropertyMaps is to take the previous StructureIDs PropertyMap when initially
+ transitioning (addPropertyTransition) from it and clearing out the pointer
+ in the process. The next time we need to do the same transition, for instance
+ repeated calls to the same constructor, we use the new addPropertyTransitionToExistingStructure
+ first, which allows us not to need the PropertyMap to determine if the property
+ exists already, since a transition to that property would require it not already
+ be present in the StructureID. Should there be no transition, the PropertyMap
+ can be constructed on demand (via materializePropertyMap) to determine if the put is a
+ replace or a transition to a new StructureID.
+
+ Reduces memory use on Membuster head test (30 pages open) by ~15MB.
+
+ * JavaScriptCore.exp:
+ * runtime/JSObject.h:
+ (JSC::JSObject::putDirect): First use addPropertyTransitionToExistingStructure
+ so that we can avoid building the PropertyMap on subsequent similar object
+ creations.
+ * runtime/PropertyMapHashTable.h:
+ (JSC::PropertyMapEntry::PropertyMapEntry): Add version of constructor which takes
+ all values to be used when lazily building the PropertyMap.
+ * runtime/StructureID.cpp:
+ (JSC::StructureID::dumpStatistics): Add statistics on the number of StructureIDs
+ with PropertyMaps.
+ (JSC::StructureID::StructureID): Rename m_cachedTransistionOffset to m_offset
+ (JSC::isPowerOf2):
+ (JSC::nextPowerOf2):
+ (JSC::sizeForKeyCount): Returns the expected size of a PropertyMap for a key count.
+ (JSC::StructureID::materializePropertyMap): Builds the PropertyMap out of its previous pointer chain.
+ (JSC::StructureID::addPropertyTransitionToExistingStructure): Only transitions if there is a
+ an existing transition.
+ (JSC::StructureID::addPropertyTransition): Instead of always copying the ProperyMap, try and take
+ it from it previous pointer.
+ (JSC::StructureID::removePropertyTransition): Simplify by calling toDictionaryTransition() to do
+ transition work.
+ (JSC::StructureID::changePrototypeTransition): Build the PropertyMap if necessary before transitioning
+ because once you have transitioned, you will not be able to reconstruct it afterwards as there is no
+ previous pointer, pinning the ProperyMap as well.
+ (JSC::StructureID::getterSetterTransition): Ditto.
+ (JSC::StructureID::toDictionaryTransition): Pin the PropertyMap so that it is not destroyed on further transitions.
+ (JSC::StructureID::fromDictionaryTransition): We can only transition back from a dictionary transition if there
+ are no deleted offsets.
+ (JSC::StructureID::addPropertyWithoutTransition): Build PropertyMap on demands and pin.
+ (JSC::StructureID::removePropertyWithoutTransition): Ditto.
+ (JSC::StructureID::get): Build on demand.
+ (JSC::StructureID::createPropertyMapHashTable): Add version of create that takes a size
+ for on demand building.
+ (JSC::StructureID::expandPropertyMapHashTable):
+ (JSC::StructureID::rehashPropertyMapHashTable):
+ (JSC::StructureID::getEnumerablePropertyNamesInternal): Build PropertyMap on demand.
+ * runtime/StructureID.h:
+ (JSC::StructureID::propertyStorageSize): Account for StructureIDs without PropertyMaps.
+ (JSC::StructureID::isEmpty): Ditto.
+ (JSC::StructureID::materializePropertyMapIfNecessary):
+ (JSC::StructureID::get): Build PropertyMap on demand
+
+2008-11-14 Csaba Osztrogonac <oszi@inf.u-szeged.hu>
+
+ Reviewed by Simon Hausmann.
+
+ <https://bugs.webkit.org/show_bug.cgi?id=21500>
+
+ JavaScriptCore build with -O3 flag instead of -O2 (gcc).
+ 2.02% speedup on SunSpider (Qt-port on Linux)
+ 1.10% speedup on V8 (Qt-port on Linux)
+ 3.45% speedup on WindScorpion (Qt-port on Linux)
+
+ * JavaScriptCore.pri:
+
+2008-11-14 Kristian Amlie <kristian.amlie@trolltech.com>
+
+ Reviewed by Darin Adler.
+
+ Compile fix for RVCT.
+
+ In reality, it is two fixes:
+
+ 1. Remove typename. I believe typename can only be used when the named
+ type depends on the template parameters, which it doesn't in this
+ case, so I think this is more correct.
+ 2. Replace ::iterator scope with specialized typedef. This is to work
+ around a bug in RVCT.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22260
+
+ * wtf/ListHashSet.h:
+ (WTF::::find):
+
+2008-11-14 Kristian Amlie <kristian.amlie@trolltech.com>
+
+ Reviewed by Darin Adler.
+
+ Compile fix for WINSCW.
+
+ This fix doesn't protect against implicit conversions from bool to
+ integers, but most likely that will be caught on another platform.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22260
+
+ * wtf/PassRefPtr.h:
+ (WTF::PassRefPtr::operator bool):
+ * wtf/RefPtr.h:
+ (WTF::RefPtr::operator bool):
+
+2008-11-14 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Bug 22245: Move wtf/dtoa.h into the WTF namespace
+ <https://bugs.webkit.org/show_bug.cgi?id=22245>
+
+ Move wtf/dtoa.h into the WTF namespace from the JSC namespace. This
+ introduces some ambiguities in name lookups, so I changed all uses of
+ the functions in wtf/dtoa.h to explicitly state the namespace.
+
+ * JavaScriptCore.exp:
+ * parser/Lexer.cpp:
+ (JSC::Lexer::lex):
+ * runtime/InitializeThreading.cpp:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::parseInt):
+ * runtime/NumberPrototype.cpp:
+ (JSC::integerPartNoExp):
+ (JSC::numberProtoFuncToExponential):
+ * runtime/UString.cpp:
+ (JSC::concatenate):
+ (JSC::UString::from):
+ (JSC::UString::toDouble):
+ * wtf/dtoa.cpp:
+ * wtf/dtoa.h:
+
+2008-11-14 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Bug 22257: Enable redundant read optimizations for results generated by compileBinaryArithOp()
+ <https://bugs.webkit.org/show_bug.cgi?id=22257>
+
+ This shows no change in performance on either SunSpider or the V8
+ benchmark suite, but it removes an ugly special case and allows for
+ future optimizations to be implemented in a cleaner fashion.
+
+ This patch was essentially given to me by Gavin Barraclough upon my
+ request, but I did regression and performance testing so that he could
+ work on something else.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::putDoubleResultToJSNumberCellOrJSImmediate): Move the final
+ result to eax if it is not already there.
+ (JSC::CTI::compileBinaryArithOp): Remove the killing of the final result
+ register that disables the optimization.
+
+2008-11-13 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Roben.
+
+ Add a Scons-based build system for building
+ the Chromium-Mac build of JavaScriptCore.
+ https://bugs.webkit.org/show_bug.cgi?id=21991
+
+ * JavaScriptCore.scons: Added.
+ * SConstruct: Added.
+
+2008-11-13 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Roben.
+
+ Add PLATFORM(CHROMIUM) to the "we don't use cairo" blacklist
+ until https://bugs.webkit.org/show_bug.cgi?id=22250 is fixed.
+
+ * wtf/Platform.h:
+
+2008-11-13 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ In r38375 the 'jsc' shell was changed to improve teardown on quit. The
+ main() function in jsc.cpp uses Structured Exception Handling, so Visual
+ C++ emits a warning when destructors are used.
+
+ In order to speculatively fix the Windows build, this patch changes that
+ code to use explicit pointer manipulation and locking rather than smart
+ pointers and RAII.
+
+ * jsc.cpp:
+ (main):
+
+2008-11-13 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Bug 22246: Get arguments for opcodes together to eliminate more redundant memory reads
+ <https://bugs.webkit.org/show_bug.cgi?id=22246>
+
+ It is common for opcodes to read their first operand into eax and their
+ second operand into edx. If the value intended for the second operand is
+ in eax, we should first move eax to the register for the second operand
+ and then read the first operand into eax.
+
+ This is a 0.5% speedup on SunSpider and a 2.0% speedup on the V8
+ benchmark suite when measured using the V8 harness.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitGetArgs):
+ (JSC::CTI::compileOpStrictEq):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ * VM/CTI.h:
+
+2008-11-13 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Bug 22238: Avoid unnecessary reads of temporaries when the target machine register is not eax
+ <https://bugs.webkit.org/show_bug.cgi?id=22238>
+
+ Enable the optimization of not reading a value back from memory that we
+ just wrote when the target machine register is not eax. In order to do
+ this, the code generation for op_put_global_var must be changed to
+ read its argument into a register before overwriting eax.
+
+ This is a 0.5% speedup on SunSpider and shows no change on the V8
+ benchmark suite when run in either harness.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitGetArg):
+ (JSC::CTI::privateCompileMainPass):
+
+2008-11-13 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Perform teardown in the 'jsc' shell in order to suppress annoying and
+ misleading leak messages. There is still a lone JSC::Node leaking when
+ quit() is called, but hopefully that can be fixed as well.
+
+ * jsc.cpp:
+ (functionQuit):
+ (main):
+
+2008-11-13 Mike Pinkerton <pinkerton@chromium.org>
+
+ Reviewed by Sam Weinig.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=22087
+ Need correct platform defines for Mac Chromium
+
+ Set the appropriate platform defines for Mac Chromium, which is
+ similar to PLATFORM(MAC), but isn't.
+
+ * wtf/Platform.h:
+
+2008-11-13 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ - remove immediate checks from native codegen for known non-immediate cases like "this"
+
+ ~.5% speedup on v8 benchmarks
+
+ In the future we can extend this model to remove all sorts of
+ typechecks based on local type info or type inference.
+
+ I also added an assertion to verify that all slow cases linked as
+ many slow case jumps as the corresponding fast case generated, and
+ fixed the pre-existing cases where this was not true.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitJumpSlowCaseIfNotJSCell):
+ (JSC::CTI::linkSlowCaseIfNotJSCell):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::compileBinaryArithOpSlowCase):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ * VM/CTI.h:
+ * VM/CodeBlock.h:
+ (JSC::CodeBlock::isKnownNotImmediate):
+
+2008-11-13 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Bug 21943: Avoid needless reads of temporary values in CTI code
+ <https://bugs.webkit.org/show_bug.cgi?id=21943>
+
+ If an opcode needs to load a virtual register and a previous opcode left
+ the contents of that virtual register in a machine register, use the
+ value in the machine register rather than getting it from memory.
+
+ In order to perform this optimization, it is necessary to know the
+ jump tagets in the CodeBlock. For temporaries, the only problematic
+ jump targets are binary logical operators and the ternary conditional
+ operator. However, if this optimization were to be extended to local
+ variable registers as well, other jump targets would need to be
+ included, like switch statement cases and the beginnings of catch
+ blocks.
+
+ This optimization also requires that the fast case and the slow case
+ of an opcode use emitPutResult() on the same register, which was chosen
+ to be eax, as that is the register into which we read the first operand
+ of opcodes. In order to make this the case, we needed to add some mov
+ instructions to the slow cases of some instructions.
+
+ This optimizaton is not applied whenever compileBinaryArithOp() is used
+ to compile an opcode, because different machine registers may be used to
+ store the final result. It seems possible to rewrite the code generation
+ in compileBinaryArithOp() to allow for this optimization.
+
+ This optimization is also not applied when generating slow cases,
+ because some fast cases overwrite the value of eax before jumping to the
+ slow case. In the future, it may be possible to apply this optimization
+ to slow cases as well, but it did not seem to be a speedup when testing
+ an early version of this patch.
+
+ This is a 1.0% speedup on SunSpider and a 6.3% speedup on the V8
+ benchmark suite.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::killLastResultRegister):
+ (JSC::CTI::emitGetArg):
+ (JSC::CTI::emitGetPutArg):
+ (JSC::CTI::emitGetCTIParam):
+ (JSC::CTI::emitGetFromCallFrameHeader):
+ (JSC::CTI::emitPutResult):
+ (JSC::CTI::emitCTICall):
+ (JSC::CTI::CTI):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::compileOpStrictEq):
+ (JSC::CTI::emitSlowScriptCheck):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ (JSC::CTI::privateCompileGetByIdProto):
+ (JSC::CTI::privateCompilePatchGetArrayLength):
+ * VM/CTI.h:
+ * VM/CodeBlock.h:
+ (JSC::CodeBlock::isTemporaryRegisterIndex):
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::emitLabel):
+
+2008-11-12 Alp Toker <alp@nuanti.com>
+
+ autotools build system fix-up only. Add FloatQuad.h to the source
+ lists and sort them.
+
+ * GNUmakefile.am:
+
+2008-11-12 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixed https://bugs.webkit.org/show_bug.cgi?id=22192
+ +37 failures in fast/profiler
+
+ along with Darin's review comments in
+ https://bugs.webkit.org/show_bug.cgi?id=22174
+ Simplified op_call by nixing its responsibility for moving the value of
+ "this" into the first argument slot
+
+ * VM/Machine.cpp:
+ (JSC::returnToThrowTrampoline):
+ (JSC::throwStackOverflowError):
+ (JSC::Machine::cti_register_file_check):
+ (JSC::Machine::cti_op_call_arityCheck):
+ (JSC::Machine::cti_vm_throw): Moved the throw logic into a function, since
+ functions are better than macros.
+
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::emitCall):
+ (JSC::CodeGenerator::emitConstruct): Ensure that the function register
+ is preserved if profiling is enabled, since the profiler uses that
+ register.
+
+ * runtime/JSGlobalData.h: Renamed throwReturnAddress to exceptionLocation,
+ because I had a hard time understanding what "throwReturnAddress" meant.
+
+2008-11-12 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Roll in r38322, now that test failures have been fixed.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::compileOpCallSetupArgs):
+ (JSC::CTI::compileOpCallEvalSetupArgs):
+ (JSC::CTI::compileOpConstructSetupArgs):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ * VM/CTI.h:
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * VM/Machine.cpp:
+ (JSC::Machine::callEval):
+ (JSC::Machine::dumpCallFrame):
+ (JSC::Machine::dumpRegisters):
+ (JSC::Machine::execute):
+ (JSC::Machine::privateExecute):
+ (JSC::Machine::cti_register_file_check):
+ (JSC::Machine::cti_op_call_arityCheck):
+ (JSC::Machine::cti_op_call_NotJSFunction):
+ (JSC::Machine::cti_op_construct_JSConstruct):
+ (JSC::Machine::cti_op_construct_NotJSConstruct):
+ (JSC::Machine::cti_op_call_eval):
+ (JSC::Machine::cti_vm_throw):
+ * VM/Machine.h:
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::emitCall):
+ (JSC::CodeGenerator::emitCallEval):
+ (JSC::CodeGenerator::emitConstruct):
+ * bytecompiler/CodeGenerator.h:
+ * parser/Nodes.cpp:
+ (JSC::EvalFunctionCallNode::emitCode):
+ (JSC::FunctionCallValueNode::emitCode):
+ (JSC::FunctionCallResolveNode::emitCode):
+ (JSC::FunctionCallBracketNode::emitCode):
+ (JSC::FunctionCallDotNode::emitCode):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::neededConstants):
+
+2008-11-12 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=22201
+ Integer conversion in array.length was safe signed values,
+ but the length is unsigned.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::privateCompilePatchGetArrayLength):
+
+2008-11-12 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Mark Rowe.
+
+ Roll out r38322 due to test failures on the bots.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::compileOpCallSetupArgs):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases):
+ * VM/CTI.h:
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * VM/Machine.cpp:
+ (JSC::Machine::callEval):
+ (JSC::Machine::dumpCallFrame):
+ (JSC::Machine::dumpRegisters):
+ (JSC::Machine::execute):
+ (JSC::Machine::privateExecute):
+ (JSC::Machine::throwStackOverflowPreviousFrame):
+ (JSC::Machine::cti_register_file_check):
+ (JSC::Machine::cti_op_call_arityCheck):
+ (JSC::Machine::cti_op_call_NotJSFunction):
+ (JSC::Machine::cti_op_construct_JSConstruct):
+ (JSC::Machine::cti_op_construct_NotJSConstruct):
+ (JSC::Machine::cti_op_call_eval):
+ (JSC::Machine::cti_vm_throw):
+ * VM/Machine.h:
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::emitCall):
+ (JSC::CodeGenerator::emitCallEval):
+ (JSC::CodeGenerator::emitConstruct):
+ * bytecompiler/CodeGenerator.h:
+ * parser/Nodes.cpp:
+ (JSC::EvalFunctionCallNode::emitCode):
+ (JSC::FunctionCallValueNode::emitCode):
+ (JSC::FunctionCallResolveNode::emitCode):
+ (JSC::FunctionCallBracketNode::emitCode):
+ (JSC::FunctionCallDotNode::emitCode):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::neededConstants):
+
+2008-11-11 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Fixed https://bugs.webkit.org/show_bug.cgi?id=22174
+ Simplified op_call by nixing its responsibility for moving the value of
+ "this" into the first argument slot.
+
+ Instead, the caller emits an explicit load or mov instruction, or relies
+ on implicit knowledge that "this" is already in the first argument slot.
+ As a result, two operands to op_call are gone: firstArg and thisVal.
+
+ SunSpider and v8 tests show no change in bytecode or CTI.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::compileOpCallSetupArgs):
+ (JSC::CTI::compileOpCallEvalSetupArgs):
+ (JSC::CTI::compileOpConstructSetupArgs): Split apart these three versions
+ of setting up arguments to op_call, because they're more different than
+ they are the same -- even more so with this patch.
+
+ (JSC::CTI::compileOpCall): Updated for the fact that op_construct doesn't
+ match op_call anymore.
+
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileSlowCases): Merged a few call cases. Updated
+ for changes mentioned above.
+
+ * VM/CTI.h:
+
+ * VM/CodeBlock.cpp:
+ (JSC::CodeBlock::dump): Updated for new bytecode format of call / construct.
+
+ * VM/Machine.cpp:
+ (JSC::Machine::callEval): Updated for new bytecode format of call / construct.
+
+ (JSC::Machine::dumpCallFrame):
+ (JSC::Machine::dumpRegisters): Simplified these debugging functions,
+ taking advantage of the new call frame layout.
+
+ (JSC::Machine::execute): Fixed up the eval version of execute to be
+ friendlier to calls in the new format.
+
+ (JSC::Machine::privateExecute): Implemented the new call format in
+ bytecode.
+
+ (JSC::Machine::cti_op_call_NotJSFunction):
+ (JSC::Machine::cti_op_construct_JSConstruct):
+ (JSC::Machine::cti_op_construct_NotJSConstruct):
+ (JSC::Machine::cti_op_call_eval): Updated CTI helpers to match the new
+ call format.
+
+ Fixed a latent bug in stack overflow checking that is now hit because
+ the register layout has changed a bit -- namely: when throwing a stack
+ overflow exception inside an op_call helper, we need to account for the
+ fact that the current call frame is only half-constructed, and use the
+ parent call frame instead.
+
+ * VM/Machine.h:
+
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::emitCall):
+ (JSC::CodeGenerator::emitCallEval):
+ (JSC::CodeGenerator::emitConstruct):
+ * bytecompiler/CodeGenerator.h: Updated codegen to match the new call
+ format.
+
+ * parser/Nodes.cpp:
+ (JSC::EvalFunctionCallNode::emitCode):
+ (JSC::FunctionCallValueNode::emitCode):
+ (JSC::FunctionCallResolveNode::emitCode):
+ (JSC::FunctionCallBracketNode::emitCode):
+ (JSC::FunctionCallDotNode::emitCode):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::neededConstants): ditto
+
+2008-11-11 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Remove an unused forwarding header for a file that no longer exists.
+
+ * ForwardingHeaders/JavaScriptCore/JSLock.h: Removed.
+
+2008-11-11 Mark Rowe <mrowe@apple.com>
+
+ Fix broken dependencies building JavaScriptCore on a freezing cold cat, caused
+ by failure to update all instances of "kjs" to their new locations.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2008-11-11 Alexey Proskuryakov <ap@webkit.org>
+
+ Rubber-stamped by Adam Roben.
+
+ * wtf/AVLTree.h: (WTF::AVLTree::Iterator::start_iter):
+ Fix indentation a little more.
+
+2008-11-11 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Sam Weinig.
+
+ Clean up EvalCodeCache to match our coding style a bit more.
+
+ * VM/EvalCodeCache.h:
+ (JSC::EvalCodeCache::get):
+
+2008-11-11 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Sam Weinig.
+
+ Bug 22179: Move EvalCodeCache from CodeBlock.h into its own file
+ <https://bugs.webkit.org/show_bug.cgi?id=22179>
+
+ * GNUmakefile.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * VM/CodeBlock.h:
+ * VM/EvalCodeCache.h: Copied from VM/CodeBlock.h.
+ * VM/Machine.cpp:
+
+2008-11-11 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Remove the 'm_' prefix from the fields of the SwitchRecord struct.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::privateCompile):
+ * VM/CTI.h:
+ (JSC::SwitchRecord):
+ (JSC::SwitchRecord::SwitchRecord):
+
+2008-11-11 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Sam Weinig.
+
+ Make asInteger() a static function so that it has internal linkage.
+
+ * VM/CTI.cpp:
+ (JSC::asInteger):
+
+2008-11-11 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ - shrink CodeBlock and AST related Vectors to exact fit (5-10M savings on membuster test)
+
+ No perf regression combined with the last patch (each seems like a small regression individually)
+
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::generate):
+ * parser/Nodes.h:
+ (JSC::SourceElements::releaseContentsIntoVector):
+ * wtf/Vector.h:
+ (WTF::Vector::shrinkToFit):
+
+2008-11-11 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ - remove inline capacity from declaration stacks (15M savings on membuster test)
+
+ No perf regression on SunSpider or V8 test combined with other upcoming memory improvement patch.
+
+ * JavaScriptCore.exp:
+ * parser/Nodes.h:
+
+2008-11-11 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ While r38286 removed the need for the m_callFrame member variable of
+ CTI, it should be also be removed.
+
+ * VM/CTI.h:
+
+2008-11-10 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Make CTI::asInteger() a non-member function, since it needs no access to
+ any of CTI's member variables.
+
+ * VM/CTI.cpp:
+ (JSC::asInteger):
+ * VM/CTI.h:
+
+2008-11-10 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Use 'value' instead of 'js' in CTI as a name for JSValue* to match our
+ usual convention elsewhere.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitGetArg):
+ (JSC::CTI::emitGetPutArg):
+ (JSC::CTI::getConstantImmediateNumericArg):
+ (JSC::CTI::printOpcodeOperandTypes):
+
+2008-11-10 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Make CTI::getConstant() a member function of CodeBlock instead.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitGetArg):
+ (JSC::CTI::emitGetPutArg):
+ (JSC::CTI::getConstantImmediateNumericArg):
+ (JSC::CTI::printOpcodeOperandTypes):
+ (JSC::CTI::privateCompileMainPass):
+ * VM/CTI.h:
+ * VM/CodeBlock.h:
+ (JSC::CodeBlock::getConstant):
+
+2008-11-10 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Rename CodeBlock::isConstant() to isConstantRegisterIndex().
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitGetArg):
+ (JSC::CTI::emitGetPutArg):
+ (JSC::CTI::getConstantImmediateNumericArg):
+ (JSC::CTI::printOpcodeOperandTypes):
+ (JSC::CTI::privateCompileMainPass):
+ * VM/CodeBlock.h:
+ (JSC::CodeBlock::isConstantRegisterIndex):
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::emitEqualityOp):
+
+2008-11-10 Gavin Barraclough <barraclough@apple.com>
+
+ Build fix for non-CTI builds.
+
+ * VM/Machine.cpp:
+ (JSC::Machine::initialize):
+
+2008-11-10 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Remove the unused labels member variable of CodeBlock.
+
+ * VM/CodeBlock.h:
+ * VM/LabelID.h:
+ (JSC::LabelID::setLocation):
+
+2008-11-10 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Batch compile the set of static trampolines at the point Machine is constructed, using a single allocation.
+ Refactor out m_callFrame from CTI, since this is only needed to access the global data (instead store a
+ pointer to the global data directly, since this is available at the point the Machine is constructed).
+ Add a method to align the code buffer, to allow JIT generation for multiple trampolines in one block.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::getConstant):
+ (JSC::CTI::emitGetArg):
+ (JSC::CTI::emitGetPutArg):
+ (JSC::CTI::getConstantImmediateNumericArg):
+ (JSC::CTI::printOpcodeOperandTypes):
+ (JSC::CTI::CTI):
+ (JSC::CTI::compileBinaryArithOp):
+ (JSC::CTI::privateCompileMainPass):
+ (JSC::CTI::privateCompileGetByIdProto):
+ (JSC::CTI::privateCompileGetByIdChain):
+ (JSC::CTI::privateCompileCTIMachineTrampolines):
+ (JSC::CTI::freeCTIMachineTrampolines):
+ * VM/CTI.h:
+ (JSC::CTI::compile):
+ (JSC::CTI::compileGetByIdSelf):
+ (JSC::CTI::compileGetByIdProto):
+ (JSC::CTI::compileGetByIdChain):
+ (JSC::CTI::compilePutByIdReplace):
+ (JSC::CTI::compilePutByIdTransition):
+ (JSC::CTI::compileCTIMachineTrampolines):
+ (JSC::CTI::compilePatchGetArrayLength):
+ * VM/Machine.cpp:
+ (JSC::Machine::initialize):
+ (JSC::Machine::~Machine):
+ (JSC::Machine::execute):
+ (JSC::Machine::tryCTICachePutByID):
+ (JSC::Machine::tryCTICacheGetByID):
+ (JSC::Machine::cti_op_call_JSFunction):
+ (JSC::Machine::cti_vm_lazyLinkCall):
+ * VM/Machine.h:
+ * masm/X86Assembler.h:
+ (JSC::JITCodeBuffer::isAligned):
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::align):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+
+2008-11-10 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Antti Koivisto.
+
+ - Make Vector::clear() release the Vector's memory (1MB savings on membuster)
+ https://bugs.webkit.org/show_bug.cgi?id=22170
+
+ * wtf/Vector.h:
+ (WTF::VectorBufferBase::deallocateBuffer): Set capacity to 0 as
+ well as size, otherwise shrinking capacity to 0 can fail to reset
+ the capacity and thus cause a future crash.
+ (WTF::Vector::~Vector): Shrink size not capacity; we only need
+ to call destructors, the buffer will be freed anyway.
+ (WTF::Vector::clear): Change this to shrinkCapacity(0), not just shrink(0).
+ (WTF::::shrinkCapacity): Use shrink() instead of resize() for case where
+ the size is greater than the new capacity, to work with types that have no
+ default constructor.
+
+2008-11-10 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Split multiple definitions into separate lines.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::compileBinaryArithOp):
+
+2008-11-10 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 22162: Remove cachedValueGetter from the JavaScriptCore API implementation
+ <https://bugs.webkit.org/show_bug.cgi?id=22162>
+
+ There is no more need for the cachedValueGetter hack now that we have
+ PropertySlot::setValue(), so we should remove it.
+
+ * API/JSCallbackObject.h:
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::getOwnPropertySlot):
+
+2008-11-10 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Bug 22152: Remove asObject() call from JSCallbackObject::getOwnPropertySlot()
+ <https://bugs.webkit.org/show_bug.cgi?id=22152>
+
+ With the recent change to adopt asType() style cast functions with
+ assertions instead of static_casts in many places, the assertion for
+ the asObject() call in JSCallbackObject::getOwnPropertySlot() has been
+ failing when using any nontrivial client of the JavaScriptCore API.
+ The cast isn't even necessary to call slot.setCustom(), so it should
+ be removed.
+
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::JSCallbackObject::getOwnPropertySlot):
+
+2008-11-10 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Adam Roben.
+
+ A few coding style fixes for AVLTree.
+
+ * wtf/AVLTree.h: Moved to WTF namespace, Removed "KJS_" from include guards.
+ (WTF::AVLTree::Iterator::start_iter): Fixed indentation
+
+ * runtime/JSArray.cpp: Added "using namepace WTF".
+
+2008-11-09 Cameron Zwarich <zwarich@apple.com>
+
+ Not reviewed.
+
+ Speculatively fix the non-AllInOne build.
+
+ * runtime/NativeErrorConstructor.cpp:
+
+2008-11-09 Darin Adler <darin@apple.com>
+
+ Reviewed by Tim Hatcher.
+
+ - https://bugs.webkit.org/show_bug.cgi?id=22149
+ remove unused code from the parser
+
+ * AllInOneFile.cpp: Removed nodes2string.cpp.
+ * GNUmakefile.am: Ditto.
+ * JavaScriptCore.exp: Ditto.
+ * JavaScriptCore.pri: Ditto.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
+ * JavaScriptCoreSources.bkl: Ditto.
+
+ * VM/CodeBlock.h: Added include.
+
+ * VM/Machine.cpp: (JSC::Machine::execute): Use the types from
+ DeclarationStacks as DeclarationStacks:: rather than Node:: since
+ "Node" really has little to do with it.
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::CodeGenerator): Ditto.
+
+ * jsc.cpp:
+ (Options::Options): Removed prettyPrint option.
+ (runWithScripts): Ditto.
+ (printUsageStatement): Ditto.
+ (parseArguments): Ditto.
+ (jscmain): Ditto.
+
+ * parser/Grammar.y: Removed use of obsolete ImmediateNumberNode.
+
+ * parser/Nodes.cpp:
+ (JSC::ThrowableExpressionData::emitThrowError): Use inline functions
+ instead of direct member access for ThrowableExpressionData values.
+ (JSC::BracketAccessorNode::emitCode): Ditto.
+ (JSC::DotAccessorNode::emitCode): Ditto.
+ (JSC::NewExprNode::emitCode): Ditto.
+ (JSC::EvalFunctionCallNode::emitCode): Ditto.
+ (JSC::FunctionCallValueNode::emitCode): Ditto.
+ (JSC::FunctionCallResolveNode::emitCode): Ditto.
+ (JSC::FunctionCallBracketNode::emitCode): Ditto.
+ (JSC::FunctionCallDotNode::emitCode): Ditto.
+ (JSC::PostfixResolveNode::emitCode): Ditto.
+ (JSC::PostfixBracketNode::emitCode): Ditto.
+ (JSC::PostfixDotNode::emitCode): Ditto.
+ (JSC::DeleteResolveNode::emitCode): Ditto.
+ (JSC::DeleteBracketNode::emitCode): Ditto.
+ (JSC::DeleteDotNode::emitCode): Ditto.
+ (JSC::PrefixResolveNode::emitCode): Ditto.
+ (JSC::PrefixBracketNode::emitCode): Ditto.
+ (JSC::PrefixDotNode::emitCode): Ditto.
+ (JSC::ThrowableBinaryOpNode::emitCode): Ditto.
+ (JSC::InstanceOfNode::emitCode): Ditto.
+ (JSC::ReadModifyResolveNode::emitCode): Ditto.
+ (JSC::AssignResolveNode::emitCode): Ditto.
+ (JSC::AssignDotNode::emitCode): Ditto.
+ (JSC::ReadModifyDotNode::emitCode): Ditto.
+ (JSC::AssignBracketNode::emitCode): Ditto.
+ (JSC::ReadModifyBracketNode::emitCode): Ditto.
+ (JSC::statementListEmitCode): Take a const StatementVector instead
+ of a non-const one. Also removed unused statementListPushFIFO.
+ (JSC::ForInNode::emitCode): Inline functions instead of member access.
+ (JSC::ThrowNode::emitCode): Ditto.
+ (JSC::EvalNode::emitCode): Ditto.
+ (JSC::FunctionBodyNode::emitCode): Ditto.
+ (JSC::ProgramNode::emitCode): Ditto.
+
+ * parser/Nodes.h: Removed unused includes and forward declarations.
+ Removed Precedence enum. Made many more members private instead of
+ protected or public. Removed unused NodeStack typedef. Moved the
+ VarStack and FunctionStack typedefs from Node to ScopeNode. Made
+ Node::emitCode pure virtual and changed classes that don't emit
+ any code to inherit from ParserRefCounted rather than Node.
+ Moved isReturnNode from Node to StatementNode. Removed the
+ streamTo, precedence, and needsParensIfLeftmost functions from
+ all classes. Removed the ImmediateNumberNode class and make
+ NumberNode::setValue nonvirtual.
+
+ * parser/nodes2string.cpp: Removed.
+
+2008-11-09 Darin Adler <darin@apple.com>
+
+ Reviewed by Sam Weinig and Maciej Stachowiak.
+ Includes some work done by Chris Brichford.
+
+ - fix https://bugs.webkit.org/show_bug.cgi?id=14886
+ Stack overflow due to deeply nested parse tree doing repeated string concatentation
+
+ Test: fast/js/large-expressions.html
+
+ 1) Code generation is recursive, so takes stack proportional to the complexity
+ of the source code expression. Fixed by setting an arbitrary recursion limit
+ of 10,000 nodes.
+
+ 2) Destruction of the syntax tree was recursive. Fixed by introducing a
+ non-recursive mechanism for destroying the tree.
+
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::CodeGenerator): Initialize depth to 0.
+ (JSC::CodeGenerator::emitThrowExpressionTooDeepException): Added. Emits the code
+ to throw a "too deep" exception.
+ * bytecompiler/CodeGenerator.h:
+ (JSC::CodeGenerator::emitNode): Check depth and emit an exception if we exceed
+ the maximum depth.
+
+ * parser/Nodes.cpp:
+ (JSC::NodeReleaser::releaseAllNodes): Added. To be called inside node destructors
+ to avoid recursive calls to destructors for nodes inside this one.
+ (JSC::NodeReleaser::release): Added. To be called inside releaseNodes functions.
+ Also added releaseNodes functions and calls to releaseAllNodes inside destructors
+ for each class derived from Node that has RefPtr to other nodes.
+ (JSC::NodeReleaser::adopt): Added. Used by the release function.
+ (JSC::NodeReleaser::adoptFunctionBodyNode): Added.
+
+ * parser/Nodes.h: Added declarations of releaseNodes and destructors in all classes
+ that needed it. Eliminated use of ListRefPtr and releaseNext, which are the two parts
+ of an older solution to the non-recursive destruction problem that works only for
+ lists, whereas the new solution works for other graphs. Changed ReverseBinaryOpNode
+ to use BinaryOpNode as a base class to avoid some duplicated code.
+
+2008-11-08 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fixes after addition of JSCore parser and bycompiler dirs. Also cleanup
+ the JSCore Bakefile's group names to be consistent.
+
+ * JavaScriptCoreSources.bkl:
+ * jscore.bkl:
+
+2008-11-07 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 21801: REGRESSION (r37821): YUI date formatting JavaScript puts the letter 'd' in place of the day
+ <https://bugs.webkit.org/show_bug.cgi?id=21801>
+
+ Fix the constant register check in the 'typeof' optimization in
+ CodeGenerator, which was completely broken after r37821.
+
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::emitEqualityOp):
+
+2008-11-07 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 22129: Move CTI::isConstant() to CodeBlock
+ <https://bugs.webkit.org/show_bug.cgi?id=22129>
+
+ * VM/CTI.cpp:
+ (JSC::CTI::emitGetArg):
+ (JSC::CTI::emitGetPutArg):
+ (JSC::CTI::getConstantImmediateNumericArg):
+ (JSC::CTI::printOpcodeOperandTypes):
+ (JSC::CTI::privateCompileMainPass):
+ * VM/CTI.h:
+ * VM/CodeBlock.h:
+ (JSC::CodeBlock::isConstant):
+
+2008-11-07 Alp Toker <alp@nuanti.com>
+
+ autotools fix. Always use the configured perl binary (which may be
+ different to the one in $PATH) when generating sources.
+
+ * GNUmakefile.am:
+
+2008-11-07 Cameron Zwarich <zwarich@apple.com>
+
+ Not reviewed.
+
+ Change grammar.cpp to Grammar.cpp and grammar.h to Grammar.h in several
+ build scripts.
+
+ * DerivedSources.make:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCoreSources.bkl:
+
+2008-11-07 Alp Toker <alp@nuanti.com>
+
+ More grammar.cpp -> Grammar.cpp build fixes.
+
+ * AllInOneFile.cpp:
+ * GNUmakefile.am:
+
+2008-11-07 Simon Hausmann <hausmann@webkit.org>
+
+ Fix the build on case-sensitive file systems. grammar.y was renamed to
+ Grammar.y but Lexer.cpp includes grammar.h. The build bots didn't
+ notice this change because of stale files.
+
+ * parser/Lexer.cpp:
+
+2008-11-07 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Rename the m_nextGlobal, m_nextParameter, and m_nextConstant member
+ variables of CodeGenerator to m_nextGlobalIndex, m_nextParameterIndex,
+ and m_nextConstantIndex respectively. This is to distinguish these from
+ member variables like m_lastConstant, which are actually RefPtrs to
+ Registers.
+
+ * bytecompiler/CodeGenerator.cpp:
+ (JSC::CodeGenerator::addGlobalVar):
+ (JSC::CodeGenerator::allocateConstants):
+ (JSC::CodeGenerator::CodeGenerator):
+ (JSC::CodeGenerator::addParameter):
+ (JSC::CodeGenerator::addConstant):
+ * bytecompiler/CodeGenerator.h:
+
+2008-11-06 Gavin Barraclough barraclough@apple.com
+
+ Reviewed by Oliver Hunt.
+
+ Do not make a cti_* call to perform an op_call unless either:
+ (1) The codeblock for the function body has not been generated.
+ (2) The number of arguments passed does not match the callee arity.
+
+ ~1% progression on sunspider --v8
+
+ * VM/CTI.cpp:
+ (JSC::CTI::compileOpCallInitializeCallFrame):
+ (JSC::CTI::compileOpCall):
+ (JSC::CTI::privateCompileSlowCases):
+ * VM/CTI.h:
+ * VM/Machine.cpp:
+ (JSC::Machine::cti_op_call_JSFunction):
+ (JSC::Machine::cti_op_call_arityCheck):
+ (JSC::Machine::cti_op_construct_JSConstruct):
+ * VM/Machine.h:
+ * kjs/nodes.h:
+
+2008-11-06 Cameron Zwarich <zwarich@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Move the remaining files in the kjs subdirectory of JavaScriptCore to
+ a new parser subdirectory, and remove the kjs subdirectory entirely.
+
+ * AllInOneFile.cpp:
+ * DerivedSources.make:
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * VM/CodeBlock.h:
+ * VM/ExceptionHelpers.cpp:
+ * VM/SamplingTool.h:
+ * bytecompiler/CodeGenerator.h:
+ * jsc.pro:
+ * jscore.bkl:
+ * kjs: Removed.
+ * kjs/NodeInfo.h: Removed.
+ * kjs/Parser.cpp: Removed.
+ * kjs/Parser.h: Removed.
+ * kjs/ResultType.h: Removed.
+ * kjs/SourceCode.h: Removed.
+ * kjs/SourceProvider.h: Removed.
+ * kjs/grammar.y: Removed.
+ * kjs/keywords.table: Removed.
+ * kjs/lexer.cpp: Removed.
+ * kjs/lexer.h: Removed.
+ * kjs/nodes.cpp: Removed.
+ * kjs/nodes.h: Removed.
+ * kjs/nodes2string.cpp: Removed.
+ * parser: Added.
+ * parser/Grammar.y: Copied from kjs/grammar.y.
+ * parser/Keywords.table: Copied from kjs/keywords.table.
+ * parser/Lexer.cpp: Copied from kjs/lexer.cpp.
+ * parser/Lexer.h: Copied from kjs/lexer.h.
+ * parser/NodeInfo.h: Copied from kjs/NodeInfo.h.
+ * parser/Nodes.cpp: Copied from kjs/nodes.cpp.
+ * parser/Nodes.h: Copied from kjs/nodes.h.
+ * parser/Parser.cpp: Copied from kjs/Parser.cpp.
+ * parser/Parser.h: Copied from kjs/Parser.h.
+ * parser/ResultType.h: Copied from kjs/ResultType.h.
+ * parser/SourceCode.h: Copied from kjs/SourceCode.h.
+ * parser/SourceProvider.h: Copied from kjs/SourceProvider.h.
+ * parser/nodes2string.cpp: Copied from kjs/nodes2string.cpp.
+ * pcre/pcre.pri:
+ * pcre/pcre_exec.cpp:
+ * runtime/FunctionConstructor.cpp:
+ * runtime/JSActivation.h:
+ * runtime/JSFunction.h:
+ * runtime/JSGlobalData.cpp:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::toNumber):
+ * runtime/RegExp.cpp:
+
+2008-11-06 Adam Roben <aroben@apple.com>
+
+ Windows build fix after r38196
+
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj: Added bytecompiler/ to the
+ include path.
+
+2008-11-06 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Sam Weinig.
+
+ Create a new bytecompiler subdirectory of JavaScriptCore and move some
+ relevant files to it.
+
+ * AllInOneFile.cpp:
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * VM/CodeGenerator.cpp: Removed.
+ * VM/CodeGenerator.h: Removed.
+ * bytecompiler: Added.
+ * bytecompiler/CodeGenerator.cpp: Copied from VM/CodeGenerator.cpp.
+ * bytecompiler/CodeGenerator.h: Copied from VM/CodeGenerator.h.
+ * bytecompiler/LabelScope.h: Copied from kjs/LabelScope.h.
+ * jscore.bkl:
+ * kjs/LabelScope.h: Removed.
+
+2008-11-06 Adam Roben <aroben@apple.com>
+
+ Windows clean build fix after r38155
+
+ Rubberstamped by Cameron Zwarich.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Update
+ the post-build event for the move of create_hash_table out of kjs/.
+
+2008-11-06 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22107
+
+ Bug uncovered during RVCT port in functions not used. get_lt() and
+ get_gt() takes only one argument - remove second argument where
+ applicable.
+
+ * wtf/AVLTree.h:
+ (JSC::AVLTree::remove): Remove second argument of get_lt/get_gt().
+ (JSC::AVLTree::subst): Ditto.
+
+2008-11-06 Alp Toker <alp@nuanti.com>
+
+ Reviewed by Cameron Zwarich.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22033
+ [GTK] CTI/Linux r38064 crashes; JIT requires executable memory
+
+ Mark pages allocated by the FastMalloc mmap code path executable with
+ PROT_EXEC. This fixes crashes seen on CPUs and kernels that enforce
+ non-executable memory (like ExecShield on Fedora Linux) when the JIT
+ is enabled.
+
+ This patch does not resolve the issue on debug builds so affected
+ developers may still need to pass --disable-jit to configure.
+
+ * wtf/TCSystemAlloc.cpp:
+ (TryMmap):
+ (TryDevMem):
+ (TCMalloc_SystemRelease):
+
+2008-11-06 Peter Gal <galpeter@inf.u-szeged.hu>
+
+ Reviewed by Cameron Zwarich.
+
+ Bug 22099: Make the Qt port build the JSC shell in the correct place
+ <https://bugs.webkit.org/show_bug.cgi?id=22099>
+
+ Adjust include paths and build destination dir for the 'jsc' executable
+ in the Qt build.
+
+ * jsc.pro:
+
+2008-11-06 Kristian Amlie <kristian.amlie@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Implemented the block allocation on Symbian through heap allocation.
+
+ Unfortunately there is no way to allocate virtual memory. The Posix
+ layer provides mmap() but no anonymous mapping. So this is a very slow
+ solution but it should work as a start.
+
+ * runtime/Collector.cpp:
+ (JSC::allocateBlock):
+ (JSC::freeBlock):
+
+2008-11-06 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Borrow some math functions from the MSVC port to the build with the
+ RVCT compiler.
+
+ * wtf/MathExtras.h:
+ (isinf):
+ (isnan):
+ (signbit):
+
+2008-11-06 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Include strings.h for strncasecmp().
+ This is needed for compilation inside Symbian and it is also
+ confirmed by the man-page on Linux.
+
+ * runtime/DateMath.cpp:
+
+2008-11-06 Norbert Leser <norbert.leser@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Implemented currentThreadStackBase for Symbian.
+
+ * runtime/Collector.cpp:
+ (JSC::currentThreadStackBase):
+
+2008-11-06 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ RVCT does not support tm_gmtoff field, so disable that code just like
+ for MSVC.
+
+ * runtime/DateMath.h:
+ (JSC::GregorianDateTime::GregorianDateTime):
+ (JSC::GregorianDateTime::operator tm):
+
+2008-11-06 Kristian Amlie <kristian.amlie@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Define PLATFORM(UNIX) for S60. Effectively WebKit on S60 is compiled
+ on top of the Posix layer.
+
+ * wtf/Platform.h:
+
+2008-11-06 Norbert Leser <norbert.leser@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Added __SYMBIAN32__ condition for defining PLATFORM(SYMBIAN).
+
+ * wtf/Platform.h:
+
+2008-11-06 Ariya Hidayat <ariya.hidayat@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ Added WINSCW compiler define for Symbian S60.
+
+ * wtf/Platform.h:
+
+2008-11-06 Kristian Amlie <kristian.amlie@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Use the GCC defines of the WTF_ALIGN* macros for the RVCT and the
+ MINSCW compiler.
+
+ * wtf/Vector.h:
+
+2008-11-06 Kristian Amlie <kristian.amlie@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Define capabilities of the SYMBIAN platform. Some of the system
+ headers are actually dependent on RVCT.
+
+ * wtf/Platform.h:
+
+2008-11-06 Kristian Amlie <kristian.amlie@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Add missing stddef.h header needed for compilation in Symbian.
+
+ * runtime/Collector.h:
+
+2008-11-06 Kristian Amlie <kristian.amlie@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Added COMPILER(RVCT) to detect the ARM RVCT compiler used in the Symbian environment.
+
+ * wtf/Platform.h:
+
+2008-11-06 Simon Hausmann <hausmann@webkit.org>
+
+ Fix the Qt build, adjust include paths after move of jsc.pro.
+
+ * jsc.pro:
+
+2008-11-06 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Sam Weinig.
+
+ Move kjs/Shell.cpp to the top level of the JavaScriptCore directory and
+ rename it to jsc.cpp to reflect the name of the binary compiled from it.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * jsc.cpp: Copied from kjs/Shell.cpp.
+ * jsc.pro:
+ * jscore.bkl:
+ * kjs/Shell.cpp: Removed.
+
+2008-11-06 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Sam Weinig.
+
+ Move create_hash_table and jsc.pro out of the kjs directory and into the
+ root directory of JavaScriptCore.
+
+ * DerivedSources.make:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * create_hash_table: Copied from kjs/create_hash_table.
+ * jsc.pro: Copied from kjs/jsc.pro.
+ * kjs/create_hash_table: Removed.
+ * kjs/jsc.pro: Removed.
+ * make-generated-sources.sh:
+
+2008-11-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22094
+
+ Fix for bug where the callee incorrectly recieves the caller's lexical
+ global object as this, rather than its own. Implementation closely
+ follows the spec, passing jsNull, checking in the callee and replacing
+ with the global object where necessary.
+
+ * VM/CTI.cpp:
+ (JSC::CTI::compileOpCall):
+ * VM/Machine.cpp:
+ (JSC::Machine::cti_op_call_NotJSFunction):
+ (JSC::Machine::cti_op_call_eval):
+ * runtime/JSCell.h:
+ (JSC::JSValue::toThisObject):
+ * runtime/JSImmediate.cpp:
+ (JSC::JSImmediate::toThisObject):
+ * runtime/JSImmediate.h:
+
+2008-11-05 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fix after Operations.cpp move.
+
+ * JavaScriptCoreSources.bkl:
+
+2008-11-05 Cameron Zwarich <zwarich@apple.com>
+
+ Not reviewed.
+
+ Fix the build for case-sensitive build systems and wxWindows.
+
+ * JavaScriptCoreSources.bkl:
+ * kjs/create_hash_table:
+
+2008-11-05 Cameron Zwarich <zwarich@apple.com>
+
+ Not reviewed.
+
+ Fix the build for case-sensitive build systems.
+
+ * JavaScriptCoreSources.bkl:
+ * kjs/Shell.cpp:
+ * runtime/Interpreter.cpp:
+ * runtime/JSArray.cpp:
+
+2008-11-05 Cameron Zwarich <zwarich@apple.com>
+
+ Not reviewed.
+
+ Fix the build for case-sensitive build systems.
+
+ * API/JSBase.cpp:
+ * API/JSObjectRef.cpp:
+ * runtime/CommonIdentifiers.h:
+ * runtime/Identifier.cpp:
+ * runtime/InitializeThreading.cpp:
+ * runtime/InternalFunction.h:
+ * runtime/JSString.h:
+ * runtime/Lookup.h:
+ * runtime/PropertyNameArray.h:
+ * runtime/PropertySlot.h:
+ * runtime/StructureID.cpp:
+ * runtime/StructureID.h:
+ * runtime/UString.cpp:
+
+2008-11-05 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Sam Weinig.
+
+ Move more files to the runtime subdirectory of JavaScriptCore.
+
+ * API/APICast.h:
+ * API/JSBase.cpp:
+ * API/JSCallbackObject.cpp:
+ * API/JSClassRef.cpp:
+ * API/JSClassRef.h:
+ * API/JSStringRefCF.cpp:
+ * API/JSValueRef.cpp:
+ * API/OpaqueJSString.cpp:
+ * API/OpaqueJSString.h:
+ * AllInOneFile.cpp:
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * VM/CodeBlock.h:
+ * VM/CodeGenerator.cpp:
+ * VM/Machine.cpp:
+ * VM/RegisterFile.h:
+ * debugger/Debugger.h:
+ * kjs/SourceProvider.h:
+ * kjs/TypeInfo.h: Removed.
+ * kjs/collector.cpp: Removed.
+ * kjs/collector.h: Removed.
+ * kjs/completion.h: Removed.
+ * kjs/create_hash_table:
+ * kjs/identifier.cpp: Removed.
+ * kjs/identifier.h: Removed.
+ * kjs/interpreter.cpp: Removed.
+ * kjs/interpreter.h: Removed.
+ * kjs/lexer.cpp:
+ * kjs/lexer.h:
+ * kjs/lookup.cpp: Removed.
+ * kjs/lookup.h: Removed.
+ * kjs/nodes.cpp:
+ * kjs/nodes.h:
+ * kjs/operations.cpp: Removed.
+ * kjs/operations.h: Removed.
+ * kjs/protect.h: Removed.
+ * kjs/regexp.cpp: Removed.
+ * kjs/regexp.h: Removed.
+ * kjs/ustring.cpp: Removed.
+ * kjs/ustring.h: Removed.
+ * pcre/pcre_exec.cpp:
+ * profiler/CallIdentifier.h:
+ * profiler/Profile.h:
+ * runtime/ArrayConstructor.cpp:
+ * runtime/ArrayPrototype.cpp:
+ * runtime/ArrayPrototype.h:
+ * runtime/Collector.cpp: Copied from kjs/collector.cpp.
+ * runtime/Collector.h: Copied from kjs/collector.h.
+ * runtime/CollectorHeapIterator.h:
+ * runtime/Completion.h: Copied from kjs/completion.h.
+ * runtime/ErrorPrototype.cpp:
+ * runtime/Identifier.cpp: Copied from kjs/identifier.cpp.
+ * runtime/Identifier.h: Copied from kjs/identifier.h.
+ * runtime/InitializeThreading.cpp:
+ * runtime/Interpreter.cpp: Copied from kjs/interpreter.cpp.
+ * runtime/Interpreter.h: Copied from kjs/interpreter.h.
+ * runtime/JSCell.h:
+ * runtime/JSGlobalData.cpp:
+ * runtime/JSGlobalData.h:
+ * runtime/JSLock.cpp:
+ * runtime/JSNumberCell.cpp:
+ * runtime/JSNumberCell.h:
+ * runtime/JSObject.cpp:
+ * runtime/JSValue.h:
+ * runtime/Lookup.cpp: Copied from kjs/lookup.cpp.
+ * runtime/Lookup.h: Copied from kjs/lookup.h.
+ * runtime/MathObject.cpp:
+ * runtime/NativeErrorPrototype.cpp:
+ * runtime/NumberPrototype.cpp:
+ * runtime/Operations.cpp: Copied from kjs/operations.cpp.
+ * runtime/Operations.h: Copied from kjs/operations.h.
+ * runtime/PropertyMapHashTable.h:
+ * runtime/Protect.h: Copied from kjs/protect.h.
+ * runtime/RegExp.cpp: Copied from kjs/regexp.cpp.
+ * runtime/RegExp.h: Copied from kjs/regexp.h.
+ * runtime/RegExpConstructor.cpp:
+ * runtime/RegExpObject.h:
+ * runtime/RegExpPrototype.cpp:
+ * runtime/SmallStrings.h:
+ * runtime/StringObjectThatMasqueradesAsUndefined.h:
+ * runtime/StructureID.cpp:
+ * runtime/StructureID.h:
+ * runtime/StructureIDTransitionTable.h:
+ * runtime/SymbolTable.h:
+ * runtime/TypeInfo.h: Copied from kjs/TypeInfo.h.
+ * runtime/UString.cpp: Copied from kjs/ustring.cpp.
+ * runtime/UString.h: Copied from kjs/ustring.h.
+ * wrec/CharacterClassConstructor.h:
+ * wrec/WREC.h:
+
+2008-11-05 Geoffrey Garen <ggaren@apple.com>
+
+ Suggested by Darin Adler.
+
+ Removed two copy constructors that the compiler can generate for us
+ automatically.
+
+ * VM/LabelID.h:
+ (JSC::LabelID::setLocation):
+ (JSC::LabelID::offsetFrom):
+ (JSC::LabelID::ref):
+ (JSC::LabelID::refCount):
+ * kjs/LabelScope.h:
+
+2008-11-05 Anders Carlsson <andersca@apple.com>
+
+ Fix Snow Leopard build.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2008-11-04 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Steve Falkenburg.
+
+ Move dtoa.cpp and dtoa.h to the WTF Visual Studio project to reflect
+ their movement in the filesystem.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+
+2008-11-04 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Sam Weinig.
+
+ Move kjs/dtoa.h to the wtf subdirectory of JavaScriptCore.
+
+ * AllInOneFile.cpp:
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * kjs/dtoa.cpp: Removed.
+ * kjs/dtoa.h: Removed.
+ * wtf/dtoa.cpp: Copied from kjs/dtoa.cpp.
+ * wtf/dtoa.h: Copied from kjs/dtoa.h.
+
+2008-11-04 Cameron Zwarich <zwarich@apple.com>
+
+ Rubber-stamped by Sam Weinig.
+
+ Move kjs/config.h to the top level of JavaScriptCore.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * config.h: Copied from kjs/config.h.
+ * kjs/config.h: Removed.
+
+2008-11-04 Darin Adler <darin@apple.com>
+
+ Reviewed by Tim Hatcher.
+
+ * wtf/ThreadingNone.cpp: Tweak formatting.
+
+2008-11-03 Darin Adler <darin@apple.com>
+
+ Reviewed by Tim Hatcher.
+
+ - https://bugs.webkit.org/show_bug.cgi?id=22061
+ create script to check for exit-time destructors
+
+ * JavaScriptCore.exp: Changed to export functions rather than
+ a global for the atomically initialized static mutex.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Added a script
+ phase that runs the check-for-exit-time-destructors script.
+
+ * wtf/MainThread.cpp:
+ (WTF::mainThreadFunctionQueueMutex): Changed to leak an object
+ rather than using an exit time destructor.
+ (WTF::functionQueue): Ditto.
+ * wtf/unicode/icu/CollatorICU.cpp:
+ (WTF::cachedCollatorMutex): Ditto.
+
+ * wtf/Threading.h: Changed other platforms to share the Windows
+ approach where the mutex is internal and the functions are exported.
+ * wtf/ThreadingGtk.cpp:
+ (WTF::lockAtomicallyInitializedStaticMutex): Ditto.
+ (WTF::unlockAtomicallyInitializedStaticMutex): Ditto.
+ * wtf/ThreadingNone.cpp:
+ (WTF::lockAtomicallyInitializedStaticMutex): Ditto.
+ (WTF::unlockAtomicallyInitializedStaticMutex): Ditto.
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::threadMapMutex): Changed to leak an object rather than using
+ an exit time destructor.
+ (WTF::lockAtomicallyInitializedStaticMutex): Mutex change.
+ (WTF::unlockAtomicallyInitializedStaticMutex): Ditto.
+ (WTF::threadMap): Changed to leak an object rather than using
+ an exit time destructor.
+ * wtf/ThreadingQt.cpp:
+ (WTF::lockAtomicallyInitializedStaticMutex): Mutex change.
+ (WTF::unlockAtomicallyInitializedStaticMutex): Ditto.
+ * wtf/ThreadingWin.cpp:
+ (WTF::lockAtomicallyInitializedStaticMutex): Added an assertion.
+
2008-11-04 Adam Roben <aroben@apple.com>
Windows build fix
@@ -7667,7 +21201,7 @@
2008-09-23 Maciej Stachowiak <mjs@apple.com>
- Reviewed by Camron Zwarich.
+ Reviewed by Cameron Zwarich.
- inline the fast case of instanceof
https://bugs.webkit.org/show_bug.cgi?id=20818
diff --git a/JavaScriptCore/Configurations/Base.xcconfig b/JavaScriptCore/Configurations/Base.xcconfig
index 0abb45d..4154cb8 100644
--- a/JavaScriptCore/Configurations/Base.xcconfig
+++ b/JavaScriptCore/Configurations/Base.xcconfig
@@ -10,6 +10,7 @@ GCC_ENABLE_SYMBOL_SEPARATION = NO;
GCC_FAST_OBJC_DISPATCH = YES;
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
GCC_MODEL_TUNING = G5;
+GCC_OBJC_CALL_CXX_CDTORS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST $(GCC_PREPROCESSOR_DEFINITIONS);
GCC_STRICT_ALIASING = YES;
@@ -23,7 +24,7 @@ LINKER_DISPLAYS_MANGLED_NAMES = YES;
PREBINDING = NO;
VALID_ARCHS = i386 ppc x86_64 ppc64;
WARNING_CFLAGS = $(WARNING_CFLAGS_$(CURRENT_ARCH));
-WARNING_CFLAGS_BASE = -Wall -W -Wcast-align -Wchar-subscripts -Wformat-security -Wmissing-format-attribute -Wpointer-arith -Wwrite-strings -Wno-format-y2k -Wundef;
+WARNING_CFLAGS_BASE = -Wall -Wextra -Wcast-align -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings;
WARNING_CFLAGS_ = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
WARNING_CFLAGS_i386 = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
WARNING_CFLAGS_ppc = $(WARNING_CFLAGS_BASE) -Wshorten-64-to-32;
@@ -52,6 +53,10 @@ DEAD_CODE_STRIPPING_normal = YES;
DEAD_CODE_STRIPPING = $(DEAD_CODE_STRIPPING_$(CURRENT_VARIANT));
+GCC_VERSION = $(GCC_VERSION_$(XCODE_VERSION_ACTUAL));
+GCC_VERSION_0310 = 4.2;
+
+
// <rdar://problem/5488678>: Production builds on 10.4 PowerPC need to have debugging symbols disabled to prevent a huge STABS section being generated.
// Xcode on 10.4 does not define MAC_OS_X_VERSION_MAJOR, so the default Mac OS X version is treated as 10.4.
GCC_GENERATE_DEBUGGING_SYMBOLS = $(GCC_GENERATE_DEBUGGING_SYMBOLS_$(CURRENT_ARCH));
diff --git a/JavaScriptCore/Configurations/DebugRelease.xcconfig b/JavaScriptCore/Configurations/DebugRelease.xcconfig
index 0515da4..cbb2933 100644
--- a/JavaScriptCore/Configurations/DebugRelease.xcconfig
+++ b/JavaScriptCore/Configurations/DebugRelease.xcconfig
@@ -8,7 +8,3 @@ MACOSX_DEPLOYMENT_TARGET_1050 = 10.5;
MACOSX_DEPLOYMENT_TARGET_1060 = 10.6;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
-
-GCC_VERSION = $(GCC_VERSION_$(XCODE_VERSION_ACTUAL));
-GCC_VERSION_0310 = 4.2;
-GCC_VERSION_0311 = 4.2;
diff --git a/JavaScriptCore/Configurations/JavaScriptCore.xcconfig b/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
index 8e3d3c0..ef199d2 100644
--- a/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
+++ b/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
@@ -13,8 +13,11 @@ INSTALL_PATH = $(SYSTEM_LIBRARY_DIR)/Frameworks;
PRODUCT_NAME = JavaScriptCore;
// This needs to be kept sorted, and in sync with FEATURE_DEFINES in WebCore.xcconfig, WebKit.xcconfig and the default settings of build-webkit.
-FEATURE_DEFINES = ENABLE_DATABASE ENABLE_DOM_STORAGE ENABLE_ICONDATABASE ENABLE_OFFLINE_WEB_APPLICATIONS ENABLE_SVG ENABLE_SVG_ANIMATION ENABLE_SVG_AS_IMAGE ENABLE_SVG_FONTS ENABLE_SVG_FOREIGN_OBJECT ENABLE_SVG_USE ENABLE_VIDEO ENABLE_XPATH ENABLE_XSLT;
+FEATURE_DEFINES = ENABLE_DATABASE ENABLE_DOM_STORAGE ENABLE_ICONDATABASE ENABLE_OFFLINE_WEB_APPLICATIONS ENABLE_SVG ENABLE_SVG_ANIMATION ENABLE_SVG_AS_IMAGE ENABLE_SVG_FONTS ENABLE_SVG_FOREIGN_OBJECT ENABLE_SVG_USE ENABLE_VIDEO ENABLE_WORKERS ENABLE_XPATH ENABLE_XSLT;
OTHER_CFLAGS = $(OTHER_CFLAGS_$(CONFIGURATION)_$(CURRENT_VARIANT));
-OTHER_CFLAGS_Release_normal = -fomit-frame-pointer;
-OTHER_CFLAGS_Production_normal = -fomit-frame-pointer;
+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_normal_GCC_42 = -fomit-frame-pointer -funwind-tables;
diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig
index 16698b9..16a349c 100644
--- a/JavaScriptCore/Configurations/Version.xcconfig
+++ b/JavaScriptCore/Configurations/Version.xcconfig
@@ -1,5 +1,5 @@
MAJOR_VERSION = 528;
-MINOR_VERSION = 5;
+MINOR_VERSION = 15;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/JavaScriptCore/DerivedSources.make b/JavaScriptCore/DerivedSources.make
index e152979..4b33682 100644
--- a/JavaScriptCore/DerivedSources.make
+++ b/JavaScriptCore/DerivedSources.make
@@ -1,4 +1,4 @@
-# Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+# Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -25,11 +25,13 @@
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
VPATH = \
- $(JavaScriptCore)/kjs \
- $(JavaScriptCore)/VM \
+ $(JavaScriptCore) \
+ $(JavaScriptCore)/parser \
$(JavaScriptCore)/pcre \
$(JavaScriptCore)/docs \
$(JavaScriptCore)/runtime \
+ $(JavaScriptCore)/interpreter \
+ $(JavaScriptCore)/jit \
#
.PHONY : all
@@ -37,37 +39,37 @@ all : \
ArrayPrototype.lut.h \
chartables.c \
DatePrototype.lut.h \
- grammar.cpp \
- lexer.lut.h \
+ Grammar.cpp \
+ Lexer.lut.h \
MathObject.lut.h \
NumberConstructor.lut.h \
RegExpConstructor.lut.h \
RegExpObject.lut.h \
StringPrototype.lut.h \
- $(JavaScriptCore)/docs/bytecode.html \
+ docs/bytecode.html \
#
# lookup tables for classes
%.lut.h: create_hash_table %.cpp
$^ -i > $@
-lexer.lut.h: create_hash_table keywords.table
+Lexer.lut.h: create_hash_table Keywords.table
$^ > $@
# JavaScript language grammar
-grammar.cpp: grammar.y
- bison -d -p kjsyy $< -o $@ > bison_out.txt 2>&1
- perl -p -e 'END { if ($$conflict) { unlink "grammar.cpp"; die; } } $$conflict ||= /conflict/' < bison_out.txt
- touch grammar.cpp.h
- touch grammar.hpp
- cat grammar.cpp.h grammar.hpp > grammar.h
- rm -f grammar.cpp.h grammar.hpp bison_out.txt
+Grammar.cpp: Grammar.y
+ bison -d -p jscyy $< -o $@ > bison_out.txt 2>&1
+ perl -p -e 'END { if ($$conflict) { unlink "Grammar.cpp"; die; } } $$conflict ||= /conflict/' < bison_out.txt
+ touch Grammar.cpp.h
+ touch Grammar.hpp
+ cat Grammar.cpp.h Grammar.hpp > Grammar.h
+ rm -f Grammar.cpp.h Grammar.hpp bison_out.txt
# character tables for PCRE
chartables.c : dftables
$^ $@
-$(JavaScriptCore)/docs/bytecode.html: make-bytecode-docs.pl Machine.cpp
+docs/bytecode.html: make-bytecode-docs.pl Interpreter.cpp
perl $^ $@
diff --git a/JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSLock.h b/JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSLock.h
deleted file mode 100644
index 8519612..0000000
--- a/JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSLock.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <kjs/JSLock.h>
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index 2c52190..3d90470 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -1,14 +1,20 @@
javascriptcore_cppflags += \
-I$(srcdir)/JavaScriptCore/API \
-I$(srcdir)/JavaScriptCore/ForwardingHeaders \
- -I$(srcdir)/JavaScriptCore/VM \
+ -I$(srcdir)/JavaScriptCore/interpreter \
+ -I$(srcdir)/JavaScriptCore/bytecode \
+ -I$(srcdir)/JavaScriptCore/bytecompiler \
-I$(srcdir)/JavaScriptCore/debugger \
+ -I$(srcdir)/JavaScriptCore/jit \
-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/unicode \
-I$(top_builddir)/JavaScriptCore/pcre \
- -I$(top_builddir)/JavaScriptCore/kjs \
+ -I$(top_builddir)/JavaScriptCore/parser \
-I$(top_builddir)/JavaScriptCore/runtime
javascriptcore_h_api += \
@@ -24,7 +30,7 @@ javascriptcore_h_api += \
JavaScriptCore/API/WebKitAvailability.h
javascriptcore_built_nosources += \
- DerivedSources/lexer.lut.h \
+ DerivedSources/Lexer.lut.h \
JavaScriptCore/runtime/ArrayPrototype.lut.h \
JavaScriptCore/runtime/DatePrototype.lut.h \
JavaScriptCore/runtime/MathObject.lut.h \
@@ -67,27 +73,40 @@ javascriptcore_sources += \
JavaScriptCore/ForwardingHeaders/JavaScriptCore/OpaqueJSString.h \
JavaScriptCore/ForwardingHeaders/JavaScriptCore/WebKitAvailability.h \
JavaScriptCore/JavaScriptCorePrefix.h \
- JavaScriptCore/VM/CTI.cpp \
- JavaScriptCore/VM/CTI.h \
- JavaScriptCore/VM/CodeBlock.cpp \
- JavaScriptCore/VM/CodeBlock.h \
- JavaScriptCore/VM/CodeGenerator.h \
- JavaScriptCore/VM/ExceptionHelpers.cpp \
- JavaScriptCore/VM/ExceptionHelpers.h \
- JavaScriptCore/VM/Instruction.h \
- JavaScriptCore/runtime/JSPropertyNameIterator.cpp \
- JavaScriptCore/runtime/JSPropertyNameIterator.h \
- JavaScriptCore/VM/LabelID.h \
- JavaScriptCore/VM/Machine.cpp \
- JavaScriptCore/VM/Machine.h \
- JavaScriptCore/VM/Opcode.cpp \
- JavaScriptCore/VM/Opcode.h \
- JavaScriptCore/VM/Register.h \
- JavaScriptCore/VM/RegisterFile.h \
- JavaScriptCore/VM/RegisterID.h \
- JavaScriptCore/VM/SamplingTool.cpp \
- JavaScriptCore/VM/SamplingTool.h \
- JavaScriptCore/VM/SegmentedVector.h \
+ JavaScriptCore/jit/ExecutableAllocator.h \
+ JavaScriptCore/jit/JIT.cpp \
+ JavaScriptCore/jit/JITCall.cpp \
+ JavaScriptCore/jit/JITPropertyAccess.cpp \
+ JavaScriptCore/jit/JITArithmetic.cpp \
+ JavaScriptCore/jit/ExecutableAllocator.cpp \
+ JavaScriptCore/jit/ExecutableAllocatorPosix.cpp \
+ JavaScriptCore/jit/JIT.h \
+ JavaScriptCore/jit/JITInlineMethods.h \
+ JavaScriptCore/bytecode/StructureStubInfo.cpp \
+ JavaScriptCore/bytecode/StructureStubInfo.h \
+ JavaScriptCore/bytecode/CodeBlock.cpp \
+ JavaScriptCore/bytecode/CodeBlock.h \
+ JavaScriptCore/bytecode/JumpTable.cpp \
+ JavaScriptCore/bytecode/JumpTable.h \
+ JavaScriptCore/bytecode/EvalCodeCache.h \
+ JavaScriptCore/runtime/ExceptionHelpers.cpp \
+ JavaScriptCore/runtime/ExceptionHelpers.h \
+ JavaScriptCore/bytecode/Instruction.h \
+ JavaScriptCore/bytecompiler/Label.h \
+ JavaScriptCore/interpreter/Interpreter.cpp \
+ JavaScriptCore/interpreter/Interpreter.h \
+ JavaScriptCore/bytecode/Opcode.cpp \
+ JavaScriptCore/bytecode/Opcode.h \
+ JavaScriptCore/interpreter/Register.h \
+ JavaScriptCore/bytecompiler/RegisterID.h \
+ JavaScriptCore/bytecode/SamplingTool.cpp \
+ JavaScriptCore/bytecode/SamplingTool.h \
+ JavaScriptCore/bytecompiler/SegmentedVector.h \
+ JavaScriptCore/config.h \
+ JavaScriptCore/debugger/DebuggerActivation.cpp \
+ JavaScriptCore/debugger/DebuggerActivation.h \
+ JavaScriptCore/debugger/DebuggerCallFrame.cpp \
+ JavaScriptCore/debugger/DebuggerCallFrame.h \
JavaScriptCore/icu/unicode/parseerr.h \
JavaScriptCore/icu/unicode/platform.h \
JavaScriptCore/icu/unicode/putil.h \
@@ -110,52 +129,9 @@ javascriptcore_sources += \
JavaScriptCore/icu/unicode/utf_old.h \
JavaScriptCore/icu/unicode/utypes.h \
JavaScriptCore/icu/unicode/uversion.h \
- JavaScriptCore/runtime/ArgList.h \
- JavaScriptCore/runtime/Arguments.h \
- JavaScriptCore/runtime/BatchedTransitionOptimizer.h \
- JavaScriptCore/runtime/CollectorHeapIterator.h \
- JavaScriptCore/debugger/DebuggerCallFrame.cpp \
- JavaScriptCore/debugger/DebuggerCallFrame.h \
- JavaScriptCore/runtime/ExecState.cpp \
- JavaScriptCore/runtime/ExecState.h \
- JavaScriptCore/runtime/InitializeThreading.cpp \
- JavaScriptCore/runtime/InitializeThreading.h \
- JavaScriptCore/runtime/JSActivation.cpp \
- JavaScriptCore/runtime/JSActivation.h \
- JavaScriptCore/runtime/JSGlobalData.cpp \
- JavaScriptCore/runtime/JSGlobalData.h \
- JavaScriptCore/runtime/JSStaticScopeObject.h \
- JavaScriptCore/runtime/JSType.h \
- JavaScriptCore/kjs/NodeInfo.h \
- JavaScriptCore/kjs/Parser.h \
- JavaScriptCore/runtime/PropertyNameArray.h \
- JavaScriptCore/runtime/RegExpConstructor.h \
- JavaScriptCore/runtime/RegExpMatchesArray.h \
- JavaScriptCore/runtime/RegExpObject.h \
- JavaScriptCore/runtime/RegExpPrototype.h \
- JavaScriptCore/kjs/ResultType.h \
- JavaScriptCore/runtime/ScopeChain.h \
- JavaScriptCore/runtime/ScopeChainMark.h \
- JavaScriptCore/kjs/SourceProvider.h \
- JavaScriptCore/kjs/SourceCode.h \
- JavaScriptCore/runtime/SymbolTable.h \
- JavaScriptCore/runtime/Tracing.h \
- JavaScriptCore/kjs/TypeInfo.h \
- JavaScriptCore/kjs/collector.h \
- JavaScriptCore/kjs/completion.h \
- JavaScriptCore/kjs/config.h \
- JavaScriptCore/debugger/Debugger.h \
- JavaScriptCore/kjs/dtoa.h \
- JavaScriptCore/kjs/identifier.h \
- JavaScriptCore/kjs/interpreter.h \
- JavaScriptCore/kjs/lexer.h \
- JavaScriptCore/kjs/lookup.h \
- JavaScriptCore/kjs/nodes.h \
- JavaScriptCore/kjs/operations.h \
- JavaScriptCore/kjs/protect.h \
- JavaScriptCore/kjs/regexp.h \
- JavaScriptCore/kjs/ustring.h \
- JavaScriptCore/masm/X86Assembler.h \
+ JavaScriptCore/assembler/X86Assembler.h \
+ JavaScriptCore/assembler/AssemblerBuffer.h \
+ JavaScriptCore/assembler/MacroAssembler.h \
JavaScriptCore/os-win32/stdbool.h \
JavaScriptCore/os-win32/stdint.h \
JavaScriptCore/pcre/pcre.h \
@@ -179,73 +155,53 @@ javascriptcore_sources += \
JavaScriptCore/profiler/Profiler.h \
JavaScriptCore/profiler/TreeProfile.cpp \
JavaScriptCore/profiler/TreeProfile.h \
- JavaScriptCore/runtime/ArrayConstructor.h \
- JavaScriptCore/runtime/ArrayPrototype.h \
- JavaScriptCore/runtime/BooleanConstructor.h \
- JavaScriptCore/runtime/BooleanObject.h \
- JavaScriptCore/runtime/BooleanPrototype.h \
- JavaScriptCore/runtime/CallData.h \
- JavaScriptCore/runtime/ClassInfo.h \
- JavaScriptCore/runtime/DateConstructor.h \
- JavaScriptCore/runtime/DateInstance.h \
- JavaScriptCore/runtime/DateMath.h \
- JavaScriptCore/runtime/DatePrototype.h \
- JavaScriptCore/runtime/Error.h \
- JavaScriptCore/runtime/ErrorConstructor.h \
- JavaScriptCore/runtime/ErrorInstance.h \
- JavaScriptCore/runtime/ErrorPrototype.h \
- JavaScriptCore/runtime/FunctionConstructor.h \
- JavaScriptCore/runtime/FunctionPrototype.h \
- JavaScriptCore/runtime/GlobalEvalFunction.h \
- JavaScriptCore/runtime/InternalFunction.h \
- JavaScriptCore/runtime/JSArray.h \
- JavaScriptCore/runtime/JSCell.h \
- JavaScriptCore/runtime/JSFunction.h \
- JavaScriptCore/runtime/JSGlobalObject.h \
- JavaScriptCore/runtime/JSGlobalObjectFunctions.h \
- JavaScriptCore/runtime/JSImmediate.h \
+ JavaScriptCore/interpreter/CallFrame.cpp \
+ JavaScriptCore/interpreter/CallFrame.h \
+ JavaScriptCore/runtime/InitializeThreading.cpp \
+ JavaScriptCore/runtime/InitializeThreading.h \
+ JavaScriptCore/runtime/JSActivation.cpp \
+ JavaScriptCore/runtime/JSActivation.h \
+ JavaScriptCore/runtime/JSByteArray.cpp \
+ JavaScriptCore/runtime/JSByteArray.h \
+ JavaScriptCore/runtime/JSGlobalData.cpp \
+ JavaScriptCore/runtime/JSGlobalData.h \
JavaScriptCore/runtime/JSNotAnObject.cpp \
JavaScriptCore/runtime/JSNotAnObject.h \
- JavaScriptCore/runtime/JSNumberCell.h \
- JavaScriptCore/runtime/JSObject.h \
- JavaScriptCore/runtime/JSString.h \
- JavaScriptCore/runtime/JSValue.h \
- JavaScriptCore/runtime/JSVariableObject.h \
- JavaScriptCore/runtime/MathObject.h \
- JavaScriptCore/runtime/NativeErrorConstructor.h \
- JavaScriptCore/runtime/NativeErrorPrototype.h \
- JavaScriptCore/runtime/NumberConstructor.h \
- JavaScriptCore/runtime/NumberObject.h \
- JavaScriptCore/runtime/NumberPrototype.h \
- JavaScriptCore/runtime/ObjectConstructor.h \
- JavaScriptCore/runtime/ObjectPrototype.h \
- JavaScriptCore/runtime/PropertyMapHashTable.h \
- JavaScriptCore/runtime/PropertySlot.h \
- JavaScriptCore/runtime/PrototypeFunction.h \
- JavaScriptCore/runtime/PutPropertySlot.h \
+ JavaScriptCore/runtime/JSPropertyNameIterator.cpp \
+ JavaScriptCore/runtime/JSPropertyNameIterator.h \
JavaScriptCore/runtime/SmallStrings.cpp \
JavaScriptCore/runtime/SmallStrings.h \
- JavaScriptCore/runtime/StringConstructor.h \
- JavaScriptCore/runtime/StringObject.h \
- JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h \
- JavaScriptCore/runtime/StringPrototype.h \
- JavaScriptCore/runtime/StructureID.cpp \
- JavaScriptCore/runtime/StructureID.h \
- JavaScriptCore/runtime/StructureIDChain.cpp \
- JavaScriptCore/runtime/StructureIDChain.h \
- JavaScriptCore/runtime/StructureIDTransitionTable.h \
+ JavaScriptCore/runtime/Structure.cpp \
+ JavaScriptCore/runtime/Structure.h \
+ JavaScriptCore/runtime/StructureChain.cpp \
+ JavaScriptCore/runtime/StructureChain.h \
+ JavaScriptCore/runtime/StructureTransitionTable.h \
+ JavaScriptCore/runtime/TypeInfo.h \
+ JavaScriptCore/wrec/CharacterClass.cpp \
+ JavaScriptCore/wrec/CharacterClass.h \
JavaScriptCore/wrec/CharacterClassConstructor.cpp \
JavaScriptCore/wrec/CharacterClassConstructor.h \
+ JavaScriptCore/wrec/Escapes.h \
+ JavaScriptCore/wrec/Quantifier.h \
JavaScriptCore/wrec/WREC.cpp \
JavaScriptCore/wrec/WREC.h \
+ JavaScriptCore/wrec/WRECFunctors.cpp \
+ JavaScriptCore/wrec/WRECFunctors.h \
+ JavaScriptCore/wrec/WRECGenerator.cpp \
+ JavaScriptCore/wrec/WRECGenerator.h \
+ JavaScriptCore/wrec/WRECParser.cpp \
+ JavaScriptCore/wrec/WRECParser.h \
JavaScriptCore/wtf/ASCIICType.h \
JavaScriptCore/wtf/AVLTree.h \
JavaScriptCore/wtf/AlwaysInline.h \
JavaScriptCore/wtf/Assertions.cpp \
JavaScriptCore/wtf/Assertions.h \
+ JavaScriptCore/wtf/ByteArray.cpp \
+ JavaScriptCore/wtf/ByteArray.h \
+ JavaScriptCore/wtf/CurrentTime.cpp \
+ JavaScriptCore/wtf/CurrentTime.h \
JavaScriptCore/wtf/Deque.h \
JavaScriptCore/wtf/DisallowCType.h \
- JavaScriptCore/wtf/FastMalloc.h \
JavaScriptCore/wtf/Forward.h \
JavaScriptCore/wtf/GOwnPtr.cpp \
JavaScriptCore/wtf/GOwnPtr.h \
@@ -263,7 +219,6 @@ javascriptcore_sources += \
JavaScriptCore/wtf/Locker.h \
JavaScriptCore/wtf/MainThread.cpp \
JavaScriptCore/wtf/MainThread.h \
- JavaScriptCore/wtf/MallocZoneSupport.h \
JavaScriptCore/wtf/MathExtras.h \
JavaScriptCore/wtf/MessageQueue.h \
JavaScriptCore/wtf/Noncopyable.h \
@@ -272,19 +227,24 @@ javascriptcore_sources += \
JavaScriptCore/wtf/OwnPtr.h \
JavaScriptCore/wtf/PassRefPtr.h \
JavaScriptCore/wtf/Platform.h \
+ JavaScriptCore/wtf/PtrAndFlags.h \
+ JavaScriptCore/wtf/RandomNumber.cpp \
+ JavaScriptCore/wtf/RandomNumber.h \
+ JavaScriptCore/wtf/RandomNumberSeed.h \
JavaScriptCore/wtf/RefCounted.h \
JavaScriptCore/wtf/RefCountedLeakCounter.cpp \
JavaScriptCore/wtf/RefCountedLeakCounter.h \
JavaScriptCore/wtf/RefPtr.h \
JavaScriptCore/wtf/RefPtrHashMap.h \
JavaScriptCore/wtf/RetainPtr.h \
+ JavaScriptCore/wtf/StdLibExtras.h \
JavaScriptCore/wtf/StringExtras.h \
JavaScriptCore/wtf/TCPackedCache.h \
JavaScriptCore/wtf/TCPageMap.h \
JavaScriptCore/wtf/TCSpinLock.h \
- JavaScriptCore/wtf/TCSystemAlloc.h \
JavaScriptCore/wtf/ThreadSpecific.h \
JavaScriptCore/wtf/Threading.h \
+ JavaScriptCore/wtf/Threading.cpp \
JavaScriptCore/wtf/ThreadingGtk.cpp \
JavaScriptCore/wtf/ThreadingPthreads.cpp \
JavaScriptCore/wtf/UnusedParam.h \
@@ -302,114 +262,196 @@ javascriptcore_sources += \
# Debug build
if ENABLE_DEBUG
javascriptcore_built_sources += \
- DerivedSources/grammar.cpp \
- DerivedSources/grammar.h
+ DerivedSources/Grammar.cpp \
+ DerivedSources/Grammar.h
javascriptcore_sources += \
- JavaScriptCore/VM/CodeGenerator.cpp \
- JavaScriptCore/VM/RegisterFile.cpp \
+ JavaScriptCore/interpreter/RegisterFile.cpp \
+ JavaScriptCore/interpreter/RegisterFile.h \
+ JavaScriptCore/bytecompiler/BytecodeGenerator.cpp \
+ JavaScriptCore/bytecompiler/BytecodeGenerator.h \
+ JavaScriptCore/bytecompiler/LabelScope.h \
+ JavaScriptCore/debugger/Debugger.cpp \
+ JavaScriptCore/debugger/Debugger.h \
+ JavaScriptCore/parser/Lexer.cpp \
+ JavaScriptCore/parser/Lexer.h \
+ JavaScriptCore/parser/NodeInfo.h \
+ JavaScriptCore/parser/Nodes.cpp \
+ JavaScriptCore/parser/Nodes.h \
+ JavaScriptCore/parser/Parser.cpp \
+ JavaScriptCore/parser/Parser.h \
+ JavaScriptCore/parser/ResultType.h \
+ JavaScriptCore/parser/SourceCode.h \
+ JavaScriptCore/parser/SourceProvider.h \
JavaScriptCore/runtime/ArgList.cpp \
+ JavaScriptCore/runtime/ArgList.h \
JavaScriptCore/runtime/Arguments.cpp \
- JavaScriptCore/runtime/CommonIdentifiers.cpp \
- JavaScriptCore/runtime/CommonIdentifiers.h \
- JavaScriptCore/runtime/GetterSetter.cpp \
- JavaScriptCore/runtime/GetterSetter.h \
- JavaScriptCore/runtime/JSLock.cpp \
- JavaScriptCore/runtime/JSLock.h \
- JavaScriptCore/runtime/JSStaticScopeObject.cpp \
- JavaScriptCore/kjs/LabelScope.h \
- JavaScriptCore/kjs/Parser.cpp \
- JavaScriptCore/runtime/PropertyNameArray.cpp \
- JavaScriptCore/runtime/RegExpConstructor.cpp \
- JavaScriptCore/runtime/RegExpObject.cpp \
- JavaScriptCore/runtime/RegExpPrototype.cpp \
- JavaScriptCore/runtime/ScopeChain.cpp \
- JavaScriptCore/kjs/collector.cpp \
- JavaScriptCore/debugger/Debugger.cpp \
- JavaScriptCore/kjs/dtoa.cpp \
- JavaScriptCore/kjs/identifier.cpp \
- JavaScriptCore/kjs/interpreter.cpp \
- JavaScriptCore/kjs/lexer.cpp \
- JavaScriptCore/kjs/lookup.cpp \
- JavaScriptCore/kjs/nodes.cpp \
- JavaScriptCore/kjs/nodes2string.cpp \
- JavaScriptCore/kjs/operations.cpp \
- JavaScriptCore/kjs/regexp.cpp \
- JavaScriptCore/kjs/ustring.cpp \
+ JavaScriptCore/runtime/Arguments.h \
JavaScriptCore/runtime/ArrayConstructor.cpp \
+ JavaScriptCore/runtime/ArrayConstructor.h \
JavaScriptCore/runtime/ArrayPrototype.cpp \
+ JavaScriptCore/runtime/ArrayPrototype.h \
+ JavaScriptCore/runtime/BatchedTransitionOptimizer.h \
JavaScriptCore/runtime/BooleanConstructor.cpp \
+ JavaScriptCore/runtime/BooleanConstructor.h \
JavaScriptCore/runtime/BooleanObject.cpp \
+ JavaScriptCore/runtime/BooleanObject.h \
JavaScriptCore/runtime/BooleanPrototype.cpp \
+ JavaScriptCore/runtime/BooleanPrototype.h \
JavaScriptCore/runtime/CallData.cpp \
+ JavaScriptCore/runtime/CallData.h \
+ JavaScriptCore/runtime/ClassInfo.h \
+ JavaScriptCore/runtime/Collector.cpp \
+ JavaScriptCore/runtime/Collector.h \
+ JavaScriptCore/runtime/CollectorHeapIterator.h \
+ JavaScriptCore/runtime/CommonIdentifiers.cpp \
+ JavaScriptCore/runtime/CommonIdentifiers.h \
+ JavaScriptCore/runtime/Completion.h \
JavaScriptCore/runtime/ConstructData.cpp \
JavaScriptCore/runtime/ConstructData.h \
JavaScriptCore/runtime/DateConstructor.cpp \
+ JavaScriptCore/runtime/DateConstructor.h \
JavaScriptCore/runtime/DateInstance.cpp \
+ JavaScriptCore/runtime/DateInstance.h \
JavaScriptCore/runtime/DateMath.cpp \
+ JavaScriptCore/runtime/DateMath.h \
JavaScriptCore/runtime/DatePrototype.cpp \
+ JavaScriptCore/runtime/DatePrototype.h \
JavaScriptCore/runtime/Error.cpp \
+ JavaScriptCore/runtime/Error.h \
JavaScriptCore/runtime/ErrorConstructor.cpp \
+ JavaScriptCore/runtime/ErrorConstructor.h \
JavaScriptCore/runtime/ErrorInstance.cpp \
+ JavaScriptCore/runtime/ErrorInstance.h \
JavaScriptCore/runtime/ErrorPrototype.cpp \
+ JavaScriptCore/runtime/ErrorPrototype.h \
JavaScriptCore/runtime/FunctionConstructor.cpp \
+ JavaScriptCore/runtime/FunctionConstructor.h \
JavaScriptCore/runtime/FunctionPrototype.cpp \
+ JavaScriptCore/runtime/FunctionPrototype.h \
+ JavaScriptCore/runtime/GetterSetter.cpp \
+ JavaScriptCore/runtime/GetterSetter.h \
JavaScriptCore/runtime/GlobalEvalFunction.cpp \
+ JavaScriptCore/runtime/GlobalEvalFunction.h \
+ JavaScriptCore/runtime/Identifier.cpp \
+ JavaScriptCore/runtime/Identifier.h \
JavaScriptCore/runtime/InternalFunction.cpp \
+ JavaScriptCore/runtime/InternalFunction.h \
+ JavaScriptCore/runtime/Completion.cpp \
JavaScriptCore/runtime/JSArray.cpp \
+ JavaScriptCore/runtime/JSArray.h \
JavaScriptCore/runtime/JSCell.cpp \
+ JavaScriptCore/runtime/JSCell.h \
JavaScriptCore/runtime/JSFunction.cpp \
+ JavaScriptCore/runtime/JSFunction.h \
JavaScriptCore/runtime/JSGlobalObject.cpp \
+ JavaScriptCore/runtime/JSGlobalObject.h \
JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp \
+ JavaScriptCore/runtime/JSGlobalObjectFunctions.h \
JavaScriptCore/runtime/JSImmediate.cpp \
+ JavaScriptCore/runtime/JSImmediate.h \
+ JavaScriptCore/runtime/JSLock.cpp \
+ JavaScriptCore/runtime/JSLock.h \
JavaScriptCore/runtime/JSNumberCell.cpp \
+ JavaScriptCore/runtime/JSNumberCell.h \
JavaScriptCore/runtime/JSObject.cpp \
+ JavaScriptCore/runtime/JSObject.h \
+ JavaScriptCore/runtime/JSStaticScopeObject.cpp \
+ JavaScriptCore/runtime/JSStaticScopeObject.h \
JavaScriptCore/runtime/JSString.cpp \
+ JavaScriptCore/runtime/JSString.h \
+ JavaScriptCore/runtime/JSType.h \
JavaScriptCore/runtime/JSValue.cpp \
+ JavaScriptCore/runtime/JSValue.h \
JavaScriptCore/runtime/JSVariableObject.cpp \
+ JavaScriptCore/runtime/JSVariableObject.h \
JavaScriptCore/runtime/JSWrapperObject.cpp \
JavaScriptCore/runtime/JSWrapperObject.h \
+ JavaScriptCore/runtime/Lookup.cpp \
+ JavaScriptCore/runtime/Lookup.h \
JavaScriptCore/runtime/MathObject.cpp \
+ JavaScriptCore/runtime/MathObject.h \
JavaScriptCore/runtime/NativeErrorConstructor.cpp \
+ JavaScriptCore/runtime/NativeErrorConstructor.h \
JavaScriptCore/runtime/NativeErrorPrototype.cpp \
+ JavaScriptCore/runtime/NativeErrorPrototype.h \
JavaScriptCore/runtime/NumberConstructor.cpp \
+ JavaScriptCore/runtime/NumberConstructor.h \
JavaScriptCore/runtime/NumberObject.cpp \
+ JavaScriptCore/runtime/NumberObject.h \
JavaScriptCore/runtime/NumberPrototype.cpp \
+ JavaScriptCore/runtime/NumberPrototype.h \
JavaScriptCore/runtime/ObjectConstructor.cpp \
+ JavaScriptCore/runtime/ObjectConstructor.h \
JavaScriptCore/runtime/ObjectPrototype.cpp \
+ JavaScriptCore/runtime/ObjectPrototype.h \
+ JavaScriptCore/runtime/Operations.cpp \
+ JavaScriptCore/runtime/Operations.h \
+ JavaScriptCore/runtime/PropertyMapHashTable.h \
+ JavaScriptCore/runtime/PropertyNameArray.cpp \
+ JavaScriptCore/runtime/PropertyNameArray.h \
JavaScriptCore/runtime/PropertySlot.cpp \
+ JavaScriptCore/runtime/PropertySlot.h \
+ JavaScriptCore/runtime/Protect.h \
JavaScriptCore/runtime/PrototypeFunction.cpp \
+ JavaScriptCore/runtime/PrototypeFunction.h \
+ JavaScriptCore/runtime/PutPropertySlot.h \
+ JavaScriptCore/runtime/RegExp.cpp \
+ JavaScriptCore/runtime/RegExp.h \
+ JavaScriptCore/runtime/RegExpConstructor.cpp \
+ JavaScriptCore/runtime/RegExpConstructor.h \
+ JavaScriptCore/runtime/RegExpMatchesArray.h \
+ JavaScriptCore/runtime/RegExpObject.cpp \
+ JavaScriptCore/runtime/RegExpObject.h \
+ JavaScriptCore/runtime/RegExpPrototype.cpp \
+ JavaScriptCore/runtime/RegExpPrototype.h \
+ JavaScriptCore/runtime/ScopeChain.cpp \
+ JavaScriptCore/runtime/ScopeChain.h \
+ JavaScriptCore/runtime/ScopeChainMark.h \
JavaScriptCore/runtime/StringConstructor.cpp \
+ JavaScriptCore/runtime/StringConstructor.h \
JavaScriptCore/runtime/StringObject.cpp \
+ JavaScriptCore/runtime/StringObject.h \
+ JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h \
JavaScriptCore/runtime/StringPrototype.cpp \
+ JavaScriptCore/runtime/StringPrototype.h \
+ JavaScriptCore/runtime/SymbolTable.h \
+ JavaScriptCore/runtime/Tracing.h \
+ JavaScriptCore/runtime/UString.cpp \
+ JavaScriptCore/runtime/UString.h \
JavaScriptCore/wtf/FastMalloc.cpp \
- JavaScriptCore/wtf/TCSystemAlloc.cpp
+ JavaScriptCore/wtf/FastMalloc.h \
+ JavaScriptCore/wtf/MallocZoneSupport.h \
+ JavaScriptCore/wtf/TCSystemAlloc.cpp \
+ JavaScriptCore/wtf/TCSystemAlloc.h \
+ JavaScriptCore/wtf/dtoa.cpp \
+ JavaScriptCore/wtf/dtoa.h
else
javascriptcore_built_nosources += \
- DerivedSources/grammar.cpp \
- DerivedSources/grammar.h
+ DerivedSources/Grammar.cpp \
+ DerivedSources/Grammar.h
javascriptcore_sources += \
JavaScriptCore/AllInOneFile.cpp
endif # END ENABLE_DEBUG
-DerivedSources/grammar.h: DerivedSources/grammar.cpp;
+DerivedSources/Grammar.h: DerivedSources/Grammar.cpp;
-DerivedSources/grammar.cpp: $(srcdir)/JavaScriptCore/kjs/grammar.y
- $(BISON) -d -p kjsyy $(srcdir)/JavaScriptCore/kjs/grammar.y -o $@ > bison_out.txt 2>&1
- $(PERL) -p -e 'END { if ($$conflict) { unlink "grammar.cpp"; die; } } $$conflict ||= /conflict/' < bison_out.txt
- cat $(GENSOURCES)/grammar.hpp > $(GENSOURCES)/grammar.h
- rm -f $(GENSOURCES)/grammar.hpp bison_out.txt
+DerivedSources/Grammar.cpp: $(srcdir)/JavaScriptCore/parser/Grammar.y
+ $(BISON) -d -p jscyy $(srcdir)/JavaScriptCore/parser/Grammar.y -o $@ > bison_out.txt 2>&1
+ $(PERL) -p -e 'END { if ($$conflict) { unlink "Grammar.cpp"; die; } } $$conflict ||= /conflict/' < bison_out.txt
+ cat $(GENSOURCES)/Grammar.hpp > $(GENSOURCES)/Grammar.h
+ rm -f $(GENSOURCES)/Grammar.hpp bison_out.txt
-DerivedSources/lexer.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/JavaScriptCore/kjs/keywords.table
+DerivedSources/Lexer.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/JavaScriptCore/parser/Keywords.table
$(PERL) $^ > $@
JavaScriptCore/%.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/JavaScriptCore/%.cpp
- $^ -i > $@
+ $(PERL) $^ -i > $@
JavaScriptCore/pcre/chartables.c: $(srcdir)/JavaScriptCore/pcre/dftables
- $^ $@
+ $(PERL) $^ $@
bin_PROGRAMS += \
Programs/jsc
@@ -434,6 +476,7 @@ Programs_minidom_CPPFLAGS = \
$(javascriptcore_cppflags)
Programs_minidom_CFLAGS = \
+ -ansi \
-fno-strict-aliasing \
-O2 \
$(global_cflags) \
@@ -446,7 +489,7 @@ Programs_minidom_LDADD = \
# jsc
Programs_jsc_SOURCES = \
- JavaScriptCore/kjs/Shell.cpp
+ JavaScriptCore/jsc.cpp
Programs_jsc_CPPFLAGS = \
$(global_cppflags) \
@@ -475,8 +518,8 @@ javascriptcore_dist += \
JavaScriptCore/pcre/AUTHORS \
JavaScriptCore/pcre/dftables \
JavaScriptCore/pcre/ucptable.cpp \
- JavaScriptCore/kjs/grammar.y \
- JavaScriptCore/kjs/keywords.table
+ JavaScriptCore/parser/Grammar.y \
+ JavaScriptCore/parser/Keywords.table
# Clean rules for JavaScriptCore
CLEANFILES += \
diff --git a/JavaScriptCore/Info.plist b/JavaScriptCore/Info.plist
index 55537af..17949b0 100644
--- a/JavaScriptCore/Info.plist
+++ b/JavaScriptCore/Info.plist
@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleGetInfoString</key>
- <string>${BUNDLE_VERSION}, Copyright 2003-2007 Apple Inc.; Copyright 1999-2001 Harri Porten &lt;porten@kde.org&gt;; Copyright 2001 Peter Kelly &lt;pmk@post.com&gt;; Copyright 1997-2005 University of Cambridge; Copyright 1991, 2000, 2001 by Lucent Technologies.</string>
+ <string>${BUNDLE_VERSION}, Copyright 2003-2009 Apple Inc.; Copyright 1999-2001 Harri Porten &lt;porten@kde.org&gt;; Copyright 2001 Peter Kelly &lt;pmk@post.com&gt;; Copyright 1997-2005 University of Cambridge; Copyright 1991, 2000, 2001 by Lucent Technologies.</string>
<key>CFBundleIdentifier</key>
<string>com.apple.${PRODUCT_NAME}</string>
<key>CFBundleInfoDictionaryVersion</key>
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index d7e07c6..5e1bb78 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -99,27 +99,18 @@ __ZN3JSC10JSFunction4infoE
__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringE
-__ZN3JSC11Interpreter11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
-__ZN3JSC11Interpreter8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeEPNS_7JSValueE
+__ZN3JSC11JSByteArray15createStructureENS_10JSValuePtrE
+__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
__ZN3JSC11JSImmediate12nonInlineNaNEv
-__ZN3JSC11JSImmediate8toObjectEPNS_7JSValueEPNS_9ExecStateE
-__ZN3JSC11JSImmediate8toStringEPNS_7JSValueE
-__ZN3JSC11JSImmediate9prototypeEPNS_7JSValueEPNS_9ExecStateE
+__ZN3JSC11JSImmediate8toObjectENS_10JSValuePtrEPNS_9ExecStateE
+__ZN3JSC11JSImmediate8toStringENS_10JSValuePtrE
+__ZN3JSC11JSImmediate9prototypeENS_10JSValuePtrEPNS_9ExecStateE
__ZN3JSC11ProfileNode4sortEPFbRKN3WTF6RefPtrIS0_EES5_E
-__ZN3JSC11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm16EEERKNS_10SourceCodeEji
-__ZN3JSC11StructureID17stopIgnoringLeaksEv
-__ZN3JSC11StructureID18startIgnoringLeaksEv
-__ZN3JSC11StructureID21addPropertyTransitionEPS0_RKNS_10IdentifierEjRm
-__ZN3JSC11StructureID21clearEnumerationCacheEv
-__ZN3JSC11StructureID24fromDictionaryTransitionEPS0_
-__ZN3JSC11StructureID25changePrototypeTransitionEPS0_PNS_7JSValueE
-__ZN3JSC11StructureID27growPropertyStorageCapacityEv
-__ZN3JSC11StructureID28addPropertyWithoutTransitionERKNS_10IdentifierEj
-__ZN3JSC11StructureIDC1EPNS_7JSValueERKNS_8TypeInfoE
-__ZN3JSC11StructureIDD1Ev
+__ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
__ZN3JSC12DateInstance4infoE
__ZN3JSC12JSGlobalData10ClientDataD2Ev
__ZN3JSC12JSGlobalData12createLeakedEv
+__ZN3JSC12JSGlobalData14sharedInstanceEv
__ZN3JSC12JSGlobalData6createEv
__ZN3JSC12JSGlobalDataD1Ev
__ZN3JSC12SamplingTool13notifyOfScopeEPNS_9ScopeNodeE
@@ -132,11 +123,10 @@ __ZN3JSC12StringObject14toThisJSStringEPNS_9ExecStateE
__ZN3JSC12StringObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
__ZN3JSC12StringObject4infoE
-__ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_11StructureIDEEERKNS_7UStringE
+__ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7UStringE
__ZN3JSC12jsNumberCellEPNS_9ExecStateEd
-__ZN3JSC13CodeGenerator21setDumpsGeneratedCodeEb
__ZN3JSC13StatementNode6setLocEii
__ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE
__ZN3JSC14JSGlobalObject10globalExecEv
@@ -144,34 +134,40 @@ __ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSO
__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
__ZN3JSC14JSGlobalObject14setTimeoutTimeEj
__ZN3JSC14JSGlobalObject16stopTimeoutCheckEv
-__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEj
+__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrEj
__ZN3JSC14JSGlobalObject17startTimeoutCheckEv
-__ZN3JSC14JSGlobalObject29markCrossHeapDependentObjectsEv
-__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
__ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
__ZN3JSC14JSGlobalObject4markEv
__ZN3JSC14JSGlobalObjectD2Ev
__ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
__ZN3JSC14constructArrayEPNS_9ExecStateERKNS_7ArgListE
__ZN3JSC15JSWrapperObject4markEv
+__ZN3JSC15toInt32SlowCaseEdRb
__ZN3JSC16FunctionBodyNode13finishParsingEPNS_10IdentifierEm
__ZN3JSC16FunctionBodyNode14copyParametersEv
-__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm16EEERKNS_10SourceCodeEji
+__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm0EEERKNS_10SourceCodeEji
__ZN3JSC16InternalFunction4infoE
-__ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF10PassRefPtrINS_11StructureIDEEERKNS_10IdentifierE
+__ZN3JSC16InternalFunction4nameEPNS_12JSGlobalDataE
+__ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF10PassRefPtrINS_9StructureEEERKNS_10IdentifierE
__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC16JSVariableObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
__ZN3JSC16ParserRefCounted3refEv
__ZN3JSC16ParserRefCounted5derefEv
+__ZN3JSC16toUInt32SlowCaseEdRb
+__ZN3JSC17BytecodeGenerator21setDumpsGeneratedCodeEb
__ZN3JSC17PropertyNameArray3addEPNS_7UString3RepE
-__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_11StructureIDEEEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectESB_RKNS_7ArgListEE
-__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectES7_RKNS_7ArgListEE
+__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_10JSValuePtrES2_PNS_8JSObjectESA_RKNS_7ArgListEE
+__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_10JSValuePtrES2_PNS_8JSObjectES6_RKNS_7ArgListEE
__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
+__ZN3JSC18DebuggerActivationC1EPNS_8JSObjectE
__ZN3JSC19constructEmptyArrayEPNS_9ExecStateE
__ZN3JSC19initializeThreadingEv
__ZN3JSC20constructEmptyObjectEPNS_9ExecStateE
-__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectEPNS_7JSValueERKNS_7ArgListE
+__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_10JSValuePtrEPNS_14JSGlobalObjectE
+__ZN3JSC4Heap11objectCountEv
__ZN3JSC4Heap14allocateNumberEm
__ZN3JSC4Heap14primaryHeapEndEv
__ZN3JSC4Heap15recordExtraCostEm
@@ -181,15 +177,14 @@ __ZN3JSC4Heap20protectedObjectCountEv
__ZN3JSC4Heap24setGCProtectNeedsLockingEv
__ZN3JSC4Heap25protectedObjectTypeCountsEv
__ZN3JSC4Heap26protectedGlobalObjectCountEv
-__ZN3JSC4Heap4heapEPNS_7JSValueE
-__ZN3JSC4Heap4sizeEv
+__ZN3JSC4Heap4heapENS_10JSValuePtrE
__ZN3JSC4Heap6isBusyEv
__ZN3JSC4Heap7collectEv
__ZN3JSC4Heap7destroyEv
-__ZN3JSC4Heap7protectEPNS_7JSValueE
+__ZN3JSC4Heap7protectENS_10JSValuePtrE
__ZN3JSC4Heap8allocateEm
-__ZN3JSC4Heap9unprotectEPNS_7JSValueE
-__ZN3JSC4callEPNS_9ExecStateEPNS_7JSValueENS_8CallTypeERKNS_8CallDataES3_RKNS_7ArgListE
+__ZN3JSC4Heap9unprotectENS_10JSValuePtrE
+__ZN3JSC4callEPNS_9ExecStateENS_10JSValuePtrENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
__ZN3JSC5equalEPKNS_7UString3RepES3_
__ZN3JSC6JSCell11getCallDataERNS_8CallDataE
__ZN3JSC6JSCell11getJSNumberEv
@@ -199,8 +194,8 @@ __ZN3JSC6JSCell14toThisJSStringEPNS_9ExecStateE
__ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE
__ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC6JSCell3putEPNS_9ExecStateEjPNS_7JSValueE
+__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC6JSCell3putEPNS_9ExecStateEjNS_10JSValuePtrE
__ZN3JSC6JSCell9getObjectEv
__ZN3JSC6JSCellnwEmPNS_9ExecStateE
__ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE
@@ -211,8 +206,7 @@ __ZN3JSC6JSLock6unlockEb
__ZN3JSC6JSLock9lockCountEv
__ZN3JSC6JSLockC1EPNS_9ExecStateE
__ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
-__ZN3JSC6strtodEPKcPPc
-__ZN3JSC7ArgList10slowAppendEPNS_7JSValueE
+__ZN3JSC7ArgList10slowAppendENS_10JSValuePtrE
__ZN3JSC7CStringD1Ev
__ZN3JSC7CStringaSERKS0_
__ZN3JSC7JSArray4infoE
@@ -221,7 +215,7 @@ __ZN3JSC7Profile5focusEPKNS_11ProfileNodeE
__ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE
__ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE
__ZN3JSC7UString3Rep11computeHashEPKti
-__ZN3JSC7UString3Rep4nullE
+__ZN3JSC7UString3Rep14nullBaseStringE
__ZN3JSC7UString3Rep7destroyEv
__ZN3JSC7UString4fromEi
__ZN3JSC7UString4fromEj
@@ -234,42 +228,57 @@ __ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
__ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
__ZN3JSC8DebuggerC2Ev
__ZN3JSC8DebuggerD2Ev
-__ZN3JSC8JSObject11hasInstanceEPNS_9ExecStateEPNS_7JSValueES4_
+__ZN3JSC8JSObject11hasInstanceEPNS_9ExecStateENS_10JSValuePtrES3_
__ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
__ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
__ZN3JSC8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC8JSObject15unwrappedObjectEv
__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
__ZN3JSC8JSObject17createInheritorIDEv
__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj
-__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEj
-__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateEjPNS_7JSValueEj
+__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrEj
+__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateEjNS_10JSValuePtrEj
__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
-__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPPNS_7JSValueE
+__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_10JSValuePtrE
+__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_10JSValuePtrE
__ZN3JSC8JSObject23allocatePropertyStorageEmm
-__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC8JSObject3putEPNS_9ExecStateEjPNS_7JSValueE
+__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_10JSValuePtrE
__ZN3JSC8JSObject4markEv
__ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC8Profiler8profilerEv
+__ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_10JSValuePtrE
__ZN3JSC8jsStringEPNS_12JSGlobalDataERKNS_7UStringE
__ZN3JSC9CodeBlockD1Ev
__ZN3JSC9CodeBlockD2Ev
-__ZN3JSC9constructEPNS_9ExecStateEPNS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
+__ZN3JSC9Structure17stopIgnoringLeaksEv
+__ZN3JSC9Structure18startIgnoringLeaksEv
+__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjRm
+__ZN3JSC9Structure22materializePropertyMapEv
+__ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_10JSValuePtrE
+__ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEj
+__ZN3JSC9Structure3getERKNS_10IdentifierERj
+__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjRm
+__ZN3JSC9StructureC1ENS_10JSValuePtrERKNS_8TypeInfoE
+__ZN3JSC9StructureD1Ev
+__ZN3JSC9constructEPNS_9ExecStateENS_10JSValuePtrENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
__ZN3JSCeqERKNS_7UStringEPKc
+__ZN3JSCeqERKNS_7UStringES2_
__ZN3JSCgtERKNS_7UStringES2_
__ZN3JSCltERKNS_7UStringES2_
__ZN3WTF10fastCallocEmm
__ZN3WTF10fastMallocEm
+__ZN3WTF11currentTimeEv
__ZN3WTF11fastReallocEPvm
__ZN3WTF12createThreadEPFPvS0_ES0_
__ZN3WTF12createThreadEPFPvS0_ES0_PKc
__ZN3WTF12detachThreadEj
__ZN3WTF12isMainThreadEv
+__ZN3WTF12randomNumberEv
__ZN3WTF13currentThreadEv
__ZN3WTF13tryFastCallocEmm
__ZN3WTF15ThreadCondition4waitERNS_5MutexE
@@ -280,6 +289,7 @@ __ZN3WTF15ThreadConditionD1Ev
__ZN3WTF16callOnMainThreadEPFvPvES0_
__ZN3WTF16fastZeroedMallocEm
__ZN3WTF19initializeThreadingEv
+__ZN3WTF20fastMallocStatisticsEv
__ZN3WTF21RefCountedLeakCounter16suppressMessagesEPKc
__ZN3WTF21RefCountedLeakCounter24cancelMessageSuppressionEPKc
__ZN3WTF21RefCountedLeakCounter9decrementEv
@@ -289,48 +299,45 @@ __ZN3WTF21RefCountedLeakCounterD1Ev
__ZN3WTF23waitForThreadCompletionEjPPv
__ZN3WTF27releaseFastMallocFreeMemoryEv
__ZN3WTF28setMainThreadCallbacksPausedEb
-__ZN3WTF32atomicallyInitializedStaticMutexE
+__ZN3WTF36lockAtomicallyInitializedStaticMutexEv
+__ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
__ZN3WTF5Mutex4lockEv
__ZN3WTF5Mutex6unlockEv
__ZN3WTF5Mutex7tryLockEv
__ZN3WTF5MutexC1Ev
__ZN3WTF5MutexD1Ev
+__ZN3WTF6strtodEPKcPPc
__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
__ZN3WTF8Collator18setOrderLowerFirstEb
__ZN3WTF8CollatorC1EPKc
__ZN3WTF8CollatorD1Ev
__ZN3WTF8fastFreeEPv
-__ZNK3JSC11StructureID3getERKNS_10IdentifierERj
+__ZN3WTF9ByteArray6createEm
+__ZNK3JSC10JSValuePtr9toIntegerEPNS_9ExecStateE
+__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
+__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_10JSValuePtrE
__ZNK3JSC12DateInstance7getTimeERdRi
__ZNK3JSC12StringObject12toThisStringEPNS_9ExecStateE
__ZNK3JSC12StringObject8toStringEPNS_9ExecStateE
__ZNK3JSC14JSGlobalObject14isDynamicScopeEv
-__ZNK3JSC14JSGlobalObject14toGlobalObjectEPNS_9ExecStateE
__ZNK3JSC16InternalFunction9classInfoEv
__ZNK3JSC16JSVariableObject16isVariableObjectEv
__ZNK3JSC16JSVariableObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
__ZNK3JSC17DebuggerCallFrame10thisObjectEv
__ZNK3JSC17DebuggerCallFrame12functionNameEv
__ZNK3JSC17DebuggerCallFrame4typeEv
-__ZNK3JSC17DebuggerCallFrame8evaluateERKNS_7UStringERPNS_7JSValueE
-__ZNK3JSC4Node8toStringEv
+__ZNK3JSC17DebuggerCallFrame8evaluateERKNS_7UStringERNS_10JSValuePtrE
+__ZNK3JSC4Heap10statisticsEv
__ZNK3JSC6JSCell12toThisObjectEPNS_9ExecStateE
__ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE
__ZNK3JSC6JSCell14isGetterSetterEv
__ZNK3JSC6JSCell17getTruncatedInt32ERi
__ZNK3JSC6JSCell18getTruncatedUInt32ERj
__ZNK3JSC6JSCell9classInfoEv
-__ZNK3JSC6JSCell9getNumberEv
__ZNK3JSC6JSCell9getStringERNS_7UStringE
__ZNK3JSC6JSCell9getStringEv
__ZNK3JSC6JSCell9getUInt32ERj
__ZNK3JSC7ArgList8getSliceEiRS0_
-__ZNK3JSC7JSValue15toInt32SlowCaseEPNS_9ExecStateERb
-__ZNK3JSC7JSValue16toUInt32SlowCaseEPNS_9ExecStateERb
-__ZNK3JSC7JSValue7toFloatEPNS_9ExecStateE
-__ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE
-__ZNK3JSC7Machine14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
-__ZNK3JSC7Machine18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERPNS_7JSValueE
__ZNK3JSC7UString10UTF8StringEb
__ZNK3JSC7UString14toStrictUInt32EPb
__ZNK3JSC7UString5asciiEv
@@ -342,18 +349,15 @@ __ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj
__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
-__ZNK3JSC8JSObject14toGlobalObjectEPNS_9ExecStateE
__ZNK3JSC8JSObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
__ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE
__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE
__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
__ZNK3JSC8JSObject9classNameEv
__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
-__ZNK3JSC9CodeBlock17derefStructureIDsEPNS_11InstructionE
__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
__ZNK3JSC9HashTable11deleteTableEv
__ZNK3WTF8Collator7collateEPKtmS2_m
-__ZTVN3JSC12JSNumberCellE
__ZTVN3JSC12StringObjectE
__ZTVN3JSC14JSGlobalObjectE
__ZTVN3JSC15JSWrapperObjectE
diff --git a/JavaScriptCore/JavaScriptCore.order b/JavaScriptCore/JavaScriptCore.order
index 9f7cb30..05c300c 100644
--- a/JavaScriptCore/JavaScriptCore.order
+++ b/JavaScriptCore/JavaScriptCore.order
@@ -1,1526 +1,1638 @@
+__ZN3WTF19initializeThreadingEv
__ZN3WTF10fastMallocEm
+__ZN3WTF10fastMallocILb1EEEPvm
__ZN3WTF20TCMalloc_ThreadCache10InitModuleEv
-__ZN3WTF15InitSizeClassesEv
+__ZN3WTFL15InitSizeClassesEv
__Z20TCMalloc_SystemAllocmPmm
-__ZN3WTF17TCMalloc_PageHeap4initEv
__ZN3WTF20TCMalloc_ThreadCache22CreateCacheIfNecessaryEv
__ZN3WTF25TCMalloc_Central_FreeList11RemoveRangeEPPvS2_Pi
__ZN3WTF25TCMalloc_Central_FreeList18FetchFromSpansSafeEv
__ZN3WTF17TCMalloc_PageHeap10AllocLargeEm
__ZN3WTF17TCMalloc_PageHeap8GrowHeapEm
-__ZN3WTF13MetaDataAllocEm
-__ZN3WTF17TCMalloc_PageHeap19IncrementalScavengeEm
+__ZN3WTFL13MetaDataAllocEm
+__ZN3WTF20initializeMainThreadEv
+__ZN3WTF5MutexC1Ev
+__ZN3WTF36lockAtomicallyInitializedStaticMutexEv
+__ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
+__ZN3JSC19initializeThreadingEv
+__ZN3JSCL23initializeThreadingOnceEv
+__ZN3JSC17initializeUStringEv
+__ZN3JSC12initDateMathEv
+__ZN3WTF11currentTimeEv
+__ZN3WTF15ThreadConditionC1Ev
+__ZN3WTF5Mutex4lockEv
+__ZN3WTF5Mutex6unlockEv
__ZN3WTF8fastFreeEPv
+__ZN3WTF12createThreadEPFPvS0_ES0_PKc
+__ZN3WTF20createThreadInternalEPFPvS0_ES0_PKc
+__ZN3WTFL35establishIdentifierForPthreadHandleERP17_opaque_pthread_t
+__ZN3WTFL16threadEntryPointEPv
+__ZN3WTF7HashMapIjP17_opaque_pthread_tNS_7IntHashIjEENS_10HashTraitsIjEENS5_IS2_EEE3addERKjRKS2_
+__ZN3WTF9HashTableIjSt4pairIjP17_opaque_pthread_tENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSA_IS3_EEEESB_E6rehashEi
__ZN3WTF16fastZeroedMallocEm
+__ZN3WTF5MutexD1Ev
+__ZN3WTF25TCMalloc_Central_FreeList11InsertRangeEPvS1_i
+__ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansEPv
__ZN3WTF14FastMallocZone4sizeEP14_malloc_zone_tPKv
-__ZN3KJS8Bindings10RootObject19setCreateRootObjectEPFN3WTF10PassRefPtrIS1_EEPvE
-__ZN3KJS8Bindings8Instance21setDidExecuteFunctionEPFvPNS_9ExecStateEPNS_8JSObjectEE
-_kjs_strtod
-__Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
-__Z30calculateCompiledPatternLengthPKti24JSRegExpIgnoreCaseOptionR11CompileDataR9ErrorCode
-__Z11checkEscapePPKtS0_P9ErrorCodeib
-__Z13compileBranchiPiPPhPPKtS3_P9ErrorCodeS_S_R11CompileData
-__Z15jsRegExpExecutePK8JSRegExpPKtiiPii
+__ZN3WTF13currentThreadEv
+__ZN3WTF16callOnMainThreadEPFvPvES0_
+__ZN3WTF6VectorINS_19FunctionWithContextELm0EE14expandCapacityEm
+__ZN3WTF37scheduleDispatchFunctionsOnMainThreadEv
+__ZN3WTF15ThreadCondition4waitERNS_5MutexE
+__ZN3JSC8DebuggerC2Ev
+__ZN3WTF6strtodEPKcPPc
+__ZN3WTF15ThreadCondition6signalEv
+__ZN3WTF15ThreadCondition9broadcastEv
+__ZN3JSC12JSGlobalData12createLeakedEv
+__ZN3JSC12JSGlobalDataC2Eb
+__ZN3JSC11InterpreterC1Ev
+__ZN3JSC11Interpreter14privateExecuteENS0_13ExecutionFlagEPNS_12RegisterFileEPNS_9ExecStateEPNS_10JSValuePtrE
+__ZN3WTF7HashMapIPvN3JSC8OpcodeIDENS_7PtrHashIS1_EENS_10HashTraitsIS1_EENS6_IS3_EEE3addERKS1_RKS3_
+__ZN3WTF9HashTableIPvSt4pairIS1_N3JSC8OpcodeIDEENS_18PairFirstExtractorIS5_EENS_7PtrHashIS1_EENS_14PairHashTraitsINS_10HashTraitsIS1_EENSB_IS4_EEEESC_E6expandEv
+__ZN3JSC9StructureC1ENS_10JSValuePtrERKNS_8TypeInfoE
+__ZN3JSC7JSArrayC1EN3WTF10PassRefPtrINS_9StructureEEE
+__ZN3JSC7JSArrayD0Ev
+__ZN3WTF10RefCountedIN3JSC9StructureEE5derefEv
+__ZN3JSC9StructureD1Ev
+__ZN3JSC11JSByteArray15createStructureENS_10JSValuePtrE
+__ZN3JSC21createIdentifierTableEv
+__ZN3JSC17CommonIdentifiersC1EPNS_12JSGlobalDataE
+__ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKc
+__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN3JSC7UString3RepEEEENS_18PairFirstExtractorIS9_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSF_IS8_EEEESG_E4findIS2_NS_22IdentityHashTranslatorIS2_S9_SD_EEEENS_17HashTableIteratorIS2_S9_SB_SD_SI_SG_EERKT_
+__ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7StrHashIS4_EENS_10HashTraitsIS4_EESA_E6rehashEi
+__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN3JSC7UString3RepEEEENS_18PairFirstExtractorIS9_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSF_IS8_EEEESG_E6expandEv
+__ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7StrHashIS4_EENS_10HashTraitsIS4_EESA_E4findIS4_NS_22IdentityHashTranslatorIS4_S4_S8_EEEENS_17HashTableIteratorIS4_S4_S6_S8_SA_SA_EERKT_
+__ZN3JSC12SmallStringsC1Ev
+__ZN3JSC5LexerC1EPNS_12JSGlobalDataE
+__ZN3JSC4HeapC1EPNS_12JSGlobalDataE
+__ZN3JSC19ExecutableAllocator17intializePageSizeEv
+__ZN3JSC14ExecutablePool11systemAllocEm
+__ZN3JSC27startProfilerServerIfNeededEv
++[ProfilerServer sharedProfileServer]
+-[ProfilerServer init]
+__ZN3JSC11Interpreter10initializeEPNS_12JSGlobalDataE
+__ZN3JSC3JITC1EPNS_12JSGlobalDataEPNS_9CodeBlockE
+__ZN3JSC3JIT35privateCompileCTIMachineTrampolinesEv
+__ZN3JSC15AssemblerBuffer11ensureSpaceEi
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDEi
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDE
+__ZN3JSC14MacroAssembler4pokeENS_3X8610RegisterIDEi
+__ZN3JSC3JIT32compileOpCallInitializeCallFrameEv
+__ZN3JSC14MacroAssembler5jnz32ENS_3X8610RegisterIDENS0_5Imm32E
__ZN3WTF11fastReallocEPvm
-__ZN3KJS20createDidLockJSMutexEv
-__ZN3KJS9Collector14registerThreadEv
-__ZN3KJS29initializeRegisteredThreadKeyEv
-__ZN3KJS15SavedPropertiesC1Ev
-__ZN3KJS6JSCellnwEm
-__ZN3KJS9Collector12heapAllocateILNS0_8HeapTypeE0EEEPvm
-__ZN3KJS15GlobalExecStateC1EPNS_14JSGlobalObjectE
-__ZN3KJS17CommonIdentifiers6sharedEv
-__ZN3KJS17CommonIdentifiersC2Ev
-__ZN3KJS10IdentifierC1EPKc
-__ZN3KJS10Identifier3addEPKc
-__ZN3WTF7HashSetIPN3KJS7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addINS1_11UCharBufferENS1_21UCharBufferTranslatorEEESt4pairINS_24HashTableIteratorAdapterINS_9HashTableIS4_S4_NS_17IdentityExtractorIS4_EES6_S8_S8_EES4_EEbERKT_
-__ZN3WTF9HashTableIPN3KJS7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7StrHashIS4_EENS_10HashTraitsIS4_EESA_E6rehashEi
-__ZN3KJS14JSGlobalObject4initEv
-__ZN3KJS14JSGlobalObject5resetEPNS_7JSValueE
-__ZN3KJS11PropertyMap5clearEv
-__ZN3KJS17FunctionPrototypeC2EPNS_9ExecStateE
-__ZN3KJS11PropertyMap3putERKNS_10IdentifierEPNS_7JSValueEjb
-__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEPNS_17FunctionPrototypeEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectERKNS_4ListEE
-__ZN3KJS19InternalFunctionImpC2EPNS_17FunctionPrototypeERKNS_10IdentifierE
-__ZN3KJS11PropertyMap11createTableEv
-__ZN3KJS15ObjectPrototypeC2EPNS_9ExecStateEPNS_17FunctionPrototypeE
-__ZN3KJS11PropertyMap6rehashEj
-__ZN3KJS14ArrayPrototypeC1EPNS_9ExecStateEPNS_15ObjectPrototypeE
-__ZN3KJS13ArrayInstanceC2EPNS_8JSObjectEj
-__ZN3KJS15StringPrototypeC2EPNS_9ExecStateEPNS_15ObjectPrototypeE
-__ZN3KJS8jsStringEPKc
-__ZN3KJS16BooleanPrototypeC2EPNS_9ExecStateEPNS_15ObjectPrototypeEPNS_17FunctionPrototypeE
-__ZN3KJS15NumberPrototypeC2EPNS_9ExecStateEPNS_15ObjectPrototypeEPNS_17FunctionPrototypeE
-__ZN3KJS13DatePrototypeC1EPNS_9ExecStateEPNS_15ObjectPrototypeE
-__ZN3KJS12jsNumberCellEd
-__ZN3KJS9Collector12heapAllocateILNS0_8HeapTypeE1EEEPvm
-__ZN3KJS15RegExpPrototypeC2EPNS_9ExecStateEPNS_15ObjectPrototypeEPNS_17FunctionPrototypeE
-__ZN3WTF9HashTableIPN3KJS7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7StrHashIS4_EENS_10HashTraitsIS4_EESA_E4findIS4_NS_22IdentityHashTranslatorIS4_S4_S8_EEEENS_17HashTableIteratorIS4_S4_S6_S8_SA_SA_EERKT_
-__ZN3KJS14ErrorPrototypeC2EPNS_9ExecStateEPNS_15ObjectPrototypeEPNS_17FunctionPrototypeE
-__ZN3KJS7UStringC1EPKc
-__ZN3KJS20NativeErrorPrototypeC1EPNS_9ExecStateEPNS_14ErrorPrototypeERKNS_7UStringES7_
-__ZN3KJS8jsStringERKNS_7UStringE
-__ZN3KJS15ObjectObjectImpC2EPNS_9ExecStateEPNS_15ObjectPrototypeEPNS_17FunctionPrototypeE
-__ZN3KJS17FunctionObjectImpC2EPNS_9ExecStateEPNS_17FunctionPrototypeE
-__ZNK3KJS19InternalFunctionImp9classInfoEv
-__ZN3KJS14ArrayObjectImpC2EPNS_9ExecStateEPNS_17FunctionPrototypeEPNS_14ArrayPrototypeE
-__ZNK3KJS14ArrayPrototype9classInfoEv
-__ZN3KJS15StringObjectImpC2EPNS_9ExecStateEPNS_17FunctionPrototypeEPNS_15StringPrototypeE
-__ZNK3KJS15StringPrototype9classInfoEv
-__ZN3KJS19StringObjectFuncImpC2EPNS_9ExecStateEPNS_17FunctionPrototypeERKNS_10IdentifierE
-__ZN3KJS16BooleanObjectImpC2EPNS_9ExecStateEPNS_17FunctionPrototypeEPNS_16BooleanPrototypeE
-__ZNK3KJS15BooleanInstance9classInfoEv
-__ZN3KJS15NumberObjectImpC2EPNS_9ExecStateEPNS_17FunctionPrototypeEPNS_15NumberPrototypeE
-__ZNK3KJS14NumberInstance9classInfoEv
-__ZN3KJS13DateObjectImpC2EPNS_9ExecStateEPNS_17FunctionPrototypeEPNS_13DatePrototypeE
-__ZNK3KJS13DatePrototype9classInfoEv
-__ZN3KJS15RegExpObjectImpC2EPNS_9ExecStateEPNS_17FunctionPrototypeEPNS_15RegExpPrototypeE
-__ZN3KJS14ErrorObjectImpC2EPNS_9ExecStateEPNS_17FunctionPrototypeEPNS_14ErrorPrototypeE
-__ZNK3KJS13ErrorInstance9classInfoEv
-__ZN3KJS14NativeErrorImpC1EPNS_9ExecStateEPNS_17FunctionPrototypeEPNS_20NativeErrorPrototypeE
-__ZNK3KJS11PropertyMap3getERKNS_10IdentifierE
-__ZNK3KJS9StringImp4typeEv
-__ZN3KJS10Identifier11addSlowCaseEPNS_7UString3RepE
-__ZN3WTF9HashTableIPN3KJS7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7StrHashIS4_EENS_10HashTraitsIS4_EESA_E3addIS4_S4_NS_17HashSetTranslatorILb1ES4_SA_SA_S8_EEEESt4pairINS_17HashTableIteratorIS4_S4_S6_S8_SA_SA_EEbERKT_RKT0_
-__ZN3KJS8JSObject9putDirectERKNS_10IdentifierEPNS_7JSValueEi
-__ZN3KJS13MathObjectImpC1EPNS_9ExecStateEPNS_15ObjectPrototypeE
-__ZN3KJS8JSObject17putDirectFunctionEPNS_19InternalFunctionImpEi
-__ZNK3KJS8JSObject4typeEv
-__ZN3KJS9Collector23collectOnMainThreadOnlyEPNS_7JSValueE
-__ZN3KJS9Collector7protectEPNS_7JSValueE
-__ZN3WTF9HashTableIiSt4pairIiiENS_18PairFirstExtractorIS2_EENS_7IntHashIiEENS_14PairHashTraitsINS_10HashTraitsIiEES9_EES9_E3addIPN3KJS8JSObjectEjNS_17HashMapTranslatorILb1ES1_ISF_jENS_18PairBaseHashTraitsINS8_ISF_EENS8_IjEEEESA_NS_7PtrHashISF_EEEEEES1_INS_17HashTableIteratorIiS2_S4_S6_SA_S9_EEbERKT_RKT0_
-__ZN3WTF9HashTableIiSt4pairIiiENS_18PairFirstExtractorIS2_EENS_7IntHashIiEENS_14PairHashTraitsINS_10HashTraitsIiEES9_EES9_E6rehashEi
-__ZN3KJS6JSCell9getObjectEv
-__ZN3KJS8Bindings10RootObject6createEPKvPNS_14JSGlobalObjectE
-__ZN3KJS8Bindings10RootObjectC2EPKvPNS_14JSGlobalObjectE
-__ZN3WTF9HashTableIiiNS_17IdentityExtractorIiEENS_7IntHashIiEENS_10HashTraitsIiEES6_E6rehashEi
-__ZN3KJS8Bindings10RootObject9gcProtectEPNS_8JSObjectE
-__ZNK3KJS14JSGlobalObject12saveBuiltinsERNS_13SavedBuiltinsE
-__ZN3KJS21SavedBuiltinsInternalC2Ev
-__ZNK3KJS11PropertyMap4saveERNS_15SavedPropertiesE
-__ZN3KJS30comparePropertyMapEntryIndicesEPKvS1_
-__ZN3WTF9HashTableIiSt4pairIiiENS_18PairFirstExtractorIS2_EENS_7IntHashIiEENS_14PairHashTraitsINS_10HashTraitsIiEES9_EES9_E4findIiNS_22IdentityHashTranslatorIiS2_S6_EEEENS_17HashTableIteratorIiS2_S4_S6_SA_S9_EERKT_
-__ZNK3KJS16JSVariableObject16saveLocalStorageERNS_15SavedPropertiesE
-__ZN3KJS13ActivationImpD0Ev
-__ZN3KJS8JSObject12removeDirectERKNS_10IdentifierE
-__ZN3KJS11PropertyMap6removeERKNS_10IdentifierE
-__ZN3KJS7UString3Rep7destroyEv
-__ZN3KJS10Identifier6removeEPNS_7UString3RepE
-__ZN3KJS8Bindings10RootObject10invalidateEv
-__ZN3KJS9Collector9unprotectEPNS_7JSValueE
-__ZN3WTF9HashTableIiiNS_17IdentityExtractorIiEENS_7IntHashIiEENS_10HashTraitsIiEES6_E4findIiNS_22IdentityHashTranslatorIiiS4_EEEENS_17HashTableIteratorIiiS2_S4_S6_S6_EERKT_
-__ZN3KJS8Bindings10RootObjectD1Ev
-__ZN3KJS14JSGlobalObject10globalExecEv
-__ZN3KJS14JSGlobalObject17startTimeoutCheckEv
-__ZN3KJS7UStringC1EPKNS_5UCharEi
-__ZN3KJS11Interpreter8evaluateEPNS_9ExecStateERKNS_7UStringEiPKNS_5UCharEiPNS_7JSValueE
-__ZN3KJS6ParserC2Ev
-__ZN3KJS6Parser5parseINS_11ProgramNodeEEEN3WTF10PassRefPtrIT_EERKNS_7UStringEiPKNS_5UCharEjPiSD_PS7_
-__ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE
-__ZN3KJS7UStringaSEPKc
-__ZN3KJS5LexerC2Ev
-__ZN3WTF6VectorIcLm0EE15reserveCapacityEm
-__ZN3WTF6VectorIN3KJS5UCharELm0EE15reserveCapacityEm
-__ZN3WTF6VectorIPN3KJS7UStringELm0EE15reserveCapacityEm
-__ZN3WTF6VectorIPN3KJS10IdentifierELm0EE15reserveCapacityEm
-__Z10kjsyyparsev
-__Z8kjsyylexv
-__ZN3KJS5Lexer3lexEv
-__ZN3KJS5Lexer14makeIdentifierERKN3WTF6VectorINS_5UCharELm0EEE
-__ZN3KJS10Identifier3addEPKNS_5UCharEi
-__ZN3KJS5Lexer15matchPunctuatorEiiii
-__ZN3KJS7UStringC2ERKN3WTF6VectorINS_5UCharELm0EEE
-__ZN3KJS14ExpressionNodeC2ENS_6JSTypeE
-__ZN3KJS16ParserRefCountedC2Ev
-__ZN3KJS7UStringC1ERKS0_
-__ZN3KJS4NodeC2Ev
-__ZN3KJS10IdentifierC1ERKS0_
-__ZN3WTF6RefPtrIN3KJS14ExpressionNodeEEC1EPS2_
-__ZN3KJS16ParserRefCounted3refEv
-__ZN3WTF6RefPtrIN3KJS12PropertyNodeEEC1EPS2_
-__ZN3WTF10ListRefPtrIN3KJS16PropertyListNodeEEC1Ev
-__ZN3KJS11ResolveNodeC1ERKNS_10IdentifierE
-__ZN3KJS14ExpressionNodeC2Ev
-__ZN3WTF10ListRefPtrIN3KJS16ArgumentListNodeEEC1Ev
-__Z20makeFunctionCallNodePN3KJS14ExpressionNodeEPNS_13ArgumentsNodeE
-__ZNK3KJS15DotAccessorNode10isLocationEv
-__ZNK3KJS14ExpressionNode13isResolveNodeEv
-__ZNK3KJS14ExpressionNode21isBracketAccessorNodeEv
-__Z14makeNumberNoded
-__Z14makeNegateNodePN3KJS14ExpressionNodeE
-__ZNK3KJS10NumberNode8isNumberEv
-__ZN3KJS19ImmediateNumberNode8setValueEd
-__ZN3KJS5lexerEv
-__ZN3KJS5Lexer10scanRegExpEv
-__ZN3KJS6RegExp6createERKNS_7UStringES3_
-__ZNK3KJS7UString4findENS_5UCharEi
-__ZN3KJS17ObjectLiteralNodeC1EPNS_16PropertyListNodeE
-__Z14compileBracketiPiPPhPPKtS3_P9ErrorCodeiS_S_R11CompileData
-__ZN3KJS16FunctionBodyNode6createEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS4_IPNS_12FuncDeclNodeELm16EEE
-__ZN3KJS16FunctionBodyNodeC2EPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS4_IPNS_12FuncDeclNodeELm16EEE
-__ZN3KJS9ScopeNodeC2EPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS4_IPNS_12FuncDeclNodeELm16EEE
-__ZN3KJS9BlockNodeC1EPNS_14SourceElementsE
-__ZN3KJS13StatementNodeC2Ev
-__ZN3WTF6RefPtrIN3KJS13ParameterNodeEEC1EPS2_
-__ZN3WTF6RefPtrIN3KJS16FunctionBodyNodeEEC1EPS2_
-__ZN3KJS12FuncExprNode9addParamsEv
-__ZN3WTF10ListRefPtrIN3KJS13ParameterNodeEEC1Ev
-__ZN3KJS10ReturnNodeC1EPNS_14ExpressionNodeE
-__Z23allowAutomaticSemicolonv
-__ZN3KJS14SourceElementsC1Ev
-__ZN3WTF10PassRefPtrIN3KJS13StatementNodeEEC1EPS2_
-__ZN3KJS14SourceElements6appendEN3WTF10PassRefPtrINS_13StatementNodeEEE
-__ZNK3KJS13StatementNode16isEmptyStatementEv
-__ZN3WTF6VectorINS_6RefPtrIN3KJS13StatementNodeEEELm0EE14expandCapacityEm
-__ZN3WTF6VectorINS_6RefPtrIN3KJS13StatementNodeEEELm0EE15reserveCapacityEm
-__ZN3WTF6VectorIN3KJS10IdentifierELm0EE14expandCapacityEmPKS2_
-__ZN3WTF6VectorIN3KJS10IdentifierELm0EE14expandCapacityEm
-__ZN3WTF6VectorIN3KJS10IdentifierELm0EE15reserveCapacityEm
-__ZN3KJS20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEEC1Ev
-__Z26appendToVarDeclarationListRPN3KJS20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEEERKS4_j
-__Z20makeVarStatementNodePN3KJS14ExpressionNodeE
-__Z14makeAssignNodePN3KJS14ExpressionNodeENS_8OperatorES1_
-__ZN3KJS17ExprStatementNodeC1EPNS_14ExpressionNodeE
-__ZN3KJS6IfNodeC2EPNS_14ExpressionNodeEPNS_13StatementNodeE
-__Z21mergeDeclarationListsIPN3KJS20ParserRefCountedDataIN3WTF6VectorISt4pairINS0_10IdentifierEjELm16EEEEEET_SA_SA_
-__Z21mergeDeclarationListsIPN3KJS20ParserRefCountedDataIN3WTF6VectorIPNS0_12FuncDeclNodeELm16EEEEEET_S9_S9_
-__ZNK3KJS11ResolveNode10isLocationEv
-__ZNK3KJS11ResolveNode13isResolveNodeEv
-__Z22combineVarInitializersPN3KJS14ExpressionNodeEPNS_17AssignResolveNodeE
-__ZN3KJS14ExpressionNode28optimizeForUnnecessaryResultEv
-__ZN3WTF6VectorIPN3KJS10IdentifierELm0EE14expandCapacityEmPKS3_
-__ZN3WTF6VectorIPN3KJS10IdentifierELm0EE14expandCapacityEm
-__ZN3KJS12FuncDeclNode9addParamsEv
-__ZN3WTF6VectorIPN3KJS12FuncDeclNodeELm16EEC1Ev
-__ZN3WTF6VectorISt4pairIN3KJS10IdentifierEjELm16EE6appendIS4_EEvPKT_m
-__ZN3KJS16ParserRefCounted5derefEv
-__ZN3KJS20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEED1Ev
-__Z12makeLessNodePN3KJS14ExpressionNodeES1_
-__Z15makePostfixNodePN3KJS14ExpressionNodeENS_8OperatorE
-__ZN3WTF6RefPtrIN3KJS13StatementNodeEEC1EPS2_
-__ZN3KJS18PostIncResolveNode28optimizeForUnnecessaryResultEv
-__ZN3WTF6VectorISt4pairIN3KJS10IdentifierEjELm16EEaSERKS5_
-__ZN3WTF6VectorIPN3KJS12FuncDeclNodeELm16EEaSERKS4_
-__ZNK3KJS14ExpressionNode10isLocationEv
-__ZNK3KJS19BracketAccessorNode10isLocationEv
-__ZNK3KJS19BracketAccessorNode21isBracketAccessorNodeEv
-__ZN3KJS9ForInNodeC1ERKNS_10IdentifierEPNS_14ExpressionNodeES5_PNS_13StatementNodeE
-__ZN3KJS9ThrowNodeC1EPNS_14ExpressionNodeE
-__Z14makeTypeOfNodePN3KJS14ExpressionNodeE
-__ZN3WTF6VectorINS_6RefPtrIN3KJS13StatementNodeEEELm0EEC1Ev
-__ZN3WTF6RefPtrIN3KJS14CaseClauseNodeEEC1EPS2_
-__ZN3WTF10ListRefPtrIN3KJS14ClauseListNodeEEC1Ev
-__ZN3KJS13CaseBlockNodeC2EPNS_14ClauseListNodeEPNS_14CaseClauseNodeES2_
-__Z11makeAddNodePN3KJS14ExpressionNodeES1_
-__ZN3WTF10ListRefPtrIN3KJS11ElementNodeEEC1Ev
-__ZN3WTF6RefPtrIN3KJS11ElementNodeEEC1EPS2_
-__ZNK3KJS18EmptyStatementNode16isEmptyStatementEv
-__ZN3KJS9BreakNodeC1Ev
-__Z32branchFindFirstAssertedCharacterPKhb
-__Z20branchNeedsLineStartPKhjj
-__ZN3KJS10IdentifierC1ERKNS_7UStringE
-__ZN3WTF6RefPtrIN3KJS7UString3RepEED1Ev
-__ZN3KJS9CommaNodeC2EPNS_14ExpressionNodeES2_
-__Z14makePrefixNodePN3KJS14ExpressionNodeENS_8OperatorE
-__ZN3WTF6RefPtrIN3KJS13ArgumentsNodeEEC1EPS2_
-__ZN3WTF6VectorIPN3KJS7UStringELm0EE14expandCapacityEmPKS3_
-__ZN3WTF6VectorIPN3KJS7UStringELm0EE14expandCapacityEm
-__ZN3WTF6VectorIN3KJS5UCharELm0EE14expandCapacityEmPKS2_
-__ZN3WTF6VectorIN3KJS5UCharELm0EE14expandCapacityEm
-__ZNK3KJS14ExpressionNode8isNumberEv
-__ZN3KJS19PlaceholderTrueNodeC1Ev
-__ZN3KJS18EmptyStatementNodeC1Ev
-__Z14makeDeleteNodePN3KJS14ExpressionNodeE
-__Z15isCountedRepeatPKtS0_
-__ZN3KJS12ContinueNodeC1Ev
-__ZN3KJS9ForInNodeC1EPNS_14ExpressionNodeES2_PNS_13StatementNodeE
-__ZN3KJS18PostDecResolveNode28optimizeForUnnecessaryResultEv
-__Z17bracketIsAnchoredPKh
-__ZN3WTF6VectorISt4pairIN3KJS10IdentifierEjELm16EE14expandCapacityEmPKS4_
-__ZN3WTF6VectorISt4pairIN3KJS10IdentifierEjELm16EE14expandCapacityEm
-__ZN3WTF6VectorISt4pairIN3KJS10IdentifierEjELm16EE15reserveCapacityEm
-__ZN3KJS7UString4fromEd
-_kjs_dtoa
-_d2b
-_Balloc
-__ZN3KJS6parserEv
-__ZN3KJS6Parser16didFinishParsingEPNS_14SourceElementsEPNS_20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEEEPNS3_INS5_IPNS_12FuncDeclNodeELm16EEEEEi
-__ZN3KJS5Lexer5clearEv
-__ZN3WTF25TCMalloc_Central_FreeList11InsertRangeEPvS1_i
+__ZN3WTF11fastReallocILb1EEEPvS1_m
+__ZN3JSC4Heap8allocateEm
+__ZN3JSCL13allocateBlockILNS_8HeapTypeE0EEEPNS_14CollectorBlockEv
+__ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
+__ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
+__ZN3JSC14JSGlobalObject5resetENS_10JSValuePtrE
+__ZN3JSC4Heap12heapAllocateILNS_8HeapTypeE0EEEPvm
+__ZN3JSC17FunctionPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
+__ZN3JSC8jsStringEPNS_12JSGlobalDataERKNS_7UStringE
+__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
+__ZN3JSC7UStringC1EPKc
+__ZN3JSCL9createRepEPKc
+__ZN3JSC8JSObject9putDirectERKNS_10IdentifierENS_10JSValuePtrEjbRNS_15PutPropertySlotE
+__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjRm
+__ZN3JSC9Structure3getERKNS_10IdentifierERj
+__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjRm
+__ZN3JSC9Structure3putERKNS_10IdentifierEj
+__ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEj
+__ZN3JSC17FunctionPrototype21addFunctionPropertiesEPNS_9ExecStateEPNS_9StructureE
+__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_10JSValuePtrES2_PNS_8JSObjectESA_RKNS_7ArgListEE
+__ZN3JSC8JSObject34putDirectFunctionWithoutTransitionEPNS_9ExecStateEPNS_16InternalFunctionEj
+__ZN3JSC15ObjectPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC9Structure26rehashPropertyMapHashTableEj
+__ZN3JSC15StringPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
+__ZN3JSC16BooleanPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC15NumberPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC12jsNumberCellEPNS_9ExecStateEd
+__ZN3JSCL13allocateBlockILNS_8HeapTypeE1EEEPNS_14CollectorBlockEv
+__ZN3JSC15RegExpPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC14ErrorPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
+__ZN3WTF6RefPtrIN3JSC7UString3RepEED1Ev
+__ZN3JSC20NativeErrorPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7UStringES9_
+__ZN3JSC17ObjectConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_15ObjectPrototypeE
+__ZN3JSC19FunctionConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_17FunctionPrototypeE
+__ZNK3JSC16InternalFunction9classInfoEv
+__ZN3JSC16ArrayConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_14ArrayPrototypeE
+__ZNK3JSC14ArrayPrototype9classInfoEv
+__ZN3JSC17StringConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_PNS_15StringPrototypeE
+__ZNK3JSC15StringPrototype9classInfoEv
+__ZN3JSC18BooleanConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_16BooleanPrototypeE
+__ZNK3JSC13BooleanObject9classInfoEv
+__ZN3JSC17NumberConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_15NumberPrototypeE
+__ZN3JSC15DateConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_PNS_13DatePrototypeE
+__ZNK3JSC13DatePrototype9classInfoEv
+__ZN3JSC17RegExpConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_15RegExpPrototypeE
+__ZN3JSC16ErrorConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_14ErrorPrototypeE
+__ZNK3JSC13ErrorInstance9classInfoEv
+__ZN3JSC22NativeErrorConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_20NativeErrorPrototypeE
+__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPNS_7UString3RepE
+__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addERKS4_
+__ZN3JSC10MathObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
+__ZN3JSC12SmallStrings24singleCharacterStringRepEh
+__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS2_16SymbolTableEntryENS2_17IdentifierRepHashENS_10HashTraitsIS5_EENS2_26SymbolTableIndexHashTraitsEE3addEPS4_RKS6_
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_16SymbolTableEntryEENS_18PairFirstExtractorIS8_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS5_EENS2_26SymbolTableIndexHashTraitsEEESE_E6rehashEi
+__ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_10JSValuePtrE
+__ZN3JSC9Structure17copyPropertyTableEv
+__ZN3JSC14JSGlobalObject14setTimeoutTimeEj
+__ZN3JSC14JSGlobalObject10globalExecEv
+__ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
+__ZN3JSC4Heap4heapENS_10JSValuePtrE
+__ZN3JSC4Heap7protectENS_10JSValuePtrE
+__ZN3WTF7HashMapIPN3JSC6JSCellEjNS_7PtrHashIS3_EENS_10HashTraitsIS3_EENS6_IjEEE3addERKS3_RKj
+__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi
+__ZN3JSC6JSCellnwEmPNS_9ExecStateE
+__ZN3JSC14JSGlobalObject17startTimeoutCheckEv
+__ZN3JSC11Interpreter17resetTimeoutCheckEv
+__ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_10JSValuePtrE
+__ZN3JSC6JSLock4lockEb
+__ZN3JSC6Parser5parseINS_11ProgramNodeEEEN3WTF10PassRefPtrIT_EEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPiPNS_7UStringE
+__ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
+__ZN3JSC7UStringaSEPKc
+__Z10jscyyparsePv
+__ZN3JSC5Lexer3lexEPvS1_
+__ZN3WTF6VectorItLm0EE15reserveCapacityEm
+__ZN3WTF6VectorItLm0EE6appendItEEvRKT_
+__ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKti
+__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addIPKcNS1_17CStringTranslatorEEESt4pairINS_24HashTableIteratorAdapterINS_9HashTableIS4_S4_NS_17IdentityExtractorIS4_EES6_S8_S8_EES4_EEbERKT_
+__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
+__ZN3WTF7HashSetIPN3JSC16ParserRefCountedENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC16ParserRefCountedES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3JSC16ParserRefCountedC2EPNS_12JSGlobalDataE
+__ZN3JSC16ParserRefCounted3refEv
+__ZL20makeFunctionCallNodePvN3JSC8NodeInfoIPNS0_14ExpressionNodeEEENS1_IPNS0_13ArgumentsNodeEEEiii
+__ZNK3JSC15DotAccessorNode10isLocationEv
+__ZNK3JSC14ExpressionNode13isResolveNodeEv
+__ZNK3JSC14ExpressionNode21isBracketAccessorNodeEv
+__ZN3WTF7HashMapIPN3JSC16ParserRefCountedEjNS_7PtrHashIS3_EENS_10HashTraitsIS3_EENS6_IjEEE3addERKS3_RKj
+__ZN3WTF9HashTableIPN3JSC16ParserRefCountedESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi
+__ZN3JSC14SourceElements6appendEN3WTF10PassRefPtrINS_13StatementNodeEEE
+__ZNK3JSC13StatementNode16isEmptyStatementEv
+__ZN3JSC6Parser16didFinishParsingEPNS_14SourceElementsEPNS_20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEEEPNS3_INS5_INS4_6RefPtrINS_12FuncDeclNodeEEELm0EEEEEjii
+__ZN3JSC5Lexer5clearEv
+__ZN3WTF6VectorIN3JSC10IdentifierELm64EE14shrinkCapacityEm
+__ZN3WTF15deleteAllValuesIPN3JSC16ParserRefCountedEKNS_9HashTableIS3_S3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EESA_EEEEvRT0_
+__ZN3JSC15DotAccessorNodeD1Ev
+__ZN3JSC12NodeReleaser15releaseAllNodesEPNS_16ParserRefCountedE
+__ZN3JSC15DotAccessorNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC12NodeReleaser5adoptEN3WTF10PassRefPtrINS_16ParserRefCountedEEE
+__ZN3JSC16ParserRefCounted9hasOneRefEv
+__ZN3JSC16ParserRefCounted5derefEv
+__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS9_INS8_6RefPtrINS_12FuncDeclNodeEEELm0EEEji
+__ZN3WTF6VectorINS_6RefPtrIN3JSC13StatementNodeEEELm0EE14shrinkCapacityEm
+__ZN3JSC14SourceElementsD1Ev
+__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE
+__ZN3JSC11Interpreter7executeEPNS_11ProgramNodeEPNS_9ExecStateEPNS_14ScopeChainNodeEPNS_8JSObjectEPNS_10JSValuePtrE
+__ZN3JSC11ProgramNode16generateBytecodeEPNS_14ScopeChainNodeE
+__ZN3JSC9CodeBlockC1EPNS_9ScopeNodeENS_8CodeTypeEN3WTF10PassRefPtrINS_14SourceProviderEEEj
+__ZN3WTF7HashSetIPN3JSC16ProgramCodeBlockENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC16ProgramCodeBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3JSC17BytecodeGeneratorC2EPNS_11ProgramNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISE_EENS_26SymbolTableIndexHashTraitsEEEPNS_16ProgramCodeBlockE
+__ZN3WTF6VectorIN3JSC11InstructionELm0EE14expandCapacityEm
+__ZN3JSC9Structure22toDictionaryTransitionEPS0_
+__ZN3JSC17BytecodeGenerator11newRegisterEv
+__ZN3JSC9Structure24fromDictionaryTransitionEPS0_
+__ZN3JSC17BytecodeGenerator8generateEv
+__ZN3JSC11ProgramNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13emitDebugHookENS_11DebugHookIDEii
+__ZN3JSC17BytecodeGenerator11addConstantENS_10JSValuePtrE
+__ZN3WTF9HashTableIPN3JSC23JSValueEncodedAsPointerESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS1_17BytecodeGenerator17JSValueHashTraitsENS_10HashTraitsIjEEEESC_E6expandEv
+__ZN3WTF6VectorIN3JSC8RegisterELm0EE14expandCapacityEm
+__ZNK3JSC13StatementNode6isLoopEv
+__ZN3JSC17BytecodeGenerator8emitNodeEPNS_10RegisterIDEPNS_4NodeE
+__ZN3WTF6VectorIN3JSC8LineInfoELm0EE14expandCapacityEm
+__ZN3JSC17ExprStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC19FunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC11ResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11registerForERKNS_10IdentifierE
+__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator11emitGetByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator11addConstantERKNS_10IdentifierE
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_iENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS5_EENS2_17BytecodeGenerator28IdentifierMapIndexHashTraitsEEESD_E6expandEv
+__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator8emitCallENS_8OpcodeIDEPNS_10RegisterIDES3_S3_PNS_13ArgumentsNodeEjjj
+__ZN3WTF6VectorIN3JSC12CallLinkInfoELm0EE14expandCapacityEm
+__ZN3JSC9CodeBlock11shrinkToFitEv
+__ZN3WTF6VectorIN3JSC11InstructionELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIN3JSC17GlobalResolveInfoELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIPN3JSC12CallLinkInfoELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14shrinkCapacityEm
+__ZN3JSC17ExprStatementNodeD1Ev
+__ZN3JSC19FunctionCallDotNodeD1Ev
+__ZN3JSC19FunctionCallDotNode12releaseNodesERNS_12NodeReleaserE
+__ZN3WTF6VectorINS_6RefPtrIN3JSC16ParserRefCountedEEELm0EE14expandCapacityEm
+__ZN3JSC16ParserRefCounted12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC13ArgumentsNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11ResolveNodeD1Ev
+__ZN3JSC13ArgumentsNodeD1Ev
+__ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12RegisterFileE
+__ZN3JSC3JIT14privateCompileEv
+__ZN3JSC3JIT22privateCompileMainPassEv
+__ZN3JSC3JIT21compileGetByIdHotPathEiiPNS_10IdentifierEj
+__ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE14expandCapacityEm
+__ZN3JSC3JIT13compileOpCallENS_8OpcodeIDEPNS_11InstructionEj
+__ZN3WTF6VectorIN3JSC10CallRecordELm0EE14expandCapacityEm
+__ZN3JSC3JIT22privateCompileLinkPassEv
+__ZN3JSC3JIT23privateCompileSlowCasesEv
+__ZN3JSC3JIT22compileGetByIdSlowCaseEiiPNS_10IdentifierERPNS_13SlowCaseEntryEj
+__ZN3JSC3JIT21compileOpCallSlowCaseEPNS_11InstructionERPNS_13SlowCaseEntryEjNS_8OpcodeIDE
+__ZN3JSC3JIT22compileOpCallSetupArgsEPNS_11InstructionE
+__ZN3JSC12X86Assembler3jneEv
+__ZN3WTF6VectorIN3JSC10CallRecordELm0EE6appendIS2_EEvRKT_
+__ZN3JSC9CodeBlock10setJITCodeERNS_10JITCodeRefE
+__ZN3JSC17BytecodeGenerator18dumpsGeneratedCodeEv
+__ZN3WTF10RefCountedIN3JSC14ExecutablePoolEE5derefEv
+ctiTrampoline
+__ZN3JSC11Interpreter16cti_op_get_by_idEPvz
+__ZNK3JSC10JSValuePtr3getEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC10MathObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_10JSValuePtrES2_PNS_8JSObjectES6_RKNS_7ArgListEE
+__ZN3JSC27ctiPatchCallByReturnAddressEPvS0_
+__ZN3JSC11Interpreter25cti_op_call_NotJSFunctionEPvz
+__ZN3JSC17PrototypeFunction11getCallDataERNS_8CallDataE
+__ZN3JSCL19mathProtoFuncRandomEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3WTF12randomNumberEv
+__ZN3JSC11ProgramNodeD1Ev
+__ZN3WTF9HashTableIPN3JSC16ProgramCodeBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
+__ZN3JSC9CodeBlockD2Ev
+__ZN3JSC17StructureStubInfo5derefEv
+__ZN3JSC9ScopeNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC14JSGlobalObject16stopTimeoutCheckEv
+__ZN3JSC4Heap9unprotectENS_10JSValuePtrE
+__ZNK3JSC12JSNumberCell8toStringEPNS_9ExecStateE
+__ZN3JSC7UString4fromEd
+__ZN3WTF4dtoaEdiPiS0_PPc
+__ZN3WTFL3d2bEdPiS0_
+__ZN3WTFL8pow5multEPNS_6BigintEi
+__ZN3WTFL4multEPNS_6BigintES1_
+__ZN3WTFL6lshiftEPNS_6BigintEi
+__ZN3WTFL6quoremEPNS_6BigintES1_
+__ZN3WTFL4diffEPNS_6BigintES1_
+__ZN3JSC7UString3Rep7destroyEv
+-[WTFMainThreadCaller call]
+__ZN3WTF31dispatchFunctionsFromMainThreadEv
+__ZN3JSC4Heap7collectEv
+__ZN3JSC4Heap30markStackObjectsConservativelyEv
+__ZN3JSC4Heap31markCurrentThreadConservativelyEv
+__ZN3JSC4Heap39markCurrentThreadConservativelyInternalEv
+__ZN3JSC4Heap18markConservativelyEPvS1_
+__ZN3JSC4Heap20markProtectedObjectsEv
+__ZN3JSC12SmallStrings4markEv
+__ZN3JSC6JSCell4markEv
+__ZN3JSC4Heap5sweepILNS_8HeapTypeE0EEEmv
+__ZN3JSC14JSGlobalObjectD2Ev
+__ZN3JSC17FunctionPrototypeD0Ev
+__ZN3JSC17PrototypeFunctionD0Ev
+__ZN3JSC16BooleanPrototypeD0Ev
+__ZN3JSC15NumberPrototypeD0Ev
+__ZN3JSC14ErrorPrototypeD0Ev
+__ZN3JSC17ObjectConstructorD0Ev
+__ZN3JSC16ArrayConstructorD0Ev
+__ZN3JSC17StringConstructorD0Ev
+__ZN3JSC18BooleanConstructorD0Ev
+__ZN3JSC17NumberConstructorD0Ev
+__ZN3JSC17RegExpConstructorD0Ev
+__ZN3JSC16ErrorConstructorD0Ev
+__ZN3JSC22NativeErrorConstructorD0Ev
+__ZN3JSC18GlobalEvalFunctionD0Ev
+__ZN3JSC4Heap5sweepILNS_8HeapTypeE1EEEmv
__ZN3WTF25TCMalloc_Central_FreeList11ShrinkCacheEib
-__ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansEPv
-__ZN3WTF15deleteAllValuesIPN3KJS16ParserRefCountedEKNS_9HashTableIiiNS_17IdentityExtractorIiEENS_7IntHashIiEENS_10HashTraitsIiEESA_EEEEvRT0_
-__ZN3KJS19BracketAccessorNodeD1Ev
-__ZN3KJS11ProgramNodeC2EPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS4_IPNS_12FuncDeclNodeELm16EEE
-__ZNK3KJS8JSObject8toObjectEPNS_9ExecStateE
-__ZN3KJS11ProgramNode7executeEPNS_9ExecStateE
-__ZN3KJS11ProgramNode21initializeSymbolTableEPNS_9ExecStateE
-__ZN3WTF6VectorImLm0EE6resizeEm
-__ZN3WTF6VectorImLm0EE14expandCapacityEm
-__ZN3WTF6VectorImLm0EE15reserveCapacityEm
-__ZN3WTF9HashTableINS_6RefPtrIN3KJS7UString3RepEEESt4pairIS5_mENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS2_23IdentifierRepHashTraitsENS2_26SymbolTableIndexHashTraitsEEESC_E3addIS5_mNS_17HashMapTranslatorILb1ES7_NS_18PairBaseHashTraitsISC_SD_EESE_SA_EEEES6_INS_17HashTableIteratorIS5_S7_S9_SA_SE_SC_EEbERKT_RKT0_
-__ZN3WTF9HashTableINS_6RefPtrIN3KJS7UString3RepEEESt4pairIS5_mENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS2_23IdentifierRepHashTraitsENS2_26SymbolTableIndexHashTraitsEEESC_E6rehashEi
-__ZN3KJS14JSGlobalObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZNK3WTF7HashMapINS_6RefPtrIN3KJS7UString3RepEEEmNS2_17IdentifierRepHashENS2_23IdentifierRepHashTraitsENS2_26SymbolTableIndexHashTraitsEE3getEPS4_
-__ZN3KJS11PropertyMap11getLocationERKNS_10IdentifierE
-__ZN3KJS6Lookup9findEntryEPKNS_9HashTableERKNS_10IdentifierE
-__ZNK3KJS7UString14toStrictUInt32EPb
-__ZN3KJS8JSObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3WTF6VectorIN3KJS17LocalStorageEntryELm32EE15reserveCapacityEm
-__ZN3KJS11FunctionImpC2EPNS_9ExecStateERKNS_10IdentifierEPNS_16FunctionBodyNodeERKNS_10ScopeChainE
-__ZN3KJS15ObjectObjectImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZN3KJS9ScopeNode22optimizeVariableAccessEPNS_9ExecStateE
-__ZN3WTF6VectorIPN3KJS4NodeELm16EE14expandCapacityEm
-__ZN3WTF6VectorIPN3KJS4NodeELm16EE15reserveCapacityEm
-__ZN3KJS16VarStatementNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS17AssignResolveNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS17ObjectLiteralNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS16PropertyListNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS12PropertyNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS4Node22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPS0_Lm16EEE
-__ZN3KJS14LogicalNotNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS14LogicalAndNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS15DotAccessorNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS11ResolveNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS11GreaterNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS19FunctionCallDotNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS13ArgumentsNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS16ArgumentListNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS9EqualNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS18NotStrictEqualNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS6IfNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS17ExprStatementNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS13AssignDotNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS13LogicalOrNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS8WithNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS9BlockNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS23FunctionCallResolveNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS21FunctionCallValueNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS9ArrayNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS11ElementNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS10IfElseNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS7AddNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS6InNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS11NewExprNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS16VarStatementNode7executeEPNS_9ExecStateE
-__ZN3KJS18AssignLocalVarNode8evaluateEPNS_9ExecStateE
-__ZN3KJS17ObjectLiteralNode8evaluateEPNS_9ExecStateE
-__ZN3KJS16PropertyListNode8evaluateEPNS_9ExecStateE
-__ZN3KJS10StringNode8evaluateEPNS_9ExecStateE
-__ZN3KJS13jsOwnedStringERKNS_7UStringE
-__ZN3KJS8JSObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
-__ZN3KJS14LogicalNotNode8evaluateEPNS_9ExecStateE
-__ZN3KJS14LogicalNotNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS14LogicalAndNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS15DotAccessorNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS11ResolveNode8evaluateEPNS_9ExecStateE
-__ZN3KJS11GreaterNode8evaluateEPNS_9ExecStateE
-__ZN3KJS19FunctionCallDotNode8evaluateEPNS_9ExecStateE
-__ZN3KJS15DotAccessorNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS9ExecState19lexicalGlobalObjectEv
-__ZNK3KJS9StringImp8toObjectEPNS_9ExecStateE
-__ZN3KJS14StringInstance18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS15StringPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS20staticFunctionGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectERKNS_4ListEE
-__ZNK3KJS19InternalFunctionImp14implementsCallEv
-__ZN3KJS16ArgumentListNode12evaluateListEPNS_9ExecStateERNS_4ListE
-__ZN3KJS17PrototypeFunction14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS22stringProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS14StringInstance9classInfoEv
-__ZNK3KJS9StringImp8toStringEPNS_9ExecStateE
-__ZNK3KJS7JSValue9toIntegerEPNS_9ExecStateE
-__ZNK3KJS7UString4findERKS0_i
-__ZN3KJS19ImmediateNumberNode8evaluateEPNS_9ExecStateE
-__ZN3KJS14LogicalAndNode8evaluateEPNS_9ExecStateE
-__ZN3KJS9EqualNode8evaluateEPNS_9ExecStateE
-__ZN3KJS5equalEPNS_9ExecStateEPNS_7JSValueES3_
-__ZN3KJS19FunctionCallDotNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS10RegExpNode8evaluateEPNS_9ExecStateE
-__ZN3KJS15RegExpObjectImp15createRegExpImpEPNS_9ExecStateEN3WTF10PassRefPtrINS_6RegExpEEE
-__ZN3KJS20stringProtoFuncMatchEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS9RegExpImp9classInfoEv
-__ZN3KJS15RegExpObjectImp12performMatchEPNS_6RegExpERKNS_7UStringEiRiS6_PPi
-__ZN3KJS6RegExp5matchERKNS_7UStringEiPN3WTF11OwnArrayPtrIiEE
-__Z5matchPKtPKhiR9MatchData
-__ZNK3KJS8JSObject9toBooleanEPNS_9ExecStateE
-__ZN3KJS18NotStrictEqualNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS7UString8toUInt32EPbb
-__ZNK3KJS7UString8toDoubleEbb
-__ZN3KJS11strictEqualEPNS_9ExecStateEPNS_7JSValueES3_
-__ZN3KJS12FuncExprNode8evaluateEPNS_9ExecStateE
-__ZN3KJS14JSGlobalObject17tearOffActivationEPNS_9ExecStateEb
-__ZN3KJS6IfNode7executeEPNS_9ExecStateE
-__ZN3KJS18LocalVarAccessNode8evaluateEPNS_9ExecStateE
-__ZN3KJS17ExprStatementNode7executeEPNS_9ExecStateE
-__ZN3KJS13AssignDotNode8evaluateEPNS_9ExecStateE
-__ZN3KJS11FunctionImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS17FunctionExecStateC1EPNS_14JSGlobalObjectEPNS_8JSObjectEPNS_16FunctionBodyNodeEPNS_9ExecStateEPNS_11FunctionImpERKNS_4ListE
-__ZN3KJS14JSGlobalObject14pushActivationEPNS_9ExecStateE
-__ZN3KJS13ActivationImp4initEPNS_9ExecStateE
-__ZN3KJS16FunctionBodyNode7executeEPNS_9ExecStateE
-__ZN3KJS16FunctionBodyNode21initializeSymbolTableEPNS_9ExecStateE
-__ZN3KJS9ForInNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS17AssignBracketNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS19BracketAccessorNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS10ReturnNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS9ForInNode7executeEPNS_9ExecStateE
-__ZN3KJS8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
-__ZNK3KJS11PropertyMap26getEnumerablePropertyNamesERNS_17PropertyNameArrayE
-__ZNK3KJS8JSObject9classInfoEv
-__ZN3KJS13ActivationImp18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS13ActivationImp3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
-__ZN3KJS17AssignBracketNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS6JSCell9getUInt32ERj
-__ZN3KJS19BracketAccessorNode8evaluateEPNS_9ExecStateE
-__ZN3KJS10ReturnNode7executeEPNS_9ExecStateE
-__ZN3KJS14JSGlobalObject13popActivationEv
-__ZN3KJS11FunctionImp18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS10NumberNode8evaluateEPNS_9ExecStateE
-__ZN3KJS9CommaNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS13ActivationImpC1ERKNS0_14ActivationDataEb
-__ZN3WTF6VectorIN3KJS17LocalStorageEntryELm32EEC2ERKS3_
-__ZN3KJS13ActivationImp15argumentsGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS13ActivationImp21createArgumentsObjectEPNS_9ExecStateE
-__ZN3KJS9ArgumentsC2EPNS_9ExecStateEPNS_11FunctionImpERKNS_4ListEPNS_13ActivationImpE
-__ZN3KJS14IndexToNameMapC2EPNS_11FunctionImpERKNS_4ListE
-__ZN3KJS11FunctionImp16getParameterNameEi
-__ZN3KJS7UString4fromEj
-__ZN3KJS9Arguments18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS9CommaNode8evaluateEPNS_9ExecStateE
-__ZN3KJS8ThisNode8evaluateEPNS_9ExecStateE
-__ZN3KJS23FunctionCallResolveNode8evaluateEPNS_9ExecStateE
-__ZN3KJS9WhileNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS18PostDecResolveNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS18LocalVarAccessNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS13LogicalOrNode8evaluateEPNS_9ExecStateE
-__ZN3KJS11NewExprNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS14ArrayObjectImp19implementsConstructEv
-__ZN3KJS14ArrayObjectImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZN3KJS9WhileNode7executeEPNS_9ExecStateE
-__ZN3KJS19PostDecLocalVarNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3KJS13ArrayInstance3putEPNS_9ExecStateEjPNS_7JSValueEi
-__ZN3KJS15RegExpObjectImp18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS15RegExpObjectImp3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
-__ZN3KJS7ForNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS8LessNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS17PreIncResolveNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS8NullNode8evaluateEPNS_9ExecStateE
-__ZN3KJS13ArrayInstance18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3KJS17TypeOfResolveNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS18LocalVarTypeOfNode8evaluateEPNS_9ExecStateE
-__ZN3KJS18typeStringForValueEPNS_7JSValueE
-__ZNK3KJS8JSObject21masqueradeAsUndefinedEv
-__ZNK3KJS8JSObject14implementsCallEv
-__ZN3KJS12FuncDeclNode7executeEPNS_9ExecStateE
-__ZN3KJS11FunctionImp3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
-__ZN3KJS9ArrayNode8evaluateEPNS_9ExecStateE
-__ZN3KJS13ArrayInstanceC2EPNS_8JSObjectERKNS_4ListE
-__ZN3KJS13ArrayInstance3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
-__ZN3KJS13ArrayInstance9setLengthEj
-__ZN3KJS7ForNode7executeEPNS_9ExecStateE
-__ZN3KJS8LessNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS13ArrayInstance18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS13ArrayInstance12lengthGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS14ArrayPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS18arrayProtoFuncPushEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS8TrueNode8evaluateEPNS_9ExecStateE
-__ZN3KJS9BlockNode7executeEPNS_9ExecStateE
-__ZN3KJS18PreIncLocalVarNode8evaluateEPNS_9ExecStateE
-__ZN3KJS14StringInstance3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
-__ZN3KJS13LogicalOrNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS8WithNode7executeEPNS_9ExecStateE
-__ZN3KJS15NumberObjectImp18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS24LocalVarFunctionCallNode8evaluateEPNS_9ExecStateE
-__ZN3KJS15ConditionalNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS22stringProtoFuncReplaceEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS7replaceEPNS_9ExecStateEPNS_9StringImpEPNS_7JSValueES5_
-__ZNK3KJS7UString30spliceSubstringsWithSeparatorsEPKNS0_5RangeEiPKS0_i
-__ZN3KJS15ConditionalNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS9StringImp9toBooleanEPNS_9ExecStateE
-__ZN3KJS20stringProtoFuncSplitEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS7UString6substrEii
-__ZN3KJS7UString3Rep6createEN3WTF10PassRefPtrIS1_EEii
-__ZN3KJS7TryNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS15LessNumbersNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS15DotAccessorNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS10NumberNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS7TryNode7executeEPNS_9ExecStateE
-__ZN3KJS21arrayProtoFuncForEachEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS18PostIncResolveNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS18PostIncResolveNode8evaluateEPNS_9ExecStateE
-__ZN3KJS13ActivationImp18isActivationObjectEv
-__ZN3KJS13MathObjectImp18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS21FunctionCallValueNode8evaluateEPNS_9ExecStateE
-__ZN3KJS12NotEqualNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS9FalseNode8evaluateEPNS_9ExecStateE
-__ZN3KJS19arrayProtoFuncShiftEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS13ArrayInstance14deletePropertyEPNS_9ExecStateEj
-__ZNK3KJS11FunctionImp19implementsConstructEv
-__ZN3KJS11FunctionImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZN3KJS9EqualNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS25functionProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS11FunctionImp9classInfoEv
-__ZNK3KJS4Node8toStringEv
-__ZNK3KJS9ScopeNode8streamToERNS_12SourceStreamE
-__ZN3KJS7UString6appendEt
-__ZN3KJS7UString6appendERKS0_
-__ZN3KJS7UString6appendEPKc
-__ZN3KJS7UString14expandCapacityEi
-__ZN3KJS12SourceStreamlsEPKNS_4NodeE
-__ZNK3KJS17ExprStatementNode8streamToERNS_12SourceStreamE
-__ZNK3KJS4Node21needsParensIfLeftmostEv
-__ZNK3KJS23FunctionCallResolveNode8streamToERNS_12SourceStreamE
-__ZNK3KJS13ArgumentsNode8streamToERNS_12SourceStreamE
-__ZNK3KJS16ArgumentListNode8streamToERNS_12SourceStreamE
-__ZNK3KJS11ResolveNode10precedenceEv
-__ZNK3KJS11ResolveNode8streamToERNS_12SourceStreamE
-__ZNK3KJS13AssignDotNode8streamToERNS_12SourceStreamE
-__ZNK3KJS8ThisNode10precedenceEv
-__ZNK3KJS8ThisNode8streamToERNS_12SourceStreamE
-__ZNK3KJS19FunctionCallDotNode10precedenceEv
-__ZNK3KJS19FunctionCallDotNode8streamToERNS_12SourceStreamE
-__ZNK3KJS16FunctionBodyNode11paramStringEv
-__ZNK3KJS15RegExpObjectImp14arrayOfMatchesEPNS_9ExecStateE
-__ZN3KJS9Arguments17mappedIndexGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS19arrayProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS22functionProtoFuncApplyEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS13ArrayInstance9classInfoEv
-__ZN3KJS24substituteBackreferencesERKNS_7UStringES2_PiPNS_6RegExpE
-__ZNK3KJS15DotAccessorNode10precedenceEv
-__ZNK3KJS15DotAccessorNode8streamToERNS_12SourceStreamE
-__ZNK3KJS16VarStatementNode8streamToERNS_12SourceStreamE
-__ZNK3KJS17AssignResolveNode8streamToERNS_12SourceStreamE
-__ZNK3KJS6IfNode8streamToERNS_12SourceStreamE
-__ZNK3KJS14LogicalNotNode8streamToERNS_12SourceStreamE
-__ZNK3KJS9ArrayNode10precedenceEv
-__ZNK3KJS9ArrayNode8streamToERNS_12SourceStreamE
-__ZNK3KJS11ElementNode8streamToERNS_12SourceStreamE
-__ZNK3KJS10StringNode10precedenceEv
-__ZNK3KJS10StringNode8streamToERNS_12SourceStreamE
-__ZN3KJS29escapeStringForPrettyPrintingERKNS_7UStringE
-__ZNK3KJS9BlockNode8streamToERNS_12SourceStreamE
-__ZNK3KJS17AssignBracketNode8streamToERNS_12SourceStreamE
-__ZNK3KJS10IfElseNode8streamToERNS_12SourceStreamE
-__ZNK3KJS9EqualNode8streamToERNS_12SourceStreamE
-__ZNK3KJS9EqualNode10precedenceEv
-__ZN3KJS35streamLeftAssociativeBinaryOperatorERNS_12SourceStreamENS_10PrecedenceEPKcPKNS_4NodeES7_
-__ZNK3KJS17ReadModifyDotNode8streamToERNS_12SourceStreamE
-__ZNK3KJS7AddNode10precedenceEv
-__ZNK3KJS7AddNode8streamToERNS_12SourceStreamE
-__ZNK3KJS15ConditionalNode10precedenceEv
-__ZNK3KJS15ConditionalNode8streamToERNS_12SourceStreamE
-__ZNK3KJS10RegExpNode10precedenceEv
-__ZNK3KJS10RegExpNode8streamToERNS_12SourceStreamE
-__ZNK3KJS21ReadModifyResolveNode8streamToERNS_12SourceStreamE
-__ZNK3KJS7TryNode8streamToERNS_12SourceStreamE
-__ZNK3KJS11NewExprNode10precedenceEv
-__ZNK3KJS11NewExprNode8streamToERNS_12SourceStreamE
-__ZNK3KJS10NumberNode10precedenceEv
-__ZNK3KJS10NumberNode8streamToERNS_12SourceStreamE
-__ZN3KJS12SourceStreamlsEd
-__ZNK3KJS13LogicalOrNode10precedenceEv
-__ZNK3KJS13LogicalOrNode8streamToERNS_12SourceStreamE
-__ZNK3KJS8NullNode10precedenceEv
-__ZNK3KJS8NullNode8streamToERNS_12SourceStreamE
-__ZNK3KJS14LogicalAndNode8streamToERNS_12SourceStreamE
-__ZNK3KJS14LogicalAndNode10precedenceEv
-__ZNK3KJS14LogicalNotNode10precedenceEv
-__ZN3KJS7UString17expandPreCapacityEi
-__ZN3KJS19BracketAccessorNode17evaluateToBooleanEPNS_9ExecStateE
-__ZNK3KJS11GreaterNode10precedenceEv
-__ZNK3KJS11GreaterNode8streamToERNS_12SourceStreamE
-__ZNK3KJS17ObjectLiteralNode10precedenceEv
-__ZNK3KJS17ObjectLiteralNode8streamToERNS_12SourceStreamE
-__ZNK3KJS16PropertyListNode8streamToERNS_12SourceStreamE
-__ZNK3KJS12PropertyNode8streamToERNS_12SourceStreamE
-__ZNK3KJS8LessNode10precedenceEv
-__ZNK3KJS8LessNode8streamToERNS_12SourceStreamE
-__ZNK3KJS19BracketAccessorNode10precedenceEv
-__ZNK3KJS19BracketAccessorNode8streamToERNS_12SourceStreamE
-__ZNK3KJS15TypeOfValueNode10precedenceEv
-__ZNK3KJS15TypeOfValueNode8streamToERNS_12SourceStreamE
-__ZNK3KJS7ForNode8streamToERNS_12SourceStreamE
-__ZNK3KJS9CommaNode8streamToERNS_12SourceStreamE
-__ZNK3KJS17AssignResolveNode10precedenceEv
-__ZNK3KJS23FunctionCallResolveNode10precedenceEv
-__ZNK3KJS12FuncExprNode10precedenceEv
-__ZNK3KJS12FuncExprNode8streamToERNS_12SourceStreamE
-__ZNK3KJS13ParameterNode8streamToERNS_12SourceStreamE
-__ZNK3KJS9ForInNode8streamToERNS_12SourceStreamE
-__ZNK3KJS10ReturnNode8streamToERNS_12SourceStreamE
-__ZNK3KJS13GreaterEqNode10precedenceEv
-__ZNK3KJS13GreaterEqNode8streamToERNS_12SourceStreamE
-__ZNK3KJS8TrueNode10precedenceEv
-__ZNK3KJS8TrueNode8streamToERNS_12SourceStreamE
-__ZNK3KJS21FunctionCallValueNode8streamToERNS_12SourceStreamE
-__ZN3KJS11ElementNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS8MultNode10precedenceEv
-__ZNK3KJS8MultNode8streamToERNS_12SourceStreamE
-__ZN3KJS21functionProtoFuncCallEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS4List8getSliceEiRS0_
-__ZN3KJS10IfElseNode7executeEPNS_9ExecStateE
-__ZN3KJS6InNode17evaluateToBooleanEPNS_9ExecStateE
-__ZNK3KJS12NotEqualNode10precedenceEv
-__ZNK3KJS12NotEqualNode8streamToERNS_12SourceStreamE
-__ZN3KJS17AssignResolveNode8evaluateEPNS_9ExecStateE
-__ZN3KJS13DeleteDotNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS12ContinueNode7executeEPNS_9ExecStateE
-__ZN3KJS13DeleteDotNode8evaluateEPNS_9ExecStateE
-__ZN3KJS11FunctionImp14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZNK3KJS11PropertyMap3getERKNS_10IdentifierERj
-__ZN3KJS11GreaterNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS13PrefixDotNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS13PreIncDotNode8evaluateEPNS_9ExecStateE
-__ZN3KJS14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
-__ZNK3KJS8JSObject8toStringEPNS_9ExecStateE
-__ZNK3KJS8JSObject11toPrimitiveEPNS_9ExecStateENS_6JSTypeE
-__ZNK3KJS8JSObject12defaultValueEPNS_9ExecStateENS_6JSTypeE
-__ZN3KJS22arrayProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3WTF9HashTableIiiNS_17IdentityExtractorIiEENS_7IntHashIiEENS_10HashTraitsIiEES6_E3addIPN3KJS16RuntimeObjectImpESB_NS_17HashSetTranslatorILb1ESB_NS5_ISB_EES6_NS_7PtrHashISB_EEEEEESt4pairINS_17HashTableIteratorIiiS2_S4_S6_S6_EEbERKT_RKT0_
-__ZN3KJS11JSImmediate8toStringEPKNS_7JSValueE
-__ZN3KJS12NotEqualNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS21arrayProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS14ErrorObjectImp19implementsConstructEv
-__ZN3KJS14ErrorObjectImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZN3KJS9Collector7collectEv
-__ZN3KJS9Collector31markCurrentThreadConservativelyEv
-__ZN3KJS9Collector30markStackObjectsConservativelyEPvS1_
-__ZN3KJS6JSCell4markEv
-__ZN3KJS8JSObject4markEv
-__ZNK3KJS11PropertyMap4markEv
-__ZN3KJS11FunctionImp4markEv
-__ZN3KJS14JSGlobalObject4markEv
-__ZN3KJS16JSVariableObject4markEv
-__ZN3KJS13ArrayInstance4markEv
-__ZN3KJS15JSWrapperObject4markEv
-__ZN3KJS13ActivationImp4markEv
-__ZN3KJS13ActivationImp12markChildrenEv
-__ZN3KJS14NativeErrorImp4markEv
-__ZN3KJS9Arguments4markEv
-__ZN3KJS9Collector20markProtectedObjectsEv
-__ZN3KJS9Collector5sweepILNS0_8HeapTypeE0EEEmb
-__ZN3KJS11PropertyMapD1Ev
-__ZN3KJS11FunctionImpD0Ev
-__ZN3KJS9StringImpD0Ev
-__ZN3KJS9RegExpImpD0Ev
-__ZN3KJS13ArrayInstanceD0Ev
-__ZN3KJS9ArgumentsD0Ev
-__ZN3KJS9Collector5sweepILNS0_8HeapTypeE1EEEmb
-__ZN3KJS14AddStringsNode8evaluateEPNS_9ExecStateE
-__ZN3KJS17AddStringLeftNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS9StringImp11toPrimitiveEPNS_9ExecStateENS_6JSTypeE
-__ZN3KJS7AddNode8evaluateEPNS_9ExecStateE
-__ZN3KJS21stringProtoFuncCharAtEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS26stringProtoFuncToUpperCaseEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS24stringProtoFuncSubstringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS26stringProtoFuncToLowerCaseEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS7UString8toUInt32EPb
-__ZN3KJS22ReadModifyLocalVarNode8evaluateEPNS_9ExecStateE
-__ZN3KJS19PostIncLocalVarNode8evaluateEPNS_9ExecStateE
-__ZN3KJS17PreDecResolveNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS18PreDecLocalVarNode8evaluateEPNS_9ExecStateE
-__ZN3KJS8MultNode16evaluateToNumberEPNS_9ExecStateE
-__ZNK3KJS9NumberImp4typeEv
-__ZN3KJS20dateProtoFuncSetTimeEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS7SubNode16evaluateToNumberEPNS_9ExecStateE
-__ZNK3KJS9StringImp8toNumberEPNS_9ExecStateE
-__ZN3KJS18globalFuncParseIntEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS7JSValue15toInt32SlowCaseEPNS_9ExecStateERb
-__ZN3KJS24dateProtoFuncToGMTStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS10formatTimeERKNS_17GregorianDateTimeEb
-__ZNK3KJS15RegExpObjectImp19implementsConstructEv
-__ZN3KJS15RegExpObjectImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZN3KJS19regExpProtoFuncExecEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS14StringInstance18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3KJS35stringInstanceNumericPropertyGetterEPNS_9ExecStateEPNS_8JSObjectEjRKNS_12PropertySlotE
-__ZN3KJS23FunctionCallResolveNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS15globalFuncIsNaNEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS20dateProtoFuncSetYearEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS21gregorianDateTimeToMSERKNS_17GregorianDateTimeEdb
-__ZN3KJS15dateToDayInYearEiii
-__ZN3KJS21ReadModifyBracketNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZNK3KJS15ObjectObjectImp19implementsConstructEv
-__ZN3KJS21ReadModifyBracketNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS9ExecState12hadExceptionEv
-__ZNK3KJS7JSValue8toObjectEPNS_9ExecStateE
-__ZNK3KJS7JSValue8toStringEPNS_9ExecStateE
-__ZN3KJS7UStringD1Ev
-__ZN3KJS8JSObject15getPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZNK3KJS12PropertySlot8getValueEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierE
-__ZNK3WTF6RefPtrIN3KJS14ExpressionNodeEE3getEv
-__ZN3KJS3addEPNS_9ExecStateEPNS_7JSValueES3_
-__ZN3KJS10IdentifierD1Ev
-__ZNK3KJS8JSObject3getEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3KJS20arrayProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS14ExpressionNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS9BreakNode7executeEPNS_9ExecStateE
-__ZN3KJS18arrayProtoFuncJoinEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS11JSImmediate8toObjectEPKNS_7JSValueEPNS_9ExecStateE
-__ZN3KJS10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
-__ZN3KJS5Error6createEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringEiiS6_
-__ZN3KJS14NativeErrorImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZNK3KJS6JSCell17getTruncatedInt32ERi
-__ZN3KJS15StringObjectImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS9Collector15recordExtraCostEm
-__ZN3KJS22objectProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS8JSObject9classNameEv
-__ZN3KJS14PostDecDotNode8evaluateEPNS_9ExecStateE
-__ZN3KJS9CommaNodeD1Ev
-__ZN3KJS28globalFuncDecodeURIComponentEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS6decodeEPNS_9ExecStateERKNS_4ListEPKcb
-__ZN3KJS19BracketAccessorNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS15TypeOfValueNodeD1Ev
-__ZN3KJS17PrototypeFunctionD0Ev
-__ZN3KJS13ErrorInstanceD0Ev
-__ZN3KJS18mathProtoFuncRoundEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS23FunctionCallResolveNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS13GreaterEqNodeD1Ev
-__ZN3KJS7ModNodeD1Ev
-__ZN3KJS24LocalVarFunctionCallNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS4List15expandAndAppendEPNS_7JSValueE
-__ZN3WTF6VectorIPN3KJS7JSValueELm8EE15reserveCapacityEm
-__ZN3KJS10SwitchNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS13CaseBlockNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS14ClauseListNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS14CaseClauseNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS10SwitchNode7executeEPNS_9ExecStateE
-__ZN3KJS13CaseBlockNode12executeBlockEPNS_9ExecStateEPNS_7JSValueE
-__ZN3KJS18NotStrictEqualNode17evaluateToBooleanEPNS_9ExecStateE
-__Z23_NPN_CreateScriptObjectP4_NPPPN3KJS8JSObjectEN3WTF10PassRefPtrINS1_8Bindings10RootObjectEEE
-__NPN_CreateObject
-__Z10jsAllocateP4_NPPP7NPClass
-__NPN_RetainObject
-__NPN_Evaluate
-__ZNK3KJS8Bindings10RootObject12globalObjectEv
-__ZN3KJS8Bindings22convertNPStringToUTF16EPK9_NPStringPPtPj
-__ZN3KJS8Bindings36convertUTF8ToUTF16WithLatin1FallbackEPKciPPtPj
-__ZN3WTF7Unicode18convertUTF8ToUTF16EPPKcS2_PPtS4_b
-__ZN3KJS11Interpreter8evaluateEPNS_9ExecStateERKNS_7UStringEiS5_PNS_7JSValueE
-__ZN3KJS8Bindings23convertValueToNPVariantEPNS_9ExecStateEPNS_7JSValueEP10_NPVariant
-__ZN3KJS11JSImmediate4typeEPKNS_7JSValueE
-__NPN_GetStringIdentifier
-__ZN3KJS8Bindings26identifierFromNPIdentifierEPKc
-__NPN_Invoke
-__ZN3KJS8Bindings14findRootObjectEPNS_14JSGlobalObjectE
-__NPN_ReleaseVariantValue
-__ZNK3KJS7UString10UTF8StringEb
+__ZN3WTF14FastMallocZone9forceLockEP14_malloc_zone_t
+__ZN3WTF14FastMallocZone11forceUnlockEP14_malloc_zone_t
+__ZN3JSC7UStringC1EPKti
+__ZN3JSC5Lexer7record8Ei
+__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeE
+__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncDeclNodeEEELm0EE15reserveCapacityEm
+__ZN3JSC10Identifier6removeEPNS_7UString3RepE
+__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncDeclNodeEEELm0EEaSERKS5_
+__ZN3JSC8JSObject12removeDirectERKNS_10IdentifierE
+__ZN3JSC9Structure31removePropertyWithoutTransitionERKNS_10IdentifierE
+__ZN3JSC9Structure6removeERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator15emitNewFunctionEPNS_10RegisterIDEPNS_12FuncDeclNodeE
+__ZN3JSC9CodeBlock25createRareDataIfNecessaryEv
+__ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14shrinkCapacityEm
+__ZN3JSC3JIT11emitCTICallEPFvPvzE
+__ZN3JSC11Interpreter15cti_op_new_funcEPvz
+__ZN3JSC12FuncDeclNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
+__ZN3JSC11Interpreter10cti_op_endEPvz
+__ZN3JSC12FuncDeclNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC12NodeReleaser21adoptFunctionBodyNodeERN3WTF6RefPtrINS_16FunctionBodyNodeEEE
+__ZN3JSC8JSObject4markEv
+__ZN3JSC14JSGlobalObject4markEv
+__ZN3JSC7JSArray4markEv
+__ZN3JSC15JSWrapperObject4markEv
+__ZN3JSC18GlobalEvalFunction4markEv
+__ZNK3JSC10NumberNode8isNumberEv
+__ZN3JSC5Lexer10scanRegExpEv
+__ZN3JSC7UStringC2ERKN3WTF6VectorItLm0EEE
+__ZL26appendToVarDeclarationListPvRPN3JSC20ParserRefCountedDataIN3WTF6VectorISt4pairINS0_10IdentifierEjELm0EEEEERKS5_j
+__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EE14expandCapacityEmPKS4_
+__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EE15reserveCapacityEm
+__ZL20makeVarStatementNodePvPN3JSC14ExpressionNodeE
+__ZL14makeAssignNodePvPN3JSC14ExpressionNodeENS0_8OperatorES2_bbiii
+__Z21mergeDeclarationListsIPN3JSC20ParserRefCountedDataIN3WTF6VectorINS2_6RefPtrINS0_12FuncDeclNodeEEELm0EEEEEET_SA_SA_
+__ZN3JSC20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEED1Ev
+__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE14expandCapacityEm
+__ZNK3JSC18EmptyStatementNode16isEmptyStatementEv
+__ZNK3JSC14ExpressionNode10isLocationEv
+__ZL11makeAddNodePvPN3JSC14ExpressionNodeES2_b
+__ZNK3JSC14ExpressionNode8isNumberEv
+__ZN3JSC16PropertyListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11emitPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3JSC11UnaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13LogicalOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8newLabelEv
+__ZN3JSC17BytecodeGenerator15emitJumpIfFalseEPNS_10RegisterIDEPNS_5LabelE
+__ZNK3JSC14LogicalNotNode8opcodeIDEv
+__ZN3JSC17BytecodeGenerator9emitLabelEPNS_5LabelE
+__ZN3WTF6VectorIjLm0EE15reserveCapacityEm
+__ZN3JSC19ReverseBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC10NumberNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC17BytecodeGenerator11emitResolveEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3WTF6VectorIN3JSC17GlobalResolveInfoELm0EE14expandCapacityEm
+__ZNK3JSC11GreaterNode8opcodeIDEv
+__ZN3JSC17BytecodeGenerator12emitBinaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_NS_12OperandTypesE
+__ZN3JSC9EqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC14ExpressionNode6isNullEv
+__ZN3JSC17BytecodeGenerator14emitEqualityOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_
+__ZN3JSC10RegExpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
+__ZN3JSC4WREC9Generator13compileRegExpEPNS_12JSGlobalDataERKNS_7UStringEPjPPKcRN3WTF6RefPtrINS_14ExecutablePoolEEEbb
+__ZN3JSC4WREC9Generator13generateEnterEv
+__ZN3JSC4WREC9Generator17generateSaveIndexEv
+__ZN3JSC4WREC6Parser16parseDisjunctionERNS_14MacroAssembler8JumpListE
+__ZN3JSC4WREC6Parser16parseAlternativeERNS_14MacroAssembler8JumpListE
+__ZN3JSC4WREC9Generator32generatePatternCharacterSequenceERNS_14MacroAssembler8JumpListEPim
+__ZN3JSC4WREC9Generator28generatePatternCharacterPairERNS_14MacroAssembler8JumpListEii
+__ZN3WTF6VectorIN3JSC14MacroAssembler4JumpELm16EE6appendIS3_EEvRKT_
+__ZN3JSC12X86Assembler7cmpl_irEiNS_3X8610RegisterIDE
+__ZN3JSC4WREC9Generator24generatePatternCharacterERNS_14MacroAssembler8JumpListEi
+__ZN3JSC4WREC9Generator21generateLoadCharacterERNS_14MacroAssembler8JumpListE
+__ZN3JSC4WREC14CharacterClass7newlineEv
+__ZN3JSC4WREC6Parser29parseCharacterClassQuantifierERNS_14MacroAssembler8JumpListERKNS0_14CharacterClassEb
+__ZN3JSC4WREC6Parser17consumeQuantifierEv
+__ZN3JSC4WREC9Generator24generateGreedyQuantifierERNS_14MacroAssembler8JumpListERNS0_19GenerateAtomFunctorEjj
+__ZN3JSC4WREC29GenerateCharacterClassFunctor12generateAtomEPNS0_9GeneratorERNS_14MacroAssembler8JumpListE
+__ZN3JSC4WREC9Generator22generateCharacterClassERNS_14MacroAssembler8JumpListERKNS0_14CharacterClassEb
+__ZN3JSC4WREC9Generator30generateCharacterClassInvertedERNS_14MacroAssembler8JumpListERKNS0_14CharacterClassE
+__ZN3JSC4WREC29GenerateCharacterClassFunctor9backtrackEPNS0_9GeneratorE
+__ZN3JSC4WREC9Generator18generateBacktrack1Ev
+__ZN3JSC15AssemblerBuffer4growEv
+__ZN3JSC12X86Assembler7addl_irEiNS_3X8610RegisterIDE
+__ZN3JSC4WREC9Generator21generateReturnSuccessEv
+__ZN3JSC4WREC9Generator22generateIncrementIndexEPNS_14MacroAssembler4JumpE
+__ZN3JSC4WREC9Generator27generateJumpIfNotEndOfInputENS_14MacroAssembler5LabelE
+__ZN3JSC4WREC9Generator21generateReturnFailureEv
+__ZN3JSC17BytecodeGenerator13emitNewRegExpEPNS_10RegisterIDEPNS_6RegExpE
+__ZN3JSC12BinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC18NotStrictEqualNode8opcodeIDEv
+__ZNK3JSC14ExpressionNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC4WREC9Generator20generateAssertionBOLERNS_14MacroAssembler8JumpListE
+__ZN3JSC4WREC6Parser13consumeEscapeEb
+__ZN3WTF6VectorIiLm8EE14expandCapacityEm
+__ZN3JSC4WREC6Parser16parseParenthesesERNS_14MacroAssembler8JumpListE
+__Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
+__ZL30calculateCompiledPatternLengthPKti24JSRegExpIgnoreCaseOptionR11CompileDataR9ErrorCode
+__ZL11checkEscapePPKtS0_P9ErrorCodeib
+__ZL13compileBranchiPiPPhPPKtS3_P9ErrorCodeS_S_R11CompileData
+__ZN3JSC4WREC14CharacterClass6spacesEv
+__ZN3JSC4WREC6Parser23parseNonCharacterEscapeERNS_14MacroAssembler8JumpListERKNS0_6EscapeE
+__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDE
+__ZN3JSC4WREC9Generator35generateCharacterClassInvertedRangeERNS_14MacroAssembler8JumpListES4_PKNS0_14CharacterRangeEjPjPKtj
+__ZN3JSC4WREC9Generator20terminateAlternativeERNS_14MacroAssembler8JumpListES4_
+__ZN3JSC4WREC6Parser19parseCharacterClassERNS_14MacroAssembler8JumpListE
+__ZN3JSC4WREC14CharacterClass8wordcharEv
+__ZN3JSC4WREC25CharacterClassConstructor6appendERKNS0_14CharacterClassE
+__ZN3JSC4WREC25CharacterClassConstructor5flushEv
+__ZN3JSC4WREC25CharacterClassConstructor9addSortedERN3WTF6VectorItLm0EEEt
+__ZN3WTF6VectorItLm0EE14expandCapacityEm
+__ZN3JSC4WREC25CharacterClassConstructor14addSortedRangeERN3WTF6VectorINS0_14CharacterRangeELm0EEEtt
+__ZN3WTF6VectorIN3JSC4WREC14CharacterRangeELm0EE14expandCapacityEm
+__ZN3JSC4WREC25CharacterClassConstructor3putEt
+__ZN3JSC4WREC9Generator20terminateDisjunctionERNS_14MacroAssembler8JumpListE
+__ZN3JSC11NewExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13emitConstructEPNS_10RegisterIDES2_PNS_13ArgumentsNodeEjjj
+__ZN3WTF6VectorIN3JSC20GetByIdExceptionInfoELm0EE14expandCapacityEm
+__ZN3JSC16VarStatementNodeD1Ev
+__ZN3JSC16VarStatementNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC17AssignResolveNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC17ObjectLiteralNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC16PropertyListNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC12PropertyNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11UnaryOpNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC13LogicalOpNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC12BinaryOpNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC17AssignResolveNodeD1Ev
+__ZN3JSC17ObjectLiteralNodeD1Ev
+__ZN3JSC16PropertyListNodeD1Ev
+__ZN3JSC12PropertyNodeD1Ev
+__ZN3JSC14LogicalNotNodeD1Ev
+__ZN3JSC10RegExpNodeD1Ev
+__ZN3JSC13LogicalOpNodeD1Ev
+__ZN3JSC9EqualNodeD1Ev
+__ZN3JSC18NotStrictEqualNodeD1Ev
+__ZN3JSC6IfNodeD1Ev
+__ZN3JSC6IfNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC13AssignDotNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC8WithNodeD1Ev
+__ZN3JSC8WithNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC21FunctionCallValueNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC21FunctionCallValueNodeD1Ev
+__ZN3JSC9ArrayNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC9ArrayNodeD1Ev
+__ZN3JSC11ElementNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC10IfElseNodeD1Ev
+__ZN3JSC10IfElseNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC7AddNodeD1Ev
+__ZN3JSC11NewExprNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11NewExprNodeD1Ev
+__ZN3JSC3JIT21compilePutByIdHotPathEiPNS_10IdentifierEij
+__ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE6appendIS2_EEvRKT_
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDES4_ii
+__ZN3JSC3JIT11emitCTICallEPFPNS_23JSValueEncodedAsPointerEPvzE
+__ZN3JSC3JIT17compileOpStrictEqEPNS_11InstructionENS0_21CompileOpStrictEqTypeE
+__ZN3JSC3JIT23compileFastArith_op_addEPNS_11InstructionE
+__ZN3JSC3JIT22compilePutByIdSlowCaseEiPNS_10IdentifierEiRPNS_13SlowCaseEntryEj
+__ZN3JSC3JIT27compileOpConstructSetupArgsEPNS_11InstructionE
+__ZN3JSC3JIT11emitCTICallEPFPNS_8JSObjectEPvzE
+__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
+__ZN3JSC11Interpreter17cti_op_new_objectEPvz
+__ZN3JSC20constructEmptyObjectEPNS_9ExecStateE
+__ZN3JSC11Interpreter16cti_op_put_by_idEPvz
+__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC11Interpreter12cti_op_jtrueEPvz
+__ZN3JSC11Interpreter10cti_op_notEPvz
+__ZN3WTF7HashMapISt4pairINS_6RefPtrIN3JSC7UString3RepEEEjEPNS3_9StructureENS3_28StructureTransitionTableHashENS3_34StructureTransitionTableHashTraitsENS_10HashTraitsIS9_EEE3addERKS7_RKS9_
+__ZN3WTF9HashTableISt4pairINS_6RefPtrIN3JSC7UString3RepEEEjES1_IS7_PNS3_9StructureEENS_18PairFirstExtractorISA_EENS3_28StructureTransitionTableHashENS_14PairHashTraitsINS3_34StructureTransitionTableHashTraitsENS_10HashTraitsIS9_EEEESF_E6rehashEi
+__ZN3JSC11Interpreter21cti_op_resolve_globalEPvz
+__ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC15StringPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL22stringProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC8JSString12toThisStringEPNS_9ExecStateE
+__ZNK3JSC10JSValuePtr9toIntegerEPNS_9ExecStateE
+__ZN3JSC11JSImmediate12nonInlineNaNEv
+__ZNK3JSC7UString4findERKS0_i
+__ZN3JSC11Interpreter11cti_op_lessEPvz
+__ZN3JSC11Interpreter17cti_op_new_regexpEPvz
+__ZN3JSC12RegExpObjectC1EN3WTF10PassRefPtrINS_9StructureEEENS2_INS_6RegExpEEE
+__ZN3JSCL20stringProtoFuncMatchEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC6JSCell8isObjectEPKNS_9ClassInfoE
+__ZNK3JSC12RegExpObject9classInfoEv
+__ZN3JSC17RegExpConstructor12performMatchEPNS_6RegExpERKNS_7UStringEiRiS6_PPi
+__ZN3JSC6RegExp5matchERKNS_7UStringEiPN3WTF11OwnArrayPtrIiEE
+__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
+__ZNK3JSC7UString8toUInt32EPbb
+__ZNK3JSC7UString8toDoubleEbb
+__ZN3WTF6VectorIcLm32EE6resizeEm
+__ZN3JSC11Interpreter16cti_op_nstricteqEPvz
+__ZN3JSC10JSValuePtr19strictEqualSlowCaseES0_S0_
+__ZN3JSC11Interpreter19cti_op_new_func_expEPvz
+__ZN3JSC12FuncExprNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
+__ZNK3JSC19BracketAccessorNode10isLocationEv
+__ZNK3JSC19BracketAccessorNode21isBracketAccessorNodeEv
+__ZN3JSC9ForInNodeC2EPNS_12JSGlobalDataERKNS_10IdentifierEPNS_14ExpressionNodeES7_PNS_13StatementNodeEiii
+__ZN3JSC19BracketAccessorNodeD1Ev
+__ZN3JSC19BracketAccessorNode12releaseNodesERNS_12NodeReleaserE
+__ZNK3JSC9ForInNode6isLoopEv
+__ZN3JSC9ForInNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC20EvalFunctionCallNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator19emitResolveWithBaseEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZN3JSC20EvalFunctionCallNodeD1Ev
+__ZN3JSC20EvalFunctionCallNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC3JIT26compileOpCallEvalSetupArgsEPNS_11InstructionE
+__ZN3JSC11Interpreter24cti_op_resolve_with_baseEPvz
+__ZN3JSC11Interpreter16cti_op_call_evalEPvz
+__ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12RegisterFileEPNS_8RegisterEiiRNS_10JSValuePtrE
+__ZNK3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS1_INS2_8EvalNodeEEENS_7StrHashIS5_EENS_10HashTraitsIS5_EENSA_IS7_EEE3getEPS4_
+__ZN3JSC7UString3Rep11computeHashEPKti
+__ZN3JSC6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPiPNS_7UStringE
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS1_INS2_8EvalNodeEEEENS_18PairFirstExtractorIS9_EENS_7StrHashIS5_EENS_14PairHashTraitsINS_10HashTraitsIS5_EENSF_IS8_EEEESG_E6rehashEi
+__ZN3JSC9ExecState9thisValueEv
+__ZN3JSC11Interpreter7executeEPNS_8EvalNodeEPNS_9ExecStateEPNS_8JSObjectEiPNS_14ScopeChainNodeEPNS_10JSValuePtrE
+__ZN3JSC8EvalNode16generateBytecodeEPNS_14ScopeChainNodeE
+__ZN3JSC17BytecodeGeneratorC2EPNS_8EvalNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISE_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE
+__ZN3JSC8EvalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC18globalFuncParseIntEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncToGMTStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC10formatTimeERKNS_17GregorianDateTimeEb
+__ZN3JSC9BreakNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11breakTargetERKNS_10IdentifierE
+__ZN3JSC9BreakNodeD1Ev
+__ZN3JSC8JSString18getPrimitiveNumberEPNS_9ExecStateERdRNS_10JSValuePtrE
+__ZNK3JSC8JSString8toNumberEPNS_9ExecStateE
+__ZL18makeRightShiftNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC4WREC14CharacterClass6digitsEv
+__ZNK3JSC14RightShiftNode8opcodeIDEv
+__ZN3JSC14RightShiftNodeD1Ev
+__ZN3JSC3JIT26compileFastArith_op_rshiftEjjj
+__ZN3JSC3JIT30compileFastArithSlow_op_rshiftEjjjRPNS_13SlowCaseEntryE
+__ZN3JSCL20dateProtoFuncSetYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC21gregorianDateTimeToMSERKNS_17GregorianDateTimeEdb
+__ZN3JSCL15dateToDayInYearEiii
+__ZN3JSC8EvalNode4markEv
+__ZN3JSC19JSStaticScopeObjectD0Ev
+__ZN3JSC18PostfixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC18PostfixBracketNodeD1Ev
+__ZN3JSC18PostfixBracketNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC9ForInNodeC2EPNS_12JSGlobalDataEPNS_14ExpressionNodeES4_PNS_13StatementNodeE
+__ZN3JSC21ReadModifyBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC21ReadModifyBracketNodeD1Ev
+__ZN3JSC21ReadModifyBracketNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSCL20arrayProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC17RegExpConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC15constructRegExpEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC8JSObject9classNameEv
+__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL20stringProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC8NullNode6isNullEv
+__ZN3JSC17StringConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callStringConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC12StringObject8toStringEPNS_9ExecStateE
+__ZN3JSCL23stringProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter28cti_op_get_by_id_string_failEPvz
+__ZN3JSCL19regExpProtoFuncExecEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter16cti_op_is_numberEPvz
+__ZNK3JSC12StringObject9classInfoEv
+__ZN3JSC11Interpreter16cti_op_is_objectEPvz
+__ZN3JSC3JIT30privateCompileGetByIdChainListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureEPNS_14StructureChainEmmPNS_9ExecStateE
+__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC10Identifier5equalEPKNS_7UString3RepEPKc
+__ZNK3JSC6JSCell17getTruncatedInt32ERi
+__ZN3JSC15toInt32SlowCaseEdRb
+__ZNK3JSC12JSNumberCell9toBooleanEPNS_9ExecStateE
+__ZN3JSC9Structure24removePropertyTransitionEPS0_RKNS_10IdentifierERm
+__ZN3JSC11Interpreter10cti_op_subEPvz
+__ZN3JSC28globalFuncEncodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL6encodeEPNS_9ExecStateERKNS_7ArgListEPKc
+__ZNK3JSC7UString10UTF8StringEb
__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
-__Z35NPN_InitializeVariantWithStringCopyP10_NPVariantPK9_NPString
-__ZN3KJS7CStringD1Ev
-__NPN_ReleaseObject
-__Z12jsDeallocateP8NPObject
-__ZN3KJS8Bindings10RootObject11gcUnprotectEPNS_8JSObjectE
-_pow5mult
-_quorem
-_diff
-__ZN3WTF6VectorIPN3KJS12FuncDeclNodeELm16EE14expandCapacityEmPKS3_
-__ZN3WTF6VectorIPN3KJS12FuncDeclNodeELm16EE14expandCapacityEm
-__ZN3WTF6VectorIPN3KJS12FuncDeclNodeELm16EE15reserveCapacityEm
-__ZN3KJS10NumberNode8setValueEd
-__ZN3KJS11ResolveNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS21dateProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS24dateProtoFuncGetFullYearEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS12NotEqualNode8evaluateEPNS_9ExecStateE
-__ZN3KJS14InstanceOfNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS17PreIncResolveNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS9NumberImp9toBooleanEPNS_9ExecStateE
-__ZN3KJS10LessEqNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS29objectProtoFuncHasOwnPropertyEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS10LessEqNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS13UnaryPlusNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS17DeleteBracketNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS17DeleteBracketNode8evaluateEPNS_9ExecStateE
-__ZN3KJS20arrayProtoFuncSpliceEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS17staticValueGetterINS_13MathObjectImpEEEPNS_7JSValueEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZNK3KJS13MathObjectImp16getValuePropertyEPNS_9ExecStateEi
-__NPN_DeallocateObject
-__ZN3KJS14PostIncDotNodeD1Ev
-__ZN3KJS22ReadModifyLocalVarNodeD1Ev
-__ZN3KJS10LessEqNodeD1Ev
-__ZN3KJS18PostDecResolveNodeD1Ev
-__ZN3KJS17DeleteBracketNodeD1Ev
-__ZN3KJS18PostIncResolveNodeD1Ev
-__ZN3KJS14InstanceOfNodeD1Ev
-__ZN3KJS10NegateNodeD1Ev
-__ZN3KJS17PreDecResolveNodeD1Ev
-__ZN3KJS21ReadModifyBracketNodeD1Ev
-__ZN3KJS10BitAndNodeD1Ev
-__ZN3KJS9BitOrNodeD1Ev
-__ZN3KJS14RightShiftNodeD1Ev
-__ZN3KJS13LeftShiftNodeD1Ev
-__ZN3KJS13UnaryPlusNodeD1Ev
-__ZN3KJS13MathObjectImpD0Ev
-__ZN3KJS14NativeErrorImpD0Ev
-__ZN3KJS14ErrorObjectImpD0Ev
-__ZN3KJS15RegExpObjectImpD0Ev
-__ZN3KJS17DateObjectFuncImpD0Ev
-__ZN3KJS13DateObjectImpD0Ev
-__ZN3KJS15NumberObjectImpD0Ev
-__ZN3KJS16BooleanObjectImpD0Ev
-__ZN3KJS19StringObjectFuncImpD0Ev
-__ZN3KJS15StringObjectImpD0Ev
-__ZN3KJS14ArrayObjectImpD0Ev
-__ZN3KJS17FunctionObjectImpD0Ev
-__ZN3KJS15ObjectObjectImpD0Ev
-__ZN3KJS20NativeErrorPrototypeD0Ev
-__ZN3KJS15RegExpPrototypeD0Ev
-__ZN3KJS15NumberPrototypeD0Ev
-__ZN3KJS16BooleanPrototypeD0Ev
-__ZN3KJS15StringPrototypeD0Ev
-__ZN3KJS15ObjectPrototypeD0Ev
-__ZN3KJS17FunctionPrototypeD0Ev
-__ZN3KJS13PreIncDotNodeD1Ev
-__ZN3KJS17staticValueGetterINS_15RegExpObjectImpEEEPNS_7JSValueEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZNK3KJS15RegExpObjectImp16getValuePropertyEPNS_9ExecStateEi
-__ZNK3KJS15RegExpObjectImp10getBackrefEj
-__ZN3KJS16mathProtoFuncMaxEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS17staticValueGetterINS_15NumberObjectImpEEEPNS_7JSValueEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZNK3KJS15NumberObjectImp16getValuePropertyEPNS_9ExecStateEi
-__ZN3KJS10NegateNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS10NegateNode8evaluateEPNS_9ExecStateE
-__ZN3KJS25stringProtoFuncCharCodeAtEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS21arrayProtoFuncUnShiftEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS10LessEqNode8evaluateEPNS_9ExecStateE
-__ZN3KJS8JSObject15getPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZNK3KJS12PropertySlot8getValueEPNS_9ExecStateEPNS_8JSObjectEj
-__ZN3KJS16mathProtoFuncMinEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS10Identifier5equalEPKNS_7UString3RepEPKc
-__ZN3KJS11addSlowCaseEPNS_9ExecStateEPNS_7JSValueES3_
-__ZN3KJS8LessNode8evaluateEPNS_9ExecStateE
-__ZN3KJS7DivNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS10NegateNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS7AddNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS16mathProtoFuncSinEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS16mathProtoFuncLogEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS16mathProtoFuncAbsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3WTF6VectorIPN3KJS9ExecStateELm16EE14expandCapacityEm
-__ZN3WTF6VectorIPN3KJS9ExecStateELm16EE15reserveCapacityEm
-__ZN3KJS17arrayProtoFuncPopEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS21stringProtoFuncSubstrEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS28globalFuncEncodeURIComponentEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS6encodeEPNS_9ExecStateERKNS_4ListEPKc
-__ZN3KJS17PrefixBracketNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS17PreIncBracketNode8evaluateEPNS_9ExecStateE
-__ZN3KJS16mathProtoFuncExpEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS17mathProtoFuncATanEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS17mathProtoFuncCeilEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS14AddNumbersNode8evaluateEPNS_9ExecStateE
-__ZN3KJS18arrayProtoFuncSortEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS13ArrayInstance4sortEPNS_9ExecStateEPNS_8JSObjectE
-__ZN3KJS13ArrayInstance17compactForSortingEv
-__ZN3KJS34compareWithCompareFunctionForQSortEPKvS1_
-__ZN3KJS13ArrayInstance4sortEPNS_9ExecStateE
-__ZN3KJS16mathProtoFuncPowEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS15NumberObjectImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZN3KJS23numberProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS9NumberImp8toObjectEPNS_9ExecStateE
-__ZN3KJS16mathProtoFuncCosEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS17mathProtoFuncSqrtEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS17mathProtoFuncASinEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS14ExpressionNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS11DoWhileNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS21stringProtoFuncSearchEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS13PreDecDotNode8evaluateEPNS_9ExecStateE
-__ZN3KJS18PostfixBracketNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS18PostIncBracketNode8evaluateEPNS_9ExecStateE
-__ZN3KJS13LeftShiftNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
+__ZN3JSC17PrefixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC10NegateNode8opcodeIDEv
+__ZN3JSC10NegateNodeD1Ev
+__ZN3JSC11Interpreter13cti_op_negateEPvz
+__ZN3JSCL17mathProtoFuncSqrtEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11JSImmediate12toThisObjectENS_10JSValuePtrEPNS_9ExecStateE
+__ZN3JSCL16mathProtoFuncAbsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL18mathProtoFuncRoundEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncCosEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncSinEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter12cti_op_jlessEPvz
+__ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE
+__ZN3JSC16ArrayConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL20callArrayConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC12JSNumberCell18getPrimitiveNumberEPNS_9ExecStateERdRNS_10JSValuePtrE
+__ZN3JSC11Interpreter10cti_op_modEPvz
+__ZL17makeLeftShiftNodePvPN3JSC14ExpressionNodeES2_b
+__ZNK3JSC13LeftShiftNode8opcodeIDEv
+__ZN3JSC13LeftShiftNodeD1Ev
+__ZN3JSC3JIT26compileFastArith_op_lshiftEjjj
+__ZN3JSC3JIT30compileFastArithSlow_op_lshiftEjjjRPNS_13SlowCaseEntryE
+__ZN3JSCL16mathProtoFuncMaxEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC10BitAndNode8opcodeIDEv
+__ZN3JSC10BitAndNodeD1Ev
+__ZN3JSC3JIT26compileFastArith_op_bitandEjjj
+__ZN3JSC3JIT30compileFastArithSlow_op_bitandEjjjRPNS_13SlowCaseEntryE
+__ZN3JSC11Interpreter13cti_op_bitandEPvz
+__ZNK3JSC14BitwiseNotNode8opcodeIDEv
+__ZN3JSC14BitwiseNotNodeD1Ev
+__ZN3JSC11Interpreter13cti_op_lshiftEPvz
+__ZN3JSC11Interpreter13cti_op_bitnotEPvz
+__ZNK3JSC22UnsignedRightShiftNode8opcodeIDEv
+__ZNK3JSC10BitXOrNode8opcodeIDEv
+__ZN3JSC22UnsignedRightShiftNodeD1Ev
+__ZN3JSC10BitXOrNodeD1Ev
+__ZN3JSCL25stringProtoFuncCharCodeAtEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter14cti_op_urshiftEPvz
+__ZNK3JSC12JSNumberCell18getTruncatedUInt32ERj
+__ZN3JSC16toUInt32SlowCaseEdRb
+__ZN3JSCL17mathProtoFuncCeilEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC6JSCell18getTruncatedUInt32ERj
+__ZN3JSC11Interpreter12cti_op_bitorEPvz
+__ZNK3JSC12JSNumberCell17getTruncatedInt32ERi
+__ZNK3JSC9BitOrNode8opcodeIDEv
+__ZN3JSC9BitOrNodeD1Ev
+__ZN3JSC11Interpreter13cti_op_rshiftEPvz
+__ZN3JSC11Interpreter13cti_op_bitxorEPvz
+__ZN3JSC9parseDateERKNS_7UStringE
+__ZNK3JSC12JSActivation12toThisObjectEPNS_9ExecStateE
+__ZN3JSC11Interpreter19cti_op_resolve_skipEPvz
+__ZN3JSCL24dateProtoFuncGetFullYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC17StringConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithStringConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC5equalEPKNS_7UString3RepES3_
+__ZN3JSC10SwitchNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13CaseBlockNode20emitBytecodeForBlockERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_
+__ZN3JSC13CaseBlockNode18tryOptimizedSwitchERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERiS7_
+__ZN3JSCL17processClauseListEPNS_14ClauseListNodeERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERNS_10SwitchKindERbRiSB_
+__ZNK3JSC10StringNode8isStringEv
+__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm8EE14expandCapacityEm
+__ZN3WTF6VectorINS_6RefPtrIN3JSC5LabelEEELm8EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator11beginSwitchEPNS_10RegisterIDENS_10SwitchInfo10SwitchTypeE
+__ZN3WTF6VectorIN3JSC10SwitchInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator9endSwitchEjPN3WTF6RefPtrINS_5LabelEEEPPNS_14ExpressionNodeEPS3_ii
+__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14expandCapacityEm
+__ZN3WTF6VectorIiLm0EE15reserveCapacityEm
+__ZN3JSC10SwitchNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC13CaseBlockNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC14ClauseListNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC14CaseClauseNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC10SwitchNodeD1Ev
+__ZN3JSC13CaseBlockNodeD1Ev
+__ZN3JSC14ClauseListNodeD1Ev
+__ZN3JSC14CaseClauseNodeD1Ev
+__ZN3WTF6VectorIN3JSC12SwitchRecordELm0EE14expandCapacityEm
+__ZN3WTF6VectorIPvLm0EE15reserveCapacityEm
+__ZN3JSC11Interpreter18cti_op_switch_charEPvz
+__ZN3JSC8EvalNodeD1Ev
+__ZN3JSCL16mathProtoFuncPowEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3WTF6VectorIcLm0EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC7UString5RangeELm16EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC7UStringELm16EE14expandCapacityEm
+__ZN3WTF17TCMalloc_PageHeap3NewEm
+__ZN3JSC7JSArray16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC9ExecState10arrayTableEPS0_
+__ZN3JSCL18regExpObjectSourceEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC7ArgList10slowAppendENS_10JSValuePtrE
+__ZN3WTF7HashSetIPN3JSC7ArgListENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC7ArgListES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3WTF6VectorIN3JSC8RegisterELm8EE15reserveCapacityEm
+__ZN3JSC22JSPropertyNameIterator4markEv
+__ZN3JSCL16mathProtoFuncLogEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL29objectProtoFuncHasOwnPropertyEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL18arrayProtoFuncSortEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC7JSArray4sortEPNS_9ExecStateENS_10JSValuePtrENS_8CallTypeERKNS_8CallDataE
+__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE6insertEi
+__ZN3JSCltERKNS_7UStringES2_
+__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE7balanceEi
+__ZN3JSC4WREC9Generator29generateAssertionWordBoundaryERNS_14MacroAssembler8JumpListEb
+__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_3X8610RegisterIDES3_ii
+__ZN3JSCL21stringProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC19globalFuncEncodeURIEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC19globalFuncDecodeURIEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL6decodeEPNS_9ExecStateERKNS_7ArgListEPKcb
__ZN3WTF7Unicode18UTF8SequenceLengthEc
__ZN3WTF7Unicode18decodeUTF8SequenceEPKc
-__ZN3KJS9StringImp18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
-__ZN3KJSltERKNS_7UStringES2_
-__ZN3KJS15ConditionalNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS10BitAndNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS10BitAndNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS15DotAccessorNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS19ImmediateNumberNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS13ArrayInstance16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
-__ZN3KJS18LocalVarAccessNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS13LeftShiftNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS19BracketAccessorNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS14RightShiftNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS14RightShiftNode8evaluateEPNS_9ExecStateE
-__ZN3KJS7AddNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS19ImmediateNumberNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS13LeftShiftNode8evaluateEPNS_9ExecStateE
-__ZN3KJS18LocalVarAccessNode16evaluateToUInt32EPNS_9ExecStateE
-__ZNK3KJS9NumberImp17getTruncatedInt32ERi
-__ZN3KJS19BracketAccessorNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS16BooleanObjectImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZN3KJS24booleanProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS14BitwiseNotNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS9BitOrNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS9BitOrNode8evaluateEPNS_9ExecStateE
-__ZN3KJS10BitAndNode8evaluateEPNS_9ExecStateE
-__ZN3KJS14BitwiseNotNode8evaluateEPNS_9ExecStateE
-__ZN3KJS15NumberObjectImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS8Bindings8Instance32createBindingForLanguageInstanceENS1_15BindingLanguageEPvN3WTF10PassRefPtrINS0_10RootObjectEEE
-__ZN3KJS8Bindings9CInstanceC2EP8NPObjectN3WTF10PassRefPtrINS0_10RootObjectEEE
-__ZN3KJS8Bindings8InstanceC2EN3WTF10PassRefPtrINS0_10RootObjectEEE
-__ZNK3KJS8Bindings8Instance10rootObjectEv
-__ZN3KJS8Bindings8Instance19createRuntimeObjectEPS1_
-__ZN3KJS16RuntimeObjectImpC2EPNS_8Bindings8InstanceE
-__ZN3KJS8Bindings10RootObject16addRuntimeObjectEPNS_16RuntimeObjectImpE
-__ZN3KJS16RuntimeObjectImp18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS8Bindings9CInstance5beginEv
-__ZNK3KJS8Bindings9CInstance8getClassEv
-__ZN3KJS8Bindings6CClass11classForIsAEP7NPClass
-__ZN3KJS8Bindings6CClassC2EP7NPClass
-__ZNK3KJS8Bindings6CClass10fieldNamedERKNS_10IdentifierEPNS0_8InstanceE
-__ZNK3KJS7UString5asciiEv
-__ZNK3KJS8Bindings6CClass12methodsNamedERKNS_10IdentifierEPNS0_8InstanceE
-__NPN_UTF8FromIdentifier
-__ZN3KJS8Bindings5Class14fallbackObjectEPNS_9ExecStateEPNS0_8InstanceERKNS_10IdentifierE
-__ZN3KJS8Bindings9CInstance3endEv
-__ZN3WTF6VectorIPN3KJS8Bindings6MethodELm0EE14expandCapacityEmPKS4_
-__ZN3WTF6VectorIPN3KJS8Bindings6MethodELm0EE14expandCapacityEm
-__ZN3WTF6VectorIPN3KJS8Bindings6MethodELm0EE15reserveCapacityEm
-__ZN3KJS16RuntimeObjectImp12methodGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS13RuntimeMethodC2EPNS_9ExecStateERKNS_10IdentifierERN3WTF6VectorIPNS_8Bindings6MethodELm0EEE
-__ZN3WTF6VectorIPN3KJS8Bindings6MethodELm0EEC2ERKS5_
-__ZN3KJS13RuntimeMethod14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS16RuntimeObjectImp9classInfoEv
-__ZN3KJS8Bindings9CInstance12invokeMethodEPNS_9ExecStateERKN3WTF6VectorIPNS0_6MethodELm0EEERKNS_4ListE
-__ZNK3KJS8Bindings7CMethod4nameEv
-__ZN3KJS8Bindings23convertNPVariantToValueEPNS_9ExecStateEPK10_NPVariantPNS0_10RootObjectE
-__ZN3KJS16RuntimeObjectImpD2Ev
-__ZN3KJS8Bindings10RootObject19removeRuntimeObjectEPNS_16RuntimeObjectImpE
-__ZN3KJS4Node10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKcPNS_7JSValueEPS0_RKNS_10IdentifierE
-__ZN3KJS10substituteERNS_7UStringERKS0_
-__ZN3KJS4Node16rethrowExceptionEPNS_9ExecStateE
-__ZN3KJS4Node15handleExceptionEPNS_9ExecStateEPNS_7JSValueE
-__ZN3KJS16RuntimeObjectImp10invalidateEv
-__ZN3KJS16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3KJS14JSGlobalObjectD2Ev
-__ZN3KJS15GlobalExecStateD1Ev
-__ZN3KJS14BitwiseNotNodeD1Ev
-__ZN3KJSplERKNS_7UStringES2_
-__ZN3KJS5Lexer14convertUnicodeEiiii
-__ZN3KJS14ArrayObjectImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS9Arguments3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
-__ZN3WTF9HashTableIjSt4pairIjiENS_18PairFirstExtractorIS2_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENS8_IiEEEES9_E3addIjS2_NS_22IdentityHashTranslatorIjS2_S6_EEEES1_INS_17HashTableIteratorIjS2_S4_S6_SB_S9_EEbERKT_RKT0_
-__ZN3WTF9HashTableIjSt4pairIjiENS_18PairFirstExtractorIS2_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENS8_IiEEEES9_EC2ERKSC_
-__ZN3KJS23stringProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3WTF9HashTableIjSt4pairIjiENS_18PairFirstExtractorIS2_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENS8_IiEEEES9_E4findIjNS_22IdentityHashTranslatorIjS2_S6_EEEENS_17HashTableIteratorIjS2_S4_S6_SB_S9_EERKT_
-__ZN3KJS10BitXOrNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS10BitXOrNode8evaluateEPNS_9ExecStateE
-__ZN3KJS14RightShiftNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS10BitXOrNodeD1Ev
-__ZN3KJS17DateObjectFuncImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS9parseDateERKNS_7UStringE
-__ZN3KJS6RegExp6createERKNS_7UStringE
-__ZN3KJS7ModNode16evaluateToNumberEPNS_9ExecStateE
-__ZNK3KJS16RuntimeObjectImp14implementsCallEv
-__ZNK3KJS8Bindings9CInstance14implementsCallEv
-__ZN3KJS11Interpreter21shouldPrintExceptionsEv
-__ZN3KJS4Node10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKcRKNS_10IdentifierE
-__ZN3KJS12PropertySlot15undefinedGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKS0_
-__ZN3KJS15SavedPropertiesD1Ev
-__ZN3KJS8JSObject18isActivationObjectEv
-__ZN3KJS19globalFuncDecodeURIEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS14JSGlobalObject15restoreBuiltinsERKNS_13SavedBuiltinsE
-__ZN3KJS11PropertyMap7restoreERKNS_15SavedPropertiesE
-__ZN3KJS16JSVariableObject19restoreLocalStorageERKNS_15SavedPropertiesE
-__ZN3WTF6VectorIN3KJS17LocalStorageEntryELm32EE6resizeEm
-__ZNK3KJS23FunctionCallBracketNode8streamToERNS_12SourceStreamE
-__ZNK3KJS17TypeOfResolveNode10precedenceEv
-__ZNK3KJS17TypeOfResolveNode8streamToERNS_12SourceStreamE
-__ZNK3KJS13AssignDotNode10precedenceEv
-__ZNK3KJS12ContinueNode8streamToERNS_12SourceStreamE
-__ZN3KJS11FunctionImp12callerGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS9BreakNodeC1ERKNS_10IdentifierE
-__ZN3KJS13StatementNode9pushLabelERKNS_10IdentifierE
-__ZN3KJS9ThrowNode7executeEPNS_9ExecStateE
-__ZNK3KJS15NumberObjectImp19implementsConstructEv
-__ZN3KJS22numberProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS8VoidNodeD1Ev
-__ZN3KJS14ErrorObjectImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS18globalFuncIsFiniteEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS21ReadModifyResolveNode8evaluateEPNS_9ExecStateE
-__ZN3KJS15StrictEqualNode8evaluateEPNS_9ExecStateE
-__ZN3KJS27compareByStringPairForQSortEPKvS1_
-__ZN3KJS7compareERKNS_7UStringES2_
-__ZN3KJS4Node10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKcPNS_7JSValueEPS0_S8_
-__ZN3KJS21arrayProtoFuncReverseEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS20stringProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS15StringObjectImp19implementsConstructEv
-__ZN3KJS15StringObjectImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZN3KJS18PostDecResolveNode8evaluateEPNS_9ExecStateE
-__ZN3KJS21dateProtoFuncSetMonthEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS23setNewValueFromDateArgsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListEib
-__ZN3KJS20dateProtoFuncSetDateEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS21dateProtoFuncSetHoursEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS23setNewValueFromTimeArgsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListEib
-__ZN3KJS23dateProtoFuncSetMinutesEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS24dateProtoFuncSetFullYearEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
-__ZN3KJS20dateProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS27dateProtoFuncGetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS27dateProtoFuncSetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS24dateProtoFuncGetUTCMonthEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS24dateProtoFuncSetUTCMonthEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS23dateProtoFuncGetUTCDateEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS23dateProtoFuncSetUTCDateEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS24dateProtoFuncGetUTCHoursEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS24dateProtoFuncSetUTCHoursEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS26dateProtoFuncGetUTCMinutesEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS26dateProtoFuncSetUTCMinutesEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS26dateProtoFuncGetUTCSecondsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS26dateProtoFuncSetUTCSecondsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS22numberProtoFuncToFixedEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS18integer_part_noexpEd
-__ZN3KJS14AddNumbersNode16evaluateToNumberEPNS_9ExecStateE
-__ZNK3KJS14InstanceOfNode10precedenceEv
-__ZNK3KJS14InstanceOfNode8streamToERNS_12SourceStreamE
-__ZNK3KJS8JSObject8toNumberEPNS_9ExecStateE
-__Z15kjs_pcre_xclassiPKh
-__ZN3KJS10NumberNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS18PostDecBracketNodeD1Ev
-__ZN3KJS17PropertyNameArray3addERKNS_10IdentifierE
-__ZN3KJS22errorProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS13LeftShiftNode15evaluateToInt32EPNS_9ExecStateE
-__ZNK3KJS9RegExpImp14implementsCallEv
-__ZN3KJS22stringProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS15ConditionalNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS16JSVariableObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
-__ZN3KJS11DoWhileNode7executeEPNS_9ExecStateE
-__ZN3KJS8Bindings23convertObjcValueToValueEPNS_9ExecStateEPvNS0_13ObjcValueTypeEPNS0_10RootObjectE
-__ZN3KJS8Bindings17webUndefinedClassEv
-__ZN3KJS8Bindings20webScriptObjectClassEv
-__ZN3KJS8Bindings8Instance19createRuntimeObjectENS1_15BindingLanguageEPvN3WTF10PassRefPtrINS0_10RootObjectEEE
-__ZN3KJS8Bindings12ObjcInstanceC2EP11objc_objectN3WTF10PassRefPtrINS0_10RootObjectEEE
-__ZN3KJS8Bindings8Instance18didExecuteFunctionEv
-__ZN3KJS8Bindings12ObjcInstance5beginEv
-__ZNK3KJS8Bindings12ObjcInstance8getClassEv
-__ZN3KJS8Bindings9ObjcClass11classForIsAEP10objc_class
-__ZN3KJS8Bindings9ObjcClassC2EP10objc_class
-__ZNK3KJS8Bindings9ObjcClass10fieldNamedERKNS_10IdentifierEPNS0_8InstanceE
-__ZNK3KJS8Bindings9ObjcClass12methodsNamedERKNS_10IdentifierEPNS0_8InstanceE
-__ZN3KJS8Bindings25convertJSMethodNameToObjcEPKcPcm
-__ZN3KJS8Bindings10ObjcMethodC2EP10objc_classPKc
-__ZN3KJS8Bindings12ObjcInstance3endEv
-__ZN3KJS8Bindings12ObjcInstance12invokeMethodEPNS_9ExecStateERKN3WTF6VectorIPNS0_6MethodELm0EEERKNS_4ListE
-__ZNK3KJS8Bindings10ObjcMethod18getMethodSignatureEv
-__ZNK3KJS8Bindings10ObjcMethod4nameEv
-__ZN3KJS8Bindings20objcValueTypeForTypeEPKc
-__ZN3KJS8Bindings23convertValueToObjcValueEPNS_9ExecStateEPNS_7JSValueENS0_13ObjcValueTypeE
-__ZNK3KJS6JSCell9getStringEv
-__ZN3KJS8Bindings23convertNSStringToStringEP8NSString
-__ZN3KJS8Bindings12ObjcInstanceD1Ev
-__ZN3KJS9LabelNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS9LabelNode7executeEPNS_9ExecStateE
-__ZN3KJS12ContinueNodeC1ERKNS_10IdentifierE
-__ZN3KJS11FunctionImp12lengthGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS9BitOrNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS18EmptyStatementNode7executeEPNS_9ExecStateE
-__ZN3KJS22UnsignedRightShiftNodeD1Ev
-__ZN3KJS7ModNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS20arrayProtoFuncFilterEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS6InNode8evaluateEPNS_9ExecStateE
-__ZN3KJS17arrayProtoFuncMapEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS10LessEqNode10precedenceEv
-__ZNK3KJS10LessEqNode8streamToERNS_12SourceStreamE
-__ZNK3KJS18NotStrictEqualNode10precedenceEv
-__ZNK3KJS18NotStrictEqualNode8streamToERNS_12SourceStreamE
-__ZN3KJS14StringInstance16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
-__ZN3KJS7UString4fromEi
-__ZN3KJS14StringInstance11indexGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS21stringProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS22UnsignedRightShiftNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS11ResolveNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS19FunctionCallDotNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS22UnsignedRightShiftNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS11ResolveNode16evaluateToUInt32EPNS_9ExecStateE
-__ZNK3KJS9NumberImp18getTruncatedUInt32ERj
-__ZN3KJS10NumberNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS7SubNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS14BitwiseNotNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS10BitAndNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS7AddNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS7SubNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS8VoidNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS8VoidNode8evaluateEPNS_9ExecStateE
-__ZN3KJS17DeleteResolveNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS18LocalVarDeleteNodeD1Ev
-__ZN3KJS11FunctionImp15argumentsGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS18LocalVarDeleteNode8evaluateEPNS_9ExecStateE
-__ZN3KJS17DeleteResolveNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS16RuntimeObjectImp6canPutEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3KJS13UnaryPlusNode8evaluateEPNS_9ExecStateE
-__ZN3KJS24dateProtoFuncToUTCStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS23booleanProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS11NewExprNode16evaluateToNumberEPNS_9ExecStateE
-__Z22kjs_pcre_ucp_othercasej
-__ZN3KJS17PreDecResolveNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS7JSValue7toFloatEPNS_9ExecStateE
-__ZN3KJS14ExpressionNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS4List26markProtectedListsSlowCaseEv
-__ZNK3KJS6JSCell9getStringERNS_7UStringE
-__ZN3KJS8TrueNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS9RegExpImp3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
-__ZNK3KJS9NumberImp9getUInt32ERj
-__ZN3KJS4Node10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKcPNS_7JSValueEPS0_
-__ZN3KJS23FunctionCallResolveNode15evaluateToInt32EPNS_9ExecStateE
-__ZNK3KJS6JSCell18getTruncatedUInt32ERj
-__ZNK3KJS9LabelNode8streamToERNS_12SourceStreamE
-__ZNK3KJS17ObjectLiteralNode21needsParensIfLeftmostEv
-__ZNK3KJS11DoWhileNode8streamToERNS_12SourceStreamE
-__ZNK3KJS17PreDecResolveNode8streamToERNS_12SourceStreamE
-__ZNK3KJS13PreIncDotNode8streamToERNS_12SourceStreamE
-__ZNK3KJS13PreDecDotNode8streamToERNS_12SourceStreamE
-__ZNK3KJS17DeleteResolveNode8streamToERNS_12SourceStreamE
-__ZN3KJS9FalseNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS23dateProtoFuncSetSecondsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS14PostIncDotNode8streamToERNS_12SourceStreamE
-__ZNK3KJS8Bindings12ObjcInstance14implementsCallEv
-__ZN3KJS8Bindings9ObjcClass14fallbackObjectEPNS_9ExecStateEPNS0_8InstanceERKNS_10IdentifierE
-__ZN3KJS16BooleanObjectImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS11jsUndefinedEv
-___tcf_2
-___tcf_6
-___tcf_0
-___tcf_5
-___tcf_3
-___tcf_4
+__ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZNK3JSC12JSNumberCell8toObjectEPNS_9ExecStateE
+__ZN3JSC15constructNumberEPNS_9ExecStateENS_10JSValuePtrE
+__ZN3JSCL22numberProtoFuncToFixedEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC12JSNumberCell11getJSNumberEv
+__ZN3JSCL16integerPartNoExpEd
+__ZN3JSC11Interpreter27cti_op_get_by_id_proto_failEPvz
+__ZN3WTF6VectorIPN3JSC10RegisterIDELm32EE14expandCapacityEm
+__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC7JSArray3popEv
+__ZNK3JSC11DoWhileNode6isLoopEv
+__ZN3JSC11DoWhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC11DoWhileNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11DoWhileNodeD1Ev
+__ZN3JSC11Interpreter17cti_op_switch_immEPvz
+__ZN3JSCL16mathProtoFuncMinEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC13UnaryPlusNode14stripUnaryPlusEv
+__ZN3JSC13UnaryPlusNodeD1Ev
+__ZN3JSCL21stringProtoFuncSubstrEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC15globalFuncIsNaNEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC17NumberConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callNumberConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter15cti_op_post_incEPvz
+__ZN3JSCL23stringProtoFuncFontsizeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncSetFullYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL23setNewValueFromDateArgsEPNS_9ExecStateENS_10JSValuePtrERKNS_7ArgListEib
+__ZN3JSCL24dateProtoFuncToUTCStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL19stringProtoFuncLinkEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL9dateParseEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter21cti_op_loop_if_lesseqEPvz
+__ZN3JSCL16mathProtoFuncExpEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringE
+__ZN3JSCL21dateProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC4WREC9Generator36generateParenthesesInvertedAssertionERNS_14MacroAssembler8JumpListE
+__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_10JSValuePtrE
+__ZN3JSC9CodeBlock27lineNumberForBytecodeOffsetEPNS_9ExecStateEj
+__ZN3JSCL23regExpProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL18regExpObjectGlobalEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL22regExpObjectIgnoreCaseEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL21regExpObjectMultilineEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC11Interpreter17cti_op_is_booleanEPvz
+__ZNK3JSC12JSNumberCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZN3JSC4WREC14CharacterClass9nonspacesEv
+__ZN3JSC4Heap15recordExtraCostEm
+__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE15reserveCapacityEm
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_14OffsetLocationEENS_18PairFirstExtractorIS8_EENS_7StrHashIS5_EENS_14PairHashTraitsINS_10HashTraitsIS5_EENSE_IS7_EEEESF_EC2ERKSI_
+__ZN3JSC11Interpreter20cti_op_switch_stringEPvz
+__ZNK3JSC12JSNumberCell12toThisObjectEPNS_9ExecStateE
+__ZN3JSCL22numberProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC12NumberObject11getJSNumberEv
+__ZNK3JSC13UnaryPlusNode8opcodeIDEv
+__ZN3WTF12detachThreadEj
+__ZN3WTFL26pthreadHandleForIdentifierEj
+__ZN3WTFL31clearPthreadHandleForIdentifierEj
+__ZN3WTF15ThreadConditionD1Ev
+__ZN3WTF23waitForThreadCompletionEjPPv
+__ZN3WTF20TCMalloc_ThreadCache18DestroyThreadCacheEPv
+__ZN3WTF20TCMalloc_ThreadCache11DeleteCacheEPS0_
+__ZN3WTF14FastMallocZone10statisticsEP14_malloc_zone_tP19malloc_statistics_t
+__ZN3JSC4Heap26protectedGlobalObjectCountEv
+__ZNK3JSC11ResolveNode10isLocationEv
+__ZNK3JSC11ResolveNode13isResolveNodeEv
+__ZN3JSC17AssignResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator18findScopedPropertyERKNS_10IdentifierERiRmbRPNS_8JSObjectE
+__ZN3JSC17BytecodeGenerator15emitResolveBaseEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3JSC15DotAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator12newTemporaryEv
+__ZN3JSC10StringNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3WTF9HashTableIPN3JSC7UString3RepESt4pairIS4_PNS1_8JSStringEENS_18PairFirstExtractorIS8_EENS1_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS4_EENSD_IS7_EEEESE_E6expandEv
+__ZN3JSC16ArgumentListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC10StringNodeD1Ev
+__ZN3JSC16ArgumentListNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC16ArgumentListNodeD1Ev
+__ZN3JSC11Interpreter19cti_op_resolve_baseEPvz
+__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZNK3JSC8JSString8toStringEPNS_9ExecStateE
+__ZN3JSC13AssignDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC10StringNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC13ParameterNode12releaseNodesERNS_12NodeReleaserE
+__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EEaSERKS5_
+__ZNK3JSC7UString14toStrictUInt32EPb
+__ZN3JSC17BytecodeGenerator8emitMoveEPNS_10RegisterIDES2_
+__ZN3JSC16VarStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZL12makeMultNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC14ExpressionNode14stripUnaryPlusEv
+__ZN3JSC10NumberNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEd
+__ZN3WTF9HashTableIdSt4pairIdN3JSC10JSValuePtrEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsIdEENSA_IS3_EEEESB_E6expandEv
+__ZNK3JSC7AddNode8opcodeIDEv
+__ZNK3JSC8MultNode8opcodeIDEv
+__ZN3JSC10NumberNodeD1Ev
+__ZN3JSC8MultNodeD1Ev
+__ZN3JSC3JIT23compileFastArith_op_mulEPNS_11InstructionE
+__ZN3JSC14MacroAssembler4jz32ENS_3X8610RegisterIDENS0_5Imm32E
+__ZN3JSC12X86Assembler7subl_irEiNS_3X8610RegisterIDE
+__ZN3JSC3JIT20compileBinaryArithOpENS_8OpcodeIDEjjjNS_12OperandTypesE
+__ZN3JSC9CodeBlock19isKnownNotImmediateEi
+__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_3X8610RegisterIDEi
+__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_3X8610RegisterIDEi
+__ZN3JSC12X86Assembler8sarl_i8rEiNS_3X8610RegisterIDE
+__ZN3JSC15AssemblerBuffer7putByteEi
+__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_3X8610RegisterIDE
+__ZN3JSC3JIT42putDoubleResultToJSNumberCellOrJSImmediateENS_3X8613XMMRegisterIDENS1_10RegisterIDEjPNS_12X86Assembler6JmpSrcES2_S3_S3_
+__ZN3JSC3JIT27compileFastArithSlow_op_mulEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT27compileFastArithSlow_op_addEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT28compileBinaryArithOpSlowCaseENS_8OpcodeIDERPNS_13SlowCaseEntryEjjjNS_12OperandTypesE
+__ZN3JSC11Interpreter31cti_op_construct_NotJSConstructEPvz
+__ZN3JSC15DateConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL28constructWithDateConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC13constructDateEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC13DatePrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL20dateProtoFuncGetTimeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC12DateInstance9classInfoEv
+__ZN3JSC11Interpreter10cti_op_addEPvz
+__ZN3JSC12jsNumberCellEPNS_12JSGlobalDataEd
+__ZNK3JSC12JSNumberCell8toNumberEPNS_9ExecStateE
+__ZN3JSC11BooleanNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC6IfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC9BlockNode7isBlockEv
+__ZN3JSC9BlockNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9BlockNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC10JSFunction4markEv
+__ZN3JSC16FunctionBodyNode4markEv
+__ZN3JSC23FunctionCallResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator19emitResolveFunctionEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZNK3JSC12NotEqualNode8opcodeIDEv
+__ZNK3JSC8LessNode8opcodeIDEv
+__ZN3JSC23FunctionCallResolveNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC23FunctionCallResolveNodeD1Ev
+__ZN3JSC12NotEqualNodeD1Ev
+__ZN3JSC8LessNodeD1Ev
+__ZN3JSC11Interpreter19cti_op_resolve_funcEPvz
+__ZN3JSC11Interpreter22cti_op_call_JSFunctionEPvz
+__ZN3JSC16FunctionBodyNode16generateBytecodeEPNS_14ScopeChainNodeE
+__ZN3JSC6Parser14reparseInPlaceEPNS_12JSGlobalDataEPNS_16FunctionBodyNodeE
+__ZN3JSC17BytecodeGeneratorC2EPNS_16FunctionBodyNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISE_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE
+__ZN3JSC16FunctionBodyNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC16JSVariableObject16isVariableObjectEv
+__ZN3JSC17BytecodeGenerator16emitGetScopedVarEPNS_10RegisterIDEmiNS_10JSValuePtrE
+__ZNK3JSC13StatementNode12isReturnNodeEv
+__ZN3JSC17BytecodeGenerator10emitReturnEPNS_10RegisterIDE
+__ZN3JSC11Interpreter23cti_vm_dontLazyLinkCallEPvz
+__ZN3JSC11Interpreter23cti_register_file_checkEPvz
+__ZN3JSC17BytecodeGenerator12addParameterERKNS_10IdentifierE
+__ZNK3JSC13StatementNode7isBlockEv
+__ZN3JSC10ReturnNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC14JSGlobalObject14isDynamicScopeEv
+__ZN3JSC10ReturnNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC10ReturnNodeD1Ev
+__ZN3JSC11concatenateEPNS_7UString3RepES2_
+__ZN3JSC11Interpreter23cti_op_get_by_id_secondEPvz
+__ZN3JSC11Interpreter18tryCTICacheGetByIDEPNS_9ExecStateEPNS_9CodeBlockEPvNS_10JSValuePtrERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC3JIT26privateCompileGetByIdProtoEPNS_17StructureStubInfoEPNS_9StructureES4_mPvPNS_9ExecStateE
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiPv
+__ZNK3JSC11ResolveNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC9CodeBlock4markEv
+__ZN3JSC19BracketAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator12emitGetByValEPNS_10RegisterIDES2_S2_
+__ZN3JSC10JSFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC11Interpreter28cti_op_construct_JSConstructEPvz
+__ZN3JSC8JSObject17createInheritorIDEv
+__ZL15makePostfixNodePvPN3JSC14ExpressionNodeENS0_8OperatorEiii
+__ZNK3JSC7ForNode6isLoopEv
+__ZN3JSC7ForNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13newLabelScopeENS_10LabelScope4TypeEPKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator8emitJumpEPNS_5LabelE
+__ZN3JSC17AssignBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC8ThisNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator12emitPutByValEPNS_10RegisterIDES2_S2_
+__ZN3JSC18PostfixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14emitJumpIfTrueEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC7ForNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC7ForNodeD1Ev
+__ZN3JSC18PostfixResolveNodeD1Ev
+__ZN3JSC17AssignBracketNodeD1Ev
+__ZN3JSC17AssignBracketNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC8ThisNodeD1Ev
+__ZN3JSC3JIT27compileFastArith_op_pre_incEj
+__ZN3JSC12X86Assembler2joEv
+__ZN3JSC3JIT19emitSlowScriptCheckEv
+__ZN3JSC3JIT31compileFastArithSlow_op_pre_incEjRPNS_13SlowCaseEntryE
+__ZN3JSC11Interpreter22cti_op_call_arityCheckEPvz
+__ZN3JSC10JSFunction15argumentsGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZNK3JSC11Interpreter17retrieveArgumentsEPNS_9ExecStateEPNS_10JSFunctionE
+__ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC11Interpreter17cti_op_get_by_valEPvz
+__ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC11Interpreter17cti_op_put_by_valEPvz
+__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_10JSValuePtrE
+__ZN3JSC11Interpreter24cti_op_get_by_id_genericEPvz
+__ZN3JSCL21dateProtoFuncGetMonthEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC12DateInstance21msToGregorianDateTimeEdbRNS_17GregorianDateTimeE
+__ZN3JSC21msToGregorianDateTimeEdbRNS_17GregorianDateTimeE
+__ZN3JSCL12getDSTOffsetEdd
+__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL20dateProtoFuncGetDateEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11concatenateEPNS_7UString3RepEi
+__ZN3JSC21ReadModifyResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC21ReadModifyResolveNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZL11makeSubNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC10IfElseNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC10LessEqNode8opcodeIDEv
+__ZNK3JSC7SubNode8opcodeIDEv
+__ZN3JSC10LessEqNodeD1Ev
+__ZN3JSC7SubNodeD1Ev
+__ZN3JSC3JIT23compileFastArith_op_subEPNS_11InstructionE
+__ZN3JSC3JIT27compileFastArithSlow_op_subEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSCL21dateProtoFuncGetHoursEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter13cti_op_lesseqEPvz
+__ZN3JSCL23dateProtoFuncGetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC13GreaterEqNode8opcodeIDEv
+__ZN3JSC13GreaterEqNodeD1Ev
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_16SymbolTableEntryEENS_18PairFirstExtractorIS8_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS5_EENS2_26SymbolTableIndexHashTraitsEEESE_E4findIS5_NS_22IdentityHashTranslatorIS5_S8_SB_EEEENS_17HashTableIteratorIS5_S8_SA_SB_SG_SE_EERKT_
+__ZN3JSC8WithNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13emitPushScopeEPNS_10RegisterIDE
+__ZN3WTF6VectorIN3JSC18ControlFlowContextELm0EE14expandCapacityEm
+__ZN3JSC11Interpreter9cti_op_eqEPvz
+__ZN3JSCeqERKNS_7UStringES2_
+__ZN3JSC11Interpreter17cti_op_push_scopeEPvz
+__ZN3JSC11Interpreter14cti_op_resolveEPvz
+__ZN3JSC11Interpreter16cti_op_pop_scopeEPvz
+__ZN3JSC8NullNodeD1Ev
+__ZN3JSC8NullNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator20emitNextPropertyNameEPNS_10RegisterIDES2_PNS_5LabelE
+__ZN3JSC9ForInNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11Interpreter17cti_op_get_pnamesEPvz
+__ZN3JSC22JSPropertyNameIterator6createEPNS_9ExecStateENS_10JSValuePtrE
+__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC9Structure26getEnumerablePropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayEPNS_8JSObjectE
+__ZN3JSC9Structure34getEnumerablePropertyNamesInternalERNS_17PropertyNameArrayE
+__ZNK3JSC6JSCell9classInfoEv
+__ZN3JSC9Structure26createCachedPrototypeChainEv
+__ZN3JSC14StructureChainC1EPNS_9StructureE
+__ZN3JSC11Interpreter17cti_op_next_pnameEPvz
+__ZN3JSC23structureChainsAreEqualEPNS_14StructureChainES1_
+__ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE
+__ZN3JSC11Interpreter10cti_op_neqEPvz
+__ZN3JSC16globalFuncEscapeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11JSImmediate8toStringENS_10JSValuePtrE
+__ZN3JSC7UString4fromEi
+__ZN3JSC7UString6appendERKS0_
+__ZN3JSC22JSPropertyNameIterator10invalidateEv
+__ZN3JSCL21dateProtoFuncSetMonthEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL20dateProtoFuncSetDateEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCplERKNS_7UStringES2_
+__ZN3JSC14ExecutablePool13systemReleaseERKNS0_10AllocationE
+__ZNK3JSC8JSString11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZN3JSC16ArrayConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL29constructWithArrayConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSCL27constructArrayWithSizeQuirkEPNS_9ExecStateERKNS_7ArgListE
+__ZL14makePrefixNodePvPN3JSC14ExpressionNodeENS0_8OperatorEiii
+__ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC9WhileNode6isLoopEv
+__ZN3JSC9WhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9WhileNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC13PrefixDotNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC13PrefixDotNodeD1Ev
+__ZN3JSC9WhileNodeD1Ev
+__ZN3JSC3JIT28compileFastArith_op_post_incEjj
+__ZN3JSC3JIT32compileFastArithSlow_op_post_incEjjRPNS_13SlowCaseEntryE
+__ZN3JSC11Interpreter22cti_op_push_activationEPvz
+__ZN3JSC12JSActivationC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_16FunctionBodyNodeEEE
+__ZN3JSC12JSActivation18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZL11makeDivNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC15ConditionalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC7DivNode8opcodeIDEv
+__ZN3JSC15ConditionalNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC15ConditionalNodeD1Ev
+__ZN3JSC7DivNodeD1Ev
+__ZN3JSC7JSArrayC2EN3WTF10PassRefPtrINS_9StructureEEEj
+__ZN3JSC11Interpreter23cti_op_put_by_val_arrayEPvz
+__ZN3JSC7JSArray3putEPNS_9ExecStateEjNS_10JSValuePtrE
+__ZN3JSC7JSArray3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC11Interpreter10cti_op_divEPvz
+__ZN3JSC3JIT16patchGetByIdSelfEPNS_17StructureStubInfoEPNS_9StructureEmPv
+__ZN3JSC3JIT33privateCompilePatchGetArrayLengthEPv
+__ZN3JSC11Interpreter23cti_op_put_by_id_secondEPvz
+__ZN3JSC11Interpreter18tryCTICachePutByIDEPNS_9ExecStateEPNS_9CodeBlockEPvNS_10JSValuePtrERKNS_15PutPropertySlotE
+__ZN3JSCL19cachePrototypeChainEPNS_9ExecStateEPNS_9StructureE
+__ZN3JSC3JIT31privateCompilePutByIdTransitionEPNS_17StructureStubInfoEPNS_9StructureES4_mPNS_14StructureChainEPv
+__ZN3JSC9Structure22materializePropertyMapEv
+__ZN3JSC3JIT19patchPutByIdReplaceEPNS_17StructureStubInfoEPNS_9StructureEmPv
+__ZN3JSCL21resizePropertyStorageEPNS_8JSObjectEii
+__ZN3JSC8JSObject23allocatePropertyStorageEmm
+__ZN3JSC11Interpreter14cti_op_pre_incEPvz
+__ZN3JSCL21stringProtoFuncCharAtEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC12StringObject12toThisStringEPNS_9ExecStateE
+__ZN3JSC11Interpreter26cti_op_tear_off_activationEPvz
+__ZN3JSC11Interpreter21cti_op_ret_scopeChainEPvz
+__ZN3JSC11Interpreter27cti_op_get_by_id_proto_listEPvz
+__ZN3JSC3JIT30privateCompileGetByIdProtoListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureES6_mPNS_9ExecStateE
+__ZN3JSC12JSActivationD0Ev
+__ZN3JSCL26stringProtoFuncToLowerCaseEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC8JSString14toThisJSStringEPNS_9ExecStateE
+__ZN3JSC7JSArray11putSlowCaseEPNS_9ExecStateEjNS_10JSValuePtrE
+__ZN3WTF11fastReallocILb0EEEPvS1_m
+__ZN3JSCL24stringProtoFuncSubstringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11jsSubstringEPNS_12JSGlobalDataERKNS_7UStringEjj
+__ZN3JSCL20stringProtoFuncSplitEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC19constructEmptyArrayEPNS_9ExecStateE
+__ZNK3JSC11BooleanNode6isPureERNS_17BytecodeGeneratorE
+__ZNK3JSC7ModNode8opcodeIDEv
+__ZN3JSC7ModNodeD1Ev
+__ZN3JSC3JIT23compileFastArith_op_modEjjj
+__ZN3JSC3JIT27compileFastArithSlow_op_modEjjjRPNS_13SlowCaseEntryE
+__ZN3JSCL23dateProtoFuncGetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC17BytecodeGenerator16emitPutScopedVarEmiPNS_10RegisterIDENS_10JSValuePtrE
+__ZN3JSC18globalFuncUnescapeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC7UString6appendEt
+__ZN3JSC11Interpreter19cti_vm_lazyLinkCallEPvz
+__ZN3JSC3JIT8linkCallEPNS_10JSFunctionEPNS_9CodeBlockEPvPNS_12CallLinkInfoEi
+__ZN3WTF6VectorIPN3JSC12CallLinkInfoELm0EE14expandCapacityEm
+__ZN3JSC12X86Assembler7cmpl_imEiiNS_3X8610RegisterIDE
+__ZN3JSC9CodeBlock13unlinkCallersEv
+__ZNK3JSC8JSString9toBooleanEPNS_9ExecStateE
+__ZN3JSC11Interpreter10cti_op_mulEPvz
+__ZN3JSC11Interpreter18cti_op_to_jsnumberEPvz
+__ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL18mathProtoFuncFloorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL13jsAddSlowCaseEPNS_9ExecStateENS_10JSValuePtrES2_
+__ZN3JSC20globalFuncParseFloatEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC7UString4fromEj
+__ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPNS_7UString3RepE
+__ZN3JSC7UString17expandPreCapacityEi
+__ZN3JSC9CommaNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9CommaNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC16VarDeclCommaNodeD1Ev
+__ZN3JSC7UStringC1EPtib
+__ZN3JSC5Error6createEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringEilS6_
+__ZN3JSC22NativeErrorConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL35constructWithNativeErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC22NativeErrorConstructor9constructEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrEj
+__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
+__ZNK3JSC8JSObject11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZN3JSCL22errorProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
+__ZN3JSC7UString6appendEPKc
+__ZN3JSC3JIT10unlinkCallEPNS_12CallLinkInfoE
+__ZN3JSC11Interpreter24cti_op_put_by_id_genericEPvz
+__ZN3JSC21FunctionCallValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE
+__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncExprNodeEEELm0EE15reserveCapacityEm
+__ZN3WTF7HashSetINS_6RefPtrIN3JSC7UString3RepEEENS2_17IdentifierRepHashENS_10HashTraitsIS5_EEE3addERKS5_
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEES5_NS_17IdentityExtractorIS5_EENS2_17IdentifierRepHashENS_10HashTraitsIS5_EESA_E6expandEv
+__ZL14compileBracketiPiPPhPPKtS3_P9ErrorCodeiS_S_R11CompileData
+__ZN3JSC4WREC9Generator20generateAssertionEOLERNS_14MacroAssembler8JumpListE
+__ZN3JSC17ObjectLiteralNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC4WREC31GeneratePatternCharacterFunctor12generateAtomEPNS0_9GeneratorERNS_14MacroAssembler8JumpListE
+__ZN3JSC4WREC31GeneratePatternCharacterFunctor9backtrackEPNS0_9GeneratorE
+__ZL20branchNeedsLineStartPKhjj
+__ZN3JSC9ArrayNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator12emitNewArrayEPNS_10RegisterIDEPNS_11ElementNodeE
+__ZL17bracketIsAnchoredPKh
+__ZL32branchFindFirstAssertedCharacterPKhb
+__ZN3JSC10JSFunction3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC11concatenateEPNS_7UString3RepEd
+__ZNK3JSC12JSActivation14isDynamicScopeEv
+__ZN3JSC17TypeOfResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15StrictEqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC12ContinueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14continueTargetERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator14emitJumpScopesEPNS_5LabelEi
+__ZN3JSC15TypeOfValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15TypeOfValueNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC17TypeOfResolveNodeD1Ev
+__ZN3JSC15StrictEqualNodeD1Ev
+__ZN3JSC12ContinueNodeD1Ev
+__ZN3JSC15TypeOfValueNodeD1Ev
+__ZN3JSC11Interpreter33cti_op_create_arguments_no_paramsEPvz
+__ZN3JSC11Interpreter13cti_op_typeofEPvz
+__ZN3JSCL20jsTypeStringForValueEPNS_9ExecStateENS_10JSValuePtrE
+__ZN3JSC6JSCell11getCallDataERNS_8CallDataE
+__ZN3JSCL30comparePropertyMapEntryIndicesEPKvS1_
+__ZN3WTF6VectorIN3JSC10IdentifierELm20EE15reserveCapacityEm
+__ZN3JSCL22objectProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC14ArrayPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL22functionProtoFuncApplyEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC7JSArray9classInfoEv
+__ZN3JSCL18arrayProtoFuncPushEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter27cti_op_get_by_id_array_failEPvz
+__ZN3JSC14PostfixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC14PostfixDotNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11Interpreter32cti_op_get_by_id_proto_list_fullEPvz
+__ZN3JSC12FuncExprNodeD1Ev
+__ZN3JSC12FuncExprNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11Interpreter26cti_op_get_by_id_self_failEPvz
+__ZN3JSC3JIT29privateCompileGetByIdSelfListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureEm
+__ZN3JSCL19arrayProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter25cti_op_tear_off_argumentsEPvz
+__ZN3WTF6VectorIPN3JSC9StructureELm8EE14expandCapacityEm
+__ZN3JSCL44countPrototypeChainEntriesAndCheckForProxiesEPNS_9ExecStateENS_10JSValuePtrERKNS_12PropertySlotE
+__ZN3JSC17DeleteBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17DeleteBracketNodeD1Ev
+__ZN3JSC17DeleteBracketNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11Interpreter17cti_op_del_by_valEPvz
+__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZNK3JSC6JSCell9getUInt32ERj
+__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSCL11getPropertyEPNS_9ExecStateEPNS_8JSObjectEj
+__ZN3JSC17ReadModifyDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17ReadModifyDotNodeD1Ev
+__ZN3JSC17ReadModifyDotNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11JSImmediate9prototypeENS_10JSValuePtrEPNS_9ExecStateE
+__ZN3JSC9CodeBlock34reparseForExceptionInfoIfNecessaryEPNS_9ExecStateE
+__ZNK3JSC10ScopeChain10localDepthEv
+__ZNK3JSC12JSActivation9classInfoEv
+__ZN3JSC6Parser7reparseINS_16FunctionBodyNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPS5_
+__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm0EEERKNS_10SourceCodeEji
+__ZN3JSC13StatementNode6setLocEii
+__ZN3JSC16FunctionBodyNode14copyParametersEv
+__ZN3JSC16FunctionBodyNode13finishParsingEPNS_10IdentifierEm
+__ZN3JSC16FunctionBodyNode31bytecodeForExceptionInfoReparseEPNS_14ScopeChainNodeEPNS_9CodeBlockE
+__ZN3JSC9CodeBlock36hasGlobalResolveInfoAtBytecodeOffsetEj
+__ZN3JSC6RegExpD1Ev
__Z12jsRegExpFreeP8JSRegExp
-__ZN3KJS25CollectorHeapIntrospector4sizeEP14_malloc_zone_tPKv
-__ZN3WTF9HashTableINS_6RefPtrIN3KJS7UString3RepEEESt4pairIS5_mENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS2_23IdentifierRepHashTraitsENS2_26SymbolTableIndexHashTraitsEEESC_E4findIS5_NS_22IdentityHashTranslatorIS5_S7_SA_EEEENS_17HashTableIteratorIS5_S7_S9_SA_SE_SC_EERKT_
-__ZN3KJS18AssignLocalVarNodeD1Ev
-__ZN3KJS8TrueNodeD1Ev
-__ZN3KJS11NewExprNodeD1Ev
-__ZN3KJS19ImmediateNumberNodeD1Ev
-__ZN3KJS17AssignBracketNodeD1Ev
-__ZN3KJS18LocalVarAccessNodeD1Ev
-__ZN3KJS16ParserRefCounted8refcountEv
-__ZN3KJS14JSGlobalObject16stopTimeoutCheckEv
-__ZN3KJS11GreaterNodeD1Ev
-__ZN3KJS16ArgumentListNodeD1Ev
-__ZN3KJS17FunctionObjectImp9constructEPNS_9ExecStateERKNS_4ListERKNS_10IdentifierERKNS_7UStringEi
-__ZN3KJS6Parser5parseINS_16FunctionBodyNodeEEEN3WTF10PassRefPtrIT_EERKNS_7UStringEiPKNS_5UCharEjPiSD_PS7_
-__ZN3KJS8JSObject4callEPNS_9ExecStateEPS0_RKNS_4ListE
-__ZN3KJS18AddStringRightNode8evaluateEPNS_9ExecStateE
-__ZN3KJS16globalFuncEscapeEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS13DateObjectImp19implementsConstructEv
-__ZN3KJS13DateObjectImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZN3KJS13DatePrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS20dateProtoFuncGetTimeEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS12DateInstance9classInfoEv
-__ZNK3KJS9NumberImp8toNumberEPNS_9ExecStateE
-__ZNK3KJS9NumberImp8toStringEPNS_9ExecStateE
-__ZN3KJS9BlockNodeD1Ev
-__ZN3KJS21dateProtoFuncGetMonthEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS21msToGregorianDateTimeEdbRNS_17GregorianDateTimeE
-__ZN3KJS12getUTCOffsetEv
-__ZN3KJS12getDSTOffsetEdd
-__ZN3KJS15ConditionalNodeD1Ev
-__ZN3KJS7DivNodeD1Ev
-__ZN3KJS9EqualNodeD1Ev
-__ZN3KJS8NullNodeD1Ev
-__ZN3KJS9FalseNodeD1Ev
-__ZN3KJS12NotEqualNodeD1Ev
-__ZN3KJS7SubNodeD1Ev
-__ZN3KJS7SubNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS24LocalVarFunctionCallNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS21ReadModifyResolveNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS14StringInstance12lengthGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS18globalFuncUnescapeEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS7DivNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS7DivNode8evaluateEPNS_9ExecStateE
-__ZN3KJS18LocalVarAccessNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS8MultNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS8MultNode8evaluateEPNS_9ExecStateE
-__ZN3KJS19FunctionCallDotNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS7SubNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS9NumberImp11toPrimitiveEPNS_9ExecStateENS_6JSTypeE
-__ZN3KJS18AddStringRightNodeD1Ev
-__ZN3KJS7AddNodeD1Ev
-__ZN3KJS13LogicalOrNodeD1Ev
-__ZN3KJS17PreIncResolveNodeD1Ev
-__ZN3KJS8MultNodeD1Ev
-__ZN3KJS8LessNodeD1Ev
-__ZN3KJS14LogicalAndNodeD1Ev
-__ZN3KJS10NumberNodeD1Ev
-__ZN3KJS13GreaterEqNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS14LogicalNotNodeD1Ev
-__ZN3KJS7ModNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS14JSGlobalObject12checkTimeoutEv
-__ZN3KJS7ModNode8evaluateEPNS_9ExecStateE
-__ZN3KJS15LessNumbersNode8evaluateEPNS_9ExecStateE
-__ZN3KJS20dateProtoFuncGetYearEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS8ThisNodeD1Ev
-__ZN3KJS19mathProtoFuncRandomEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS20globalFuncParseFloatEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS13GreaterEqNode8evaluateEPNS_9ExecStateE
-__ZN3KJS20dateProtoFuncGetDateEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS18mathProtoFuncFloorEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS23stringProtoFuncFontsizeEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS11ResolveNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS13GreaterEqNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS9NumberImp18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
-__ZN3KJS19stringProtoFuncLinkEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS19dateProtoFuncGetDayEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS21dateProtoFuncGetHoursEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS23dateProtoFuncGetMinutesEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS23dateProtoFuncGetSecondsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS9ArrayNodeD1Ev
-__ZN3KJS11ElementNodeD1Ev
-__ZN3KJS17ObjectLiteralNodeD1Ev
-__ZN3KJS14PostfixDotNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS14PostIncDotNode8evaluateEPNS_9ExecStateE
-__ZN3KJS19PlaceholderTrueNodeD1Ev
-__ZN3KJS19PostDecLocalVarNode8evaluateEPNS_9ExecStateE
-__ZN3KJS17ReadModifyDotNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS17ReadModifyDotNode8evaluateEPNS_9ExecStateE
-__ZN3KJS21FunctionCallValueNodeD1Ev
-__ZN3KJS10BitAndNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS14AddNumbersNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS10BitXOrNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS22UnsignedRightShiftNode8evaluateEPNS_9ExecStateE
-__ZN3KJS8MultNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS7DivNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS19StringObjectFuncImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS7ModNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS10BitAndNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS14RightShiftNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS14AddNumbersNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS14globalFuncEvalEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EERKNS_7UStringEiPKNS_5UCharEjPiSD_PS7_
-__ZN3KJS13EvalExecStateC1EPNS_14JSGlobalObjectEPNS_8EvalNodeEPNS_9ExecStateE
-__ZN3KJS8EvalNode7executeEPNS_9ExecStateE
-__ZN3KJS8EvalNodeD1Ev
-__ZN3KJS23FunctionCallBracketNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS23FunctionCallBracketNode8evaluateEPNS_9ExecStateE
-__ZN3KJS16PropertyListNodeD1Ev
-__ZN3KJS12PropertyNodeD1Ev
-__ZN3KJS13CaseBlockNodeD1Ev
-__ZN3KJS14CaseClauseNodeD1Ev
-__ZN3KJS14ClauseListNodeD1Ev
-__ZN3KJS9RegExpImp18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS17staticValueGetterINS_9RegExpImpEEEPNS_7JSValueEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKNS_12PropertySlotE
-__ZNK3KJS9RegExpImp16getValuePropertyEPNS_9ExecStateEi
-__ZN3KJS9ThrowNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS15StrictEqualNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS19regExpProtoFuncTestEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS9RegExpImp5matchEPNS_9ExecStateERKNS_4ListE
-__ZN3KJS15StrictEqualNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS18NotStrictEqualNodeD1Ev
-__ZN3KJS15StrictEqualNodeD1Ev
-__ZN3KJS18LocalVarTypeOfNodeD1Ev
-__ZN3KJS19globalFuncEncodeURIEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS17TypeOfResolveNode8evaluateEPNS_9ExecStateE
-__ZN3KJS26stringProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS7JSValue20toIntegerPreserveNaNEPNS_9ExecStateE
-__ZNK3KJS7UString5rfindERKS0_i
-__ZN3KJS15TypeOfValueNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS15TypeOfValueNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS17FunctionObjectImp19implementsConstructEv
-__ZN3KJS17FunctionObjectImp9constructEPNS_9ExecStateERKNS_4ListE
-__ZNK3KJS8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3KJS30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS8JSObject3putEPNS_9ExecStateEjPNS_7JSValueEi
-__ZN3KJS6InNodeD1Ev
-__ZNK3KJS9Arguments9classInfoEv
-__ZN3KJS10BitXOrNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS19addSlowCaseToNumberEPNS_9ExecStateEPNS_7JSValueES3_
-__ZN3KJS8JSObject14deletePropertyEPNS_9ExecStateEj
-__ZNK3KJS9WhileNode8streamToERNS_12SourceStreamE
-__ZNK3KJS9FalseNode8streamToERNS_12SourceStreamE
-__ZNK3KJS7DivNode8streamToERNS_12SourceStreamE
-__ZNK3KJS7DivNode10precedenceEv
-__ZNK3KJS15StrictEqualNode8streamToERNS_12SourceStreamE
-__ZNK3KJS15StrictEqualNode10precedenceEv
-__ZNK3KJS16VarDeclCommaNode10precedenceEv
-__ZNK3KJS17PreIncResolveNode8streamToERNS_12SourceStreamE
-__ZNK3KJS9FalseNode10precedenceEv
-__ZN3KJS14InstanceOfNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZNK3KJS19InternalFunctionImp21implementsHasInstanceEv
-__ZN3KJS8JSObject11hasInstanceEPNS_9ExecStateEPNS_7JSValueE
-__ZN3WTF14FastMallocZone9forceLockEP14_malloc_zone_t
-__ZN3KJS25CollectorHeapIntrospector9forceLockEP14_malloc_zone_t
-__ZN3WTF14FastMallocZone11forceUnlockEP14_malloc_zone_t
-__ZN3KJS25CollectorHeapIntrospector11forceUnlockEP14_malloc_zone_t
-__ZNK3KJS23FunctionCallBracketNode10precedenceEv
-__ZN3KJS14InstanceOfNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS9ThrowNode8streamToERNS_12SourceStreamE
-__ZNK3KJS7SubNode10precedenceEv
-__ZNK3KJS7SubNode8streamToERNS_12SourceStreamE
-__ZNK3KJS10NegateNode10precedenceEv
-__ZNK3KJS10NegateNode8streamToERNS_12SourceStreamE
-__ZNK3KJS12FuncDeclNode8streamToERNS_12SourceStreamE
-__ZNK3KJS18PostDecResolveNode8streamToERNS_12SourceStreamE
-__ZNK3KJS9BreakNode8streamToERNS_12SourceStreamE
-__ZNK3KJS6InNode10precedenceEv
-__ZNK3KJS6InNode8streamToERNS_12SourceStreamE
-__ZN3KJS14StringInstanceC2EPNS_8JSObjectERKNS_7UStringE
-__ZN3KJS18PostDecBracketNode8evaluateEPNS_9ExecStateE
-__ZN3KJS28dateProtoFuncGetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS18PostIncResolveNode8streamToERNS_12SourceStreamE
-__ZN3KJS13ArrayInstance14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3KJS14StringInstance14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3KJS15AssignErrorNodeD1Ev
-__ZN3WTF6VectorIcLm0EE14expandCapacityEmPKc
-__ZN3WTF6VectorIcLm0EE14expandCapacityEm
-_JSContextGetGlobalObject
-_JSClassCreate
+__ZN3JSC12JSActivation4markEv
+__ZN3JSC9ThrowNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9ThrowNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC9ThrowNodeD1Ev
+__ZNK3JSC21UStringSourceProvider6lengthEv
+__ZNK3JSC21UStringSourceProvider4dataEv
+__ZN3JSC21UStringSourceProviderD1Ev
+__ZN3JSC3JIT26privateCompileGetByIdChainEPNS_17StructureStubInfoEPNS_9StructureEPNS_14StructureChainEmmPvPNS_9ExecStateE
+__ZN3JSCL18arrayProtoFuncJoinEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3WTF7HashSetIPN3JSC8JSObjectENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3WTF6VectorItLm256EE14expandCapacityEm
+__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
+__ZN3JSC3JIT28compileFastArith_op_post_decEjj
+__ZN3JSC3JIT27compileFastArith_op_pre_decEj
+__ZN3JSC3JIT32compileFastArithSlow_op_post_decEjjRPNS_13SlowCaseEntryE
+__ZN3JSC3JIT31compileFastArithSlow_op_pre_decEjRPNS_13SlowCaseEntryE
+__ZN3JSCL26stringProtoFuncToUpperCaseEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC9Arguments4markEv
+__ZN3JSC11Interpreter17cti_timeout_checkEPvz
+__ZN3JSCL18stringFromCharCodeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC17ObjectConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithObjectConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC19JSStaticScopeObject4markEv
+__ZN3JSC17NumberConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC21ThrowableBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC6InNode8opcodeIDEv
+__ZN3JSC11Interpreter9cti_op_inEPvz
+__ZN3JSC11Interpreter21cti_op_put_by_id_failEPvz
+__ZN3JSC17RegExpConstructor3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC11Interpreter18cti_op_is_functionEPvz
+__ZN3JSC18globalFuncIsFiniteEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL21arrayProtoFuncForEachEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL17arrayProtoFuncMapEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC12StringObject14toThisJSStringEPNS_9ExecStateE
+__ZNK3JSC8JSString12toThisObjectEPNS_9ExecStateE
+__ZN3JSCL21arrayProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC13DeleteDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14emitDeleteByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZN3JSC13DeleteDotNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11Interpreter16cti_op_del_by_idEPvz
+__ZN3JSC10JSFunction14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC10JSFunction12callerGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
+__ZN3JSCL22arrayProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC16ErrorConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL29constructWithErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC14constructErrorEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC12JSActivation3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3WTF6VectorIN3JSC14MacroAssembler4JumpELm16EE14expandCapacityEm
+__ZN3JSC14InstanceOfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14emitInstanceOfEPNS_10RegisterIDES2_S2_S2_
+__ZN3JSC14InstanceOfNodeD1Ev
+__ZN3JSC11JSImmediate8toObjectENS_10JSValuePtrEPNS_9ExecStateE
+__ZNK3JSC12NumberObject9classInfoEv
+__ZN3JSC11Interpreter17cti_op_instanceofEPvz
+__ZNK3JSC7UString6substrEii
+__ZN3JSCL20arrayProtoFuncSpliceEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC19FunctionConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL32constructWithFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
+__ZNK3JSC17ExprStatementNode15isExprStatementEv
+__ZNK3JSC12FuncExprNode14isFuncExprNodeEv
+__ZN3JSC7ArgList9markListsERN3WTF7HashSetIPS0_NS1_7PtrHashIS3_EENS1_10HashTraitsIS3_EEEE
+__ZN3JSC9CommaNodeD1Ev
+__ZN3JSC11Interpreter12cti_op_throwEPvz
+__ZN3JSC11Interpreter14throwExceptionERPNS_9ExecStateERNS_10JSValuePtrEjb
+__ZNK3JSC8JSObject22isNotAnObjectErrorStubEv
+__ZN3JSC9CodeBlock32expressionRangeForBytecodeOffsetEPNS_9ExecStateEjRiS3_S3_
+__ZNK3JSC8JSObject19isWatchdogExceptionEv
+__ZN3JSC9CodeBlock24handlerForBytecodeOffsetEj
+__ZN3JSC11Interpreter15unwindCallFrameERPNS_9ExecStateENS_10JSValuePtrERjRPNS_9CodeBlockE
+__ZN3JSCL23returnToThrowTrampolineEPNS_12JSGlobalDataEPvRS2_
+__ZN3JSC19ctiSetReturnAddressEPPvS0_
+ctiVMThrowTrampoline
+__ZN3JSC11Interpreter12cti_vm_throwEPvz
+__ZN3JSC11Interpreter21cti_op_push_new_scopeEPvz
+__ZN3JSC19JSStaticScopeObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC9Arguments3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC4WREC9Generator27generateNonGreedyQuantifierERNS_14MacroAssembler8JumpListERNS0_19GenerateAtomFunctorEjj
+__ZN3JSCL21arrayProtoFuncReverseEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC7UString6appendEPKti
+__ZN3JSCL26stringProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC10JSValuePtr20toIntegerPreserveNaNEPNS_9ExecStateE
+__Z22jsc_pcre_ucp_othercasej
+__ZN3JSCL24regExpConstructorDollar1EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar2EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar3EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar4EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL19dateProtoFuncGetDayEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC19JSStaticScopeObject14isDynamicScopeEv
+__ZN3JSCL35objectProtoFuncPropertyIsEnumerableEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC8JSObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
+__ZN3WTF9HashTableIjSt4pairIjN3JSC10JSValuePtrEENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSA_IS3_EEEESB_EC2ERKSE_
+__ZN3JSC11Interpreter14cti_op_pre_decEPvz
+__ZN3JSC11Interpreter16cti_op_new_arrayEPvz
+__ZN3JSC14constructArrayEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC10JSFunction11getCallDataERNS_8CallDataE
+__ZN3JSC4callEPNS_9ExecStateENS_10JSValuePtrENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
+__ZN3JSC11Interpreter7executeEPNS_16FunctionBodyNodeEPNS_9ExecStateEPNS_10JSFunctionEPNS_8JSObjectERKNS_7ArgListEPNS_14ScopeChainNodeEPNS_10JSValuePtrE
+__ZN3JSC9LabelNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9LabelNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11Interpreter15cti_op_stricteqEPvz
+__Z15jsRegExpExecutePK8JSRegExpPKtiiPii
+__ZL5matchPKtPKhiR9MatchData
+__ZN3JSC18RegExpMatchesArrayC2EPNS_9ExecStateEPNS_24RegExpConstructorPrivateE
+__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC18RegExpMatchesArray17fillArrayInstanceEPNS_9ExecStateE
+__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC12RegExpObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL19regExpProtoFuncTestEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC12RegExpObject5matchEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSCL21functionProtoFuncCallEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC8JSString8toObjectEPNS_9ExecStateE
+__ZNK3JSC7ArgList8getSliceEiRS0_
+__ZN3JSC17RegExpConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC23FunctionCallBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC23FunctionCallBracketNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC23FunctionCallBracketNodeD1Ev
+__ZN3JSC11Interpreter16cti_op_is_stringEPvz
+__ZN3JSC7TryNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator9emitCatchEPNS_10RegisterIDEPNS_5LabelES4_
+__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator16emitPushNewScopeEPNS_10RegisterIDERNS_10IdentifierES2_
+__ZN3JSC7TryNode12releaseNodesERNS_12NodeReleaserE
+__ZN3WTF6VectorIN3JSC14ExecutablePool10AllocationELm2EE14expandCapacityEm
+__ZN3JSC11Interpreter19cti_op_loop_if_lessEPvz
+__ZN3JSCL22stringProtoFuncReplaceEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC7UString30spliceSubstringsWithSeparatorsEPKNS0_5RangeEiPKS0_i
+__Z15jsc_pcre_xclassiPKh
+__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateEjNS_10JSValuePtrE
+__ZN3JSC7JSArray9setLengthEj
+__ZN3JSCL21arrayProtoFuncUnShiftEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC11Interpreter19cti_op_is_undefinedEPvz
+__ZNK3JSC9Arguments9classInfoEv
+__ZN3JSC9Arguments11fillArgListEPNS_9ExecStateERNS_7ArgListE
+__ZN3JSC11Interpreter23cti_op_create_argumentsEPvz
+__ZN3JSC17PropertyNameArray3addEPNS_7UString3RepE
+__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7PtrHashIS4_EENS_10HashTraitsIS4_EEE3addERKS4_
+__ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7PtrHashIS4_EENS_10HashTraitsIS4_EESA_E6expandEv
+__ZN3WTF6VectorIN3JSC10IdentifierELm20EE14expandCapacityEm
+__ZN3JSC11Interpreter19cti_op_convert_thisEPvz
+__ZN3JSC17PrefixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17PrefixBracketNodeD1Ev
+__ZN3JSC17PrefixBracketNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSCL25functionProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC10JSFunction9classInfoEv
+__ZN3JSC7CStringD1Ev
+__ZN3JSC6JSLock12DropAllLocksC1Eb
+__ZN3JSCL17createJSLockCountEv
+__ZN3JSC6JSLock12DropAllLocksD1Ev
+__ZN3JSC26createNotAnObjectErrorStubEPNS_9ExecStateEb
+__ZN3JSC13JSNotAnObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZNK3JSC22JSNotAnObjectErrorStub22isNotAnObjectErrorStubEv
+__ZN3JSC22createNotAnObjectErrorEPNS_9ExecStateEPNS_22JSNotAnObjectErrorStubEjPNS_9CodeBlockE
+__ZN3JSC9CodeBlock37getByIdExceptionInfoForBytecodeOffsetEPNS_9ExecStateEjRNS_8OpcodeIDE
+__ZN3JSCL18createErrorMessageEPNS_9ExecStateEPNS_9CodeBlockEiiiNS_10JSValuePtrENS_7UStringE
+__ZNK3JSC7UString5asciiEv
+__ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF10PassRefPtrINS_9StructureEEERKNS_10IdentifierE
+__ZN3WTF13tryFastCallocEmm
+__ZN3JSC13JSNotAnObjectD0Ev
+__ZN3JSCL31dateProtoFuncToLocaleTimeStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL16formatLocaleDateEPNS_9ExecStateEPNS_12DateInstanceEdNS_20LocaleDateTimeFormatERKNS_7ArgListE
+__ZN3JSC16InternalFunction4nameEPNS_12JSGlobalDataE
+__ZNK3JSC6JSCell9getStringERNS_7UStringE
+__ZN3JSC28globalFuncDecodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC14ExpressionNode8isStringEv
+__ZN3JSC17RegExpConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC23createNotAFunctionErrorEPNS_9ExecStateENS_10JSValuePtrEjPNS_9CodeBlockE
+__ZN3JSC11Interpreter17cti_op_jmp_scopesEPvz
+__ZN3JSC17BytecodeGenerator18emitJumpSubroutineEPNS_10RegisterIDEPNS_5LabelE
+__ZN3WTF6VectorIN3JSC3JIT7JSRInfoELm0EE14expandCapacityEm
+__ZN3JSC18RegExpMatchesArray16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC28createUndefinedVariableErrorEPNS_9ExecStateERKNS_10IdentifierEjPNS_9CodeBlockE
+__ZN3JSC17DeleteResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSCL21stringProtoFuncSearchEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL27objectProtoFuncDefineGetterEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
+__ZN3JSC9Structure22getterSetterTransitionEPS0_
+__ZN3JSCL27objectProtoFuncLookupGetterEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE
+__ZNK3JSC6JSCell14isGetterSetterEv
+__ZN3JSCL27objectProtoFuncLookupSetterEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC10JSFunction12lengthGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL27objectProtoFuncDefineSetterEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
+__ZNK3JSC12GetterSetter14isGetterSetterEv
+__ZN3JSC12GetterSetter4markEv
+__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj
+__ZN3JSC17BytecodeGenerator21emitComplexJumpScopesEPNS_5LabelEPNS_18ControlFlowContextES4_
+__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_10JSValuePtrE
+__ZN3JSC12PropertySlot14functionGetterEPNS_9ExecStateERKNS_10IdentifierERKS0_
+__ZN3JSC7JSArray4sortEPNS_9ExecStateE
+__ZN3JSC7JSArray17compactForSortingEv
+__ZN3JSCL24booleanProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC8VoidNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC8VoidNodeD1Ev
+__ZN3JSC8VoidNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSCL27compareByStringPairForQSortEPKvS1_
+__ZN3JSC6Parser7reparseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPS5_
+__ZN3JSC8EvalNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm0EEERKNS_10SourceCodeEji
+__ZN3JSC8EvalNode31bytecodeForExceptionInfoReparseEPNS_14ScopeChainNodeEPNS_9CodeBlockE
+__ZN3JSC17NumberConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithNumberConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZNK3JSC8JSObject16isVariableObjectEv
+__ZN3JSC36constructBooleanFromImmediateBooleanEPNS_9ExecStateENS_10JSValuePtrE
+__ZN3JSC13BooleanObjectD0Ev
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_14OffsetLocationEENS_18PairFirstExtractorIS8_EENS_7StrHashIS5_EENS_14PairHashTraitsINS_10HashTraitsIS5_EENSE_IS7_EEEESF_E4findIPS4_NS_29RefPtrHashMapRawKeyTranslatorISK_S8_SH_SC_EEEENS_17HashTableIteratorIS5_S8_SA_SC_SH_SF_EERKT_
+__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
+__ZN3JSC14globalFuncEvalEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter7executeEPNS_8EvalNodeEPNS_9ExecStateEPNS_8JSObjectEPNS_14ScopeChainNodeEPNS_10JSValuePtrE
+__ZN3JSC11Interpreter19cti_op_put_by_indexEPvz
+__ZN3JSCL25numberConstructorMaxValueEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL28numberConstructorPosInfinityEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL28numberConstructorNegInfinityEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL17mathProtoFuncATanEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC18RegExpMatchesArray14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC18EmptyStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSCL17mathProtoFuncASinEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL18mathProtoFuncATan2EPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC16ErrorConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL20callErrorConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL7dateNowEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC18BooleanConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL22callBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL20arrayProtoFuncFilterEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC4WREC9Generator28generateParenthesesAssertionERNS_14MacroAssembler8JumpListE
+__ZN3JSCL21regExpObjectLastIndexEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL18arrayProtoFuncSomeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC12RegExpObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSCL24setRegExpObjectLastIndexEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrE
+__ZN3JSC26createNotAConstructorErrorEPNS_9ExecStateENS_10JSValuePtrEjPNS_9CodeBlockE
+__ZN3JSC15isStrWhiteSpaceEt
+__ZN3JSCL27dateProtoFuncGetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncGetUTCMonthEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL23dateProtoFuncGetUTCDateEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncGetUTCHoursEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL26dateProtoFuncGetUTCMinutesEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL7dateUTCEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL21dateProtoFuncSetHoursEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL23setNewValueFromTimeArgsEPNS_9ExecStateENS_10JSValuePtrERKNS_7ArgListEib
+__ZN3JSCL23dateProtoFuncSetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL23dateProtoFuncSetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL28dateProtoFuncSetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC7CStringaSERKS0_
+__ZN3JSCL22dateProtoFuncGetUTCDayEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC7UString8toUInt32EPb
+__ZN3JSC12RegExpObject11getCallDataERNS_8CallDataE
+__ZNK3JSC8JSObject14isGlobalObjectEv
+__ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_10JSValuePtrE
+__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
+__ZN3JSC16JSVariableObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC17BytecodeGenerator18emitUnexpectedLoadEPNS_10RegisterIDEb
+__ZN3WTF6VectorIN3JSC10JSValuePtrELm0EE14expandCapacityEm
+__ZN3JSC18BooleanConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL31constructWithBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC16constructBooleanEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSCL26stringFromCharCodeSlowCaseEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSCL27dateProtoFuncSetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL26dateProtoFuncGetUTCSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL31dateProtoFuncGetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL28dateProtoFuncGetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC12JSNumberCell9getUInt32ERj
+__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSCL23booleanProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL27dateProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC9Arguments14deletePropertyEPNS_9ExecStateEj
+__ZNK3JSC21UStringSourceProvider8getRangeEii
+__ZN3JSC22NativeErrorConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL23dateProtoFuncSetUTCDateEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+JSClassCreate
__ZN13OpaqueJSClass6createEPK17JSClassDefinition
__ZN13OpaqueJSClassC2EPK17JSClassDefinitionPS_
-_JSClassRetain
-_JSObjectMake
-__ZN13OpaqueJSClass9prototypeEPK15OpaqueJSContext
-__ZN3KJS16JSCallbackObjectINS_8JSObjectEE4initEPNS_9ExecStateE
-_JSStringCreateWithUTF8CString
-_JSObjectSetProperty
-_JSStringRelease
-__Z30makeGetterOrSetterPropertyNodeRKN3KJS10IdentifierES2_PNS_13ParameterNodeEPNS_16FunctionBodyNodeE
-__ZN3KJS8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
-__ZN3KJS8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
-__ZNK3KJS15GetterSetterImp4typeEv
-__ZNK3KJS8JSObject6canPutEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3KJS13ConstDeclNodeC1ERKNS_10IdentifierEPNS_14ExpressionNodeE
-__Z26appendToVarDeclarationListRPN3KJS20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEEEPNS_13ConstDeclNodeE
-__ZN3KJS18ConstStatementNodeC1EPNS_13ConstDeclNodeE
-__ZN3KJS16JSCallbackObjectINS_8JSObjectEE18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3KJS16JSCallbackObjectINS_8JSObjectEE20staticFunctionGetterEPNS_9ExecStateEPS1_RKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3KJS18JSCallbackFunctionC1EPNS_9ExecStateEPFPK13OpaqueJSValuePK15OpaqueJSContextPS3_S9_mPKS5_PS5_ERKNS_10IdentifierE
-__ZN3KJS18JSCallbackFunction14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-_JSObjectGetPrivate
-__ZNK3KJS16JSCallbackObjectINS_8JSObjectEE9classInfoEv
-_JSStringCreateWithCharacters
-_JSValueMakeString
-__ZN3KJS12PropertySlot14functionGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERKS0_
-__ZN3WTF10fastCallocEmm
-_JSObjectGetProperty
-_JSValueToObject
-_JSValueProtect
-_JSObjectCallAsFunction
-_JSValueMakeNumber
-_JSValueMakeBoolean
-_JSObjectCallAsConstructor
-__ZN3KJS15GetterSetterImp4markEv
-_JSValueMakeUndefined
-_JSValueUnprotect
-_JSValueIsNumber
-_JSValueToNumber
-__ZN3KJS16JSCallbackObjectINS_8JSObjectEED0Ev
-__Z25clearReferenceToPrototypeP13OpaqueJSValue
-_JSClassRelease
-_JSStringIsEqualToUTF8CString
-_JSStringIsEqual
-__ZN3KJSeqERKNS_7UStringES2_
-__ZN3KJS16JSCallbackObjectINS_8JSObjectEE14callbackGetterEPNS_9ExecStateEPS1_RKNS_10IdentifierERKNS_12PropertySlotE
-_JSStringCreateWithCFString
-__ZN3KJS7UStringC2EPNS_5UCharEib
-__ZN3KJS16JSCallbackObjectINS_8JSObjectEE3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueEi
-_JSObjectSetPrivate
-__ZN3KJS15GetterSetterImpD0Ev
-__ZN3KJS27objectProtoFuncLookupGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS17PreIncResolveNode10precedenceEv
-__ZNK3KJS10SwitchNode8streamToERNS_12SourceStreamE
-__ZNK3KJS13CaseBlockNode8streamToERNS_12SourceStreamE
-__ZNK3KJS14CaseClauseNode8streamToERNS_12SourceStreamE
-__ZN3KJS18ConstStatementNodeD1Ev
-__ZN3KJS17PreDecBracketNodeD1Ev
-__ZN3KJS11Interpreter24setShouldPrintExceptionsEb
-__ZN3KJS9Collector26protectedGlobalObjectCountEv
-__ZN3KJS9Collector4sizeEv
-__ZN3KJS9Collector17globalObjectCountEv
-__ZN3KJS9Collector20protectedObjectCountEv
-__ZN3KJS9Collector25protectedObjectTypeCountsEv
-__ZNK3KJS15NumberObjectImp9classInfoEv
-__ZNK3KJS15RegExpPrototype9classInfoEv
-__ZNK3KJS15RegExpObjectImp9classInfoEv
-__ZNK3KJS14NativeErrorImp9classInfoEv
-__ZNK3KJS13MathObjectImp9classInfoEv
-__ZN3WTF6VectorIPN3KJS7JSValueELm8EE14expandCapacityEmPKS3_
-__ZN3WTF6VectorIPN3KJS7JSValueELm8EE14expandCapacityEm
-__ZN3KJS15ConditionalNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS9Arguments14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZNK3KJS17DeleteBracketNode8streamToERNS_12SourceStreamE
-__ZNK3KJS9BitOrNode10precedenceEv
-__ZNK3KJS9BitOrNode8streamToERNS_12SourceStreamE
-__ZNK3KJS7ModNode10precedenceEv
-__ZNK3KJS7ModNode8streamToERNS_12SourceStreamE
-__ZN3KJS31dateProtoFuncToLocaleTimeStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS16formatLocaleDateEPNS_9ExecStateEdbbRKNS_4ListE
-__ZN3KJS31dateProtoFuncToLocaleDateStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS9BitOrNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS7DivNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS14BitwiseNotNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS13ActivationImp14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3KJS27objectProtoFuncDefineGetterEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS17PreDecBracketNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS16BooleanObjectImp19implementsConstructEv
-__ZN3KJS27objectProtoFuncDefineSetterEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPPNS_7JSValueE
-__ZN3KJS10StringNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS13UnaryPlusNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS31dateProtoFuncGetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS17FunctionObjectImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS15DeleteValueNodeD1Ev
-__ZN3KJS15RegExpObjectImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS22dateProtoFuncGetUTCDayEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS8MultNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS4Node18setErrorCompletionEPNS_9ExecStateENS_9ErrorTypeEPKc
-__ZN3KJS10StringNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS27dateProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS22UnsignedRightShiftNode16evaluateToNumberEPNS_9ExecStateE
-__ZNK3KJS18PostIncResolveNode10precedenceEv
-__ZNK3KJS21ReadModifyResolveNode10precedenceEv
-__ZNK3KJS21FunctionCallValueNode10precedenceEv
-__ZN3KJS4Node15handleExceptionEPNS_9ExecStateE
-__ZNK3KJS13UnaryPlusNode10precedenceEv
-__ZNK3KJS13UnaryPlusNode8streamToERNS_12SourceStreamE
-__ZN3KJS4Node10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKcPNS_7JSValueERKNS_10IdentifierE
-__ZNK3KJS15DotAccessorNode17isDotAccessorNodeEv
-__ZNK3KJS14PostfixDotNode10precedenceEv
-__ZN3KJS23regExpProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS14PostDecDotNode8streamToERNS_12SourceStreamE
-__ZNK3KJS9CommaNode10precedenceEv
-__ZNK3KJS17ReadModifyDotNode10precedenceEv
-__ZNK3KJS13DeleteDotNode8streamToERNS_12SourceStreamE
-__ZNK3KJS19PlaceholderTrueNode8streamToERNS_12SourceStreamE
-__ZNK3KJS17AssignBracketNode10precedenceEv
-__ZNK3KJS8WithNode8streamToERNS_12SourceStreamE
-__ZNK3KJS17DeleteBracketNode10precedenceEv
-__ZN3KJS15ObjectObjectImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-_KJS_JSCreateNativeJSObject
-__ZN3KJS8Bindings12JavaJSObject6invokeEPNS0_19JSObjectCallContextE
-__ZN3KJS8Bindings12JavaJSObject12createNativeEx
-__ZN3KJS8Bindings24findProtectingRootObjectEPNS_8JSObjectE
-_KJS_JSObject_JSObjectEval
-__ZN3KJS8Bindings12JavaJSObjectC1Ex
-__ZNK3KJS8Bindings12JavaJSObject4evalEP8_jstring
-__ZN3KJS8Bindings9getJNIEnvEv
-__ZN3KJS8Bindings9getJavaVMEv
-__ZN3KJS8Bindings30getUCharactersFromJStringInEnvEP7JNIEnv_P8_jstring
-__ZN3KJS8Bindings33releaseUCharactersForJStringInEnvEP7JNIEnv_P8_jstringPKt
-__ZNK3KJS8Bindings12JavaJSObject21convertValueToJObjectEPNS_7JSValueE
-__ZN7JNIEnv_9NewObjectEP7_jclassP10_jmethodIDz
-_KJS_JSObject_JSFinalize
-__ZN3KJS19stringProtoFuncBoldEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS15RegExpObjectImp15getRightContextEv
-__ZNK3KJS15RegExpObjectImp14getLeftContextEv
-__ZN3KJS13LeftShiftNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS7ModNode15evaluateToInt32EPNS_9ExecStateE
-__ZNK3KJS18PostDecResolveNode10precedenceEv
-__ZN3KJS28dateProtoFuncSetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS32stringProtoFuncToLocaleLowerCaseEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__NPN_SetException
-__ZN3KJS18mathProtoFuncATan2EPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS8Bindings12JavaInstanceC2EP8_jobjectN3WTF10PassRefPtrINS0_10RootObjectEEE
-__ZN3KJS8Bindings12JavaInstance5beginEv
-__ZNK3KJS8Bindings12JavaInstance8getClassEv
-__ZN3KJS8Bindings9JavaClassC2EP8_jobject
-__ZN3KJS8Bindings19callJNIObjectMethodEP8_jobjectPKcS4_z
-__ZN3KJS8Bindings13callJNIMethodE7JNITypeP8_jobjectPKcS5_Pc
-__ZN3KJS8Bindings24getCharactersFromJStringEP8_jstring
-__ZN3KJS8Bindings27releaseCharactersForJStringEP8_jstringPKc
-__ZN3KJS8Bindings9JavaFieldC2EP7JNIEnv_P8_jobject
-__ZN3KJS7CStringaSERKS0_
-__ZN3KJS8Bindings20JNITypeFromClassNameEPKc
-__ZN3KJS8Bindings14JObjectWrapperC1EP8_jobject
-__ZNK3KJS8Bindings9JavaField4nameEv
-__ZN3KJS8Bindings10JavaMethodC2EP7JNIEnv_P8_jobject
-__ZN3KJS8Bindings16callJNIIntMethodEP8_jobjectPKcS4_z
-__ZN3KJS8Bindings26callJNIStaticBooleanMethodEP7_jclassPKcS4_z
-__ZN3KJS8Bindings19callJNIStaticMethodE7JNITypeP7_jclassPKcS5_Pc
-__ZNK3KJS8Bindings10JavaMethod4nameEv
-__ZN3KJS8Bindings13JavaParameterC2EP7JNIEnv_P8_jstring
-__ZNK3KJS8Bindings9JavaClass10fieldNamedERKNS_10IdentifierEPNS0_8InstanceE
-__ZNK3KJS8Bindings9JavaClass12methodsNamedERKNS_10IdentifierEPNS0_8InstanceE
-__ZN3KJS8Bindings12JavaInstance3endEv
-__ZN3KJS8Bindings12JavaInstanceD1Ev
-__ZN3KJS8Bindings9JavaClassD1Ev
-__ZN3WTF20deleteAllPairSecondsIPN3KJS8Bindings5FieldEKNS_7HashMapINS_6RefPtrINS1_7UString3RepEEES4_NS_7PtrHashIS9_EENS_10HashTraitsIS9_EENSC_IS4_EEEEEEvRT0_
-__ZN3KJS8Bindings14JObjectWrapperD1Ev
-__ZN3KJS35objectProtoFuncPropertyIsEnumerableEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS31dateProtoFuncSetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS12FuncExprNode21needsParensIfLeftmostEv
-__ZN3KJS13DateObjectImp14callAsFunctionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS11NewExprNode17evaluateToBooleanEPNS_9ExecStateE
-__ZN3KJS29numberProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS25dateProtoFuncToDateStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS9BitOrNode16evaluateToNumberEPNS_9ExecStateE
-__ZNK3KJS7JSValue8toUInt32EPNS_9ExecStateE
-__ZNK3KJS8JSObject3getEPNS_9ExecStateEj
-__ZNK3KJS7JSValue16toUInt32SlowCaseEPNS_9ExecStateERb
-__ZN3KJS9Collector29markOtherThreadConservativelyEPNS0_6ThreadE
-__ZN3WTF20TCMalloc_ThreadCache18DestroyThreadCacheEPv
-__ZN3WTF20TCMalloc_ThreadCache11DeleteCacheEPS0_
-__ZN3KJS23destroyRegisteredThreadEPv
-__ZN3KJS28numberProtoFuncToExponentialEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS26numberProtoFuncToPrecisionEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS15RegExpObjectImp16putValuePropertyEPNS_9ExecStateEiPNS_7JSValueEi
-__ZNK3KJS15RegExpObjectImp12getLastParenEv
-__ZN3KJS10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
-__ZN3KJS18arrayProtoFuncSomeEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS9LabelNode9pushLabelERKNS_10IdentifierE
-__ZN3KJS9Collector32reportOutOfMemoryToAllExecStatesEv
-__ZN3KJS5Error6createEPNS_9ExecStateENS_9ErrorTypeEPKc
-__ZNK3KJS17PreDecResolveNode10precedenceEv
-__ZN3KJS17mathProtoFuncACosEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS16mathProtoFuncTanEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS16PostfixErrorNode8streamToERNS_12SourceStreamE
-__ZNK3KJS15PrefixErrorNode8streamToERNS_12SourceStreamE
-__ZNK3KJS15AssignErrorNode8streamToERNS_12SourceStreamE
-__ZN3KJS16PostfixErrorNode8evaluateEPNS_9ExecStateE
-__ZN3KJS4Node10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKcS5_
-__ZN3KJS16PostfixErrorNodeD1Ev
-__ZNK3KJS13LeftShiftNode8streamToERNS_12SourceStreamE
-__ZNK3KJS13LeftShiftNode10precedenceEv
-__ZNK3KJS14RightShiftNode8streamToERNS_12SourceStreamE
-__ZNK3KJS14RightShiftNode10precedenceEv
-__ZNK3KJS22UnsignedRightShiftNode8streamToERNS_12SourceStreamE
-__ZNK3KJS22UnsignedRightShiftNode10precedenceEv
-__ZNK3KJS10BitAndNode8streamToERNS_12SourceStreamE
-__ZNK3KJS10BitAndNode10precedenceEv
-__ZNK3KJS10BitXOrNode8streamToERNS_12SourceStreamE
-__ZNK3KJS10BitXOrNode10precedenceEv
-__ZN3KJS15AssignErrorNode8evaluateEPNS_9ExecStateE
-__ZN3KJS4Node10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
-__ZN3KJS13char_sequenceEci
-__ZN3KJS15LessStringsNode8evaluateEPNS_9ExecStateE
-__ZN3KJS15LessStringsNodeD1Ev
-__ZN3KJS15DeleteValueNode8evaluateEPNS_9ExecStateE
-__ZN3KJS22regExpProtoFuncCompileEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS15PrefixErrorNode8evaluateEPNS_9ExecStateE
-__ZN3KJS28objectProtoFuncIsPrototypeOfEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS15PrefixErrorNodeD1Ev
-__ZN3KJS19arrayProtoFuncEveryEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS29objectProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS25arrayProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3WTF6VectorItLm0EE6resizeEm
-__ZN3WTF6VectorItLm0EE14expandCapacityEm
-__ZN3WTF6VectorItLm0EE15reserveCapacityEm
-__ZN3KJS28arrayProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS18ConstStatementNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS13ConstDeclNode22optimizeVariableAccessERKN3WTF7HashMapINS1_6RefPtrINS_7UString3RepEEEmNS_17IdentifierRepHashENS_23IdentifierRepHashTraitsENS_26SymbolTableIndexHashTraitsEEERKNS1_6VectorINS_17LocalStorageEntryELm32EEERNSD_IPNS_4NodeELm16EEE
-__ZN3KJS18ConstStatementNode7executeEPNS_9ExecStateE
-__ZN3KJS13ConstDeclNode8evaluateEPNS_9ExecStateE
-__ZN3KJS15AssignConstNode8evaluateEPNS_9ExecStateE
-__ZN3KJS16PostIncConstNode8evaluateEPNS_9ExecStateE
-__ZN3KJS16PostDecConstNode8evaluateEPNS_9ExecStateE
-__ZN3KJS15PreIncConstNode8evaluateEPNS_9ExecStateE
-__ZN3KJS15PreDecConstNode8evaluateEPNS_9ExecStateE
-__ZN3KJS19ReadModifyConstNode8evaluateEPNS_9ExecStateE
-__ZNK3KJS13ActivationImp9classInfoEv
-__ZN3KJS16PostIncConstNodeD1Ev
-__ZN3KJS15PreIncConstNodeD1Ev
-__ZN3KJS15PreDecConstNodeD1Ev
-__ZNK3KJS13DeleteDotNode10precedenceEv
-__ZN3KJS28stringProtoFuncLocaleCompareEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZN3KJS10NumberNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS19FunctionCallDotNode16evaluateToUInt32EPNS_9ExecStateE
-__ZNK3KJS21ReadModifyBracketNode8streamToERNS_12SourceStreamE
-__ZN3KJS10BitXOrNode16evaluateToNumberEPNS_9ExecStateE
-___tcf_1
-__ZNK3KJS7UString6is8BitEv
-__ZN3KJS15DotAccessorNode16evaluateToUInt32EPNS_9ExecStateE
-__ZN3KJS24stringProtoFuncFontcolorEPNS_9ExecStateEPNS_8JSObjectERKNS_4ListE
-__ZNK3KJS14NativeErrorImp19implementsConstructEv
-__ZN3KJS19PostDecLocalVarNode16evaluateToNumberEPNS_9ExecStateE
-__ZN3KJS19PostDecLocalVarNode15evaluateToInt32EPNS_9ExecStateE
-__ZN3KJS13UnaryPlusNode17evaluateToBooleanEPNS_9ExecStateE
+__ZN3JSC7UString3Rep14createFromUTF8EPKc
+__ZN3WTF7Unicode18convertUTF8ToUTF16EPPKcS2_PPtS4_b
+__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEEP19StaticFunctionEntryNS_7StrHashIS5_EENS_10HashTraitsIS5_EENSA_IS7_EEE3addERKS5_RKS7_
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_P19StaticFunctionEntryENS_18PairFirstExtractorIS9_EENS_7StrHashIS5_EENS_14PairHashTraitsINS_10HashTraitsIS5_EENSF_IS8_EEEESG_E6expandEv
+JSClassRetain
+JSObjectMake
+__ZN3JSC4Heap14registerThreadEv
+__ZN3JSC6JSLockC1EPNS_9ExecStateE
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE4initEPNS_9ExecStateE
+__ZN13OpaqueJSClass9prototypeEPN3JSC9ExecStateE
+__ZN13OpaqueJSClass11contextDataEPN3JSC9ExecStateE
+__ZN3WTF9HashTableIP13OpaqueJSClassSt4pairIS2_P24OpaqueJSClassContextDataENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS5_EEEESD_E6expandEv
+__ZN24OpaqueJSClassContextDataC2EP13OpaqueJSClass
+JSStringCreateWithCFString
+JSObjectSetProperty
+__ZNK14OpaqueJSString10identifierEPN3JSC12JSGlobalDataE
+JSStringRelease
+__ZL30makeGetterOrSetterPropertyNodePvRKN3JSC10IdentifierES3_PNS0_13ParameterNodeEPNS0_16FunctionBodyNodeERKNS0_10SourceCodeE
+__ZN3JSC18ConstStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13ConstDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13ConstDeclNode14emitCodeSingleERNS_17BytecodeGeneratorE
+__ZN3JSC17BytecodeGenerator13emitPutGetterEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3JSC17BytecodeGenerator13emitPutSetterEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3JSC18ConstStatementNodeD1Ev
+__ZN3JSC18ConstStatementNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC13ConstDeclNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC11Interpreter17cti_op_put_getterEPvz
+__ZN3JSC11Interpreter17cti_op_put_setterEPvz
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC7UString3Rep13createCopyingEPKti
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE20staticFunctionGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC18JSCallbackFunctionC1EPNS_9ExecStateEPFPK13OpaqueJSValuePK15OpaqueJSContextPS3_S9_mPKS5_PS5_ERKNS_10IdentifierE
+__ZN3JSC18JSCallbackFunction11getCallDataERNS_8CallDataE
+__ZN3JSC18JSCallbackFunction4callEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE
+JSValueIsObjectOfClass
+__ZN3JSC6JSCell9getObjectEv
+__ZNK3JSC16JSCallbackObjectINS_8JSObjectEE9classInfoEv
+JSObjectGetPrivate
+JSValueMakeString
+__ZNK14OpaqueJSString7ustringEv
+JSValueMakeBoolean
+JSContextGetGlobalObject
+JSStringCreateWithUTF8CString
+JSObjectGetProperty
+JSValueToObject
+JSObjectIsFunction
+JSObjectCallAsFunction
+JSValueMakeUndefined
+__ZN3JSC18JSCallbackFunctionD0Ev
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEED0Ev
+__ZL25clearReferenceToPrototypeP13OpaqueJSValue
+JSClassRelease
+__ZN3JSC15AssignErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC23ThrowableExpressionData14emitThrowErrorERNS_17BytecodeGeneratorENS_9ErrorTypeEPKc
+__ZN3JSC17BytecodeGenerator12emitNewErrorEPNS_10RegisterIDENS_9ErrorTypeENS_10JSValuePtrE
+__ZN3JSC15AssignErrorNodeD1Ev
+__ZN3JSC15AssignErrorNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC12StringObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC9ExecState11stringTableEPS0_
+__ZN3JSCL24dateProtoFuncSetUTCHoursEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN14OpaqueJSString6createERKN3JSC7UStringE
+JSStringIsEqualToUTF8CString
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE14callbackGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+JSValueToStringCopy
+JSStringCopyCFString
+JSValueMakeNumber
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+JSValueToNumber
+JSObjectSetPrivate
+__ZN3JSC8Profiler8profilerEv
+__ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
+__ZN3JSC8JSObject15unwrappedObjectEv
+JSStringCreateWithCharacters
+__ZN3JSC9Structure18startIgnoringLeaksEv
+__ZN3JSC9Structure17stopIgnoringLeaksEv
+JSValueProtect
+JSObjectCallAsConstructor
+__ZN3JSC10JSFunction16getConstructDataERNS_13ConstructDataE
+__ZN3JSC9constructEPNS_9ExecStateENS_10JSValuePtrENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
+__ZN3JSC10JSFunction9constructEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSCL28stringProtoFuncLocaleCompareEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3WTF8Collator11userDefaultEv
+__ZNK3WTF8Collator7collateEPKtmS2_m
+__ZNK3WTF8Collator14createCollatorEv
+__ZN3WTF8CollatorD1Ev
+__ZN3WTF8Collator15releaseCollatorEv
+__ZNK3JSC22NativeErrorConstructor9classInfoEv
+JSValueUnprotect
+JSValueIsNumber
+__ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
+__ZN3WTF7HashSetIPN3JSC14JSGlobalObjectENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC14JSGlobalObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3JSC4Heap14primaryHeapEndEv
+__ZN3JSC4Heap16primaryHeapBeginEv
+__ZNK3JSC15RegExpPrototype9classInfoEv
+__ZNK3JSC17NumberConstructor9classInfoEv
+__ZNK3JSC17RegExpConstructor9classInfoEv
+__ZNK3JSC10MathObject9classInfoEv
+__ZNK3JSC18JSCallbackFunction9classInfoEv
+JSValueIsString
+JSStringGetLength
+JSStringGetCharactersPtr
+__ZN3JSC11Interpreter12cti_op_debugEPvz
+__ZN3JSC11Interpreter5debugEPNS_9ExecStateENS_11DebugHookIDEii
+__ZNK3JSC17DebuggerCallFrame4typeEv
+__ZNK3JSC17DebuggerCallFrame12functionNameEv
+__ZNK3JSC17DebuggerCallFrame10thisObjectEv
+__ZN3WTF28setMainThreadCallbacksPausedEb
+__ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
+__ZN3WTF9HashTableIPN3JSC14JSGlobalObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
+__ZN3WTF6VectorIN3JSC20FunctionRegisterInfoELm0EE14expandCapacityEm
+__ZN3JSC8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE
+__ZN3JSC16ProfileGenerator6createERKNS_7UStringEPNS_9ExecStateEj
+__ZN3JSC16ProfileGeneratorC2ERKNS_7UStringEPNS_9ExecStateEj
+__ZN3JSC7Profile6createERKNS_7UStringEj
+__ZN3JSC11TreeProfile6createERKNS_7UStringEj
+__ZN3JSC7ProfileC2ERKNS_7UStringEj
+__ZN3JSC11ProfileNodeC1ERKNS_14CallIdentifierEPS0_S4_
+__ZN3JSC33getCurrentUTCTimeWithMicrosecondsEv
+__ZN3JSC16ProfileGenerator24addParentForConsoleStartEPNS_9ExecStateE
+__ZN3JSC8Profiler20createCallIdentifierEPNS_12JSGlobalDataENS_10JSValuePtrERKNS_7UStringEi
+__ZN3JSC11ProfileNode10insertNodeEN3WTF10PassRefPtrIS0_EE
+__ZN3WTF6VectorINS_6RefPtrIN3JSC16ProfileGeneratorEEELm0EE14expandCapacityEm
+__ZN3WTF10RefCountedIN3JSC16ProfileGeneratorEE5derefEv
+__ZN3JSC8Profiler11willExecuteEPNS_9ExecStateENS_10JSValuePtrE
+__ZN3JSC8Profiler10didExecuteEPNS_9ExecStateENS_10JSValuePtrE
+__ZN3JSC16ProfileGenerator11willExecuteERKNS_14CallIdentifierE
+__ZN3JSC11ProfileNode11willExecuteERKNS_14CallIdentifierE
+__ZN3JSC11Interpreter24cti_op_profile_will_callEPvz
+__ZN3JSC11Interpreter23cti_op_profile_did_callEPvz
+__ZN3JSC16ProfileGenerator10didExecuteERKNS_14CallIdentifierE
+__ZN3JSC11ProfileNode10didExecuteEv
+__ZN3JSCL28numberProtoFuncToExponentialEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL26numberProtoFuncToPrecisionEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter16cti_op_new_errorEPvz
+__ZN3JSC19JSStaticScopeObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC4WREC14CharacterClass11nonwordcharEv
+__ZN3JSC19FunctionConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL23callFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC17ObjectConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callObjectConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC12JSActivation14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSCL26dateProtoFuncSetUTCMinutesEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL26dateProtoFuncSetUTCSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC15PrefixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15PrefixErrorNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC15PrefixErrorNodeD1Ev
+__ZN3JSCL19stringProtoFuncBoldEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm512EEELm32EE15reserveCapacityEm
+__ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7UStringE
+__ZN3JSCL24regExpConstructorDollar5EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
+__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+JSValueIsEqual
+__ZN3JSC10JSValuePtr13equalSlowCaseEPNS_9ExecStateES0_S0_
+__ZN3JSCL16mathProtoFuncTanEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC11Interpreter15cti_op_post_decEPvz
+__ZN3JSCL28regExpConstructorLeftContextEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL31dateProtoFuncToLocaleDateStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC21DebuggerStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC21DebuggerStatementNodeD1Ev
+__ZN3JSCL12charSequenceEci
+__ZN3JSCL17mathProtoFuncACosEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC4Heap24setGCProtectNeedsLockingEv
+__ZNK3JSC7UString6is8BitEv
+__ZN3WTF9ByteArray6createEm
+__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
+__ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC11Interpreter28cti_op_get_by_val_byte_arrayEPvz
+__ZN3JSC11JSByteArray3putEPNS_9ExecStateEjNS_10JSValuePtrE
+__ZN3JSC11JSByteArray3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC11Interpreter28cti_op_put_by_val_byte_arrayEPvz
+__ZN3JSCL28objectProtoFuncIsPrototypeOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
+__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
+__ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL25numberConstructorNaNValueEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL23throwStackOverflowErrorEPNS_9ExecStateEPNS_12JSGlobalDataEPvRS4_
+__ZN3JSCL24regExpConstructorDollar6EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar7EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC9ExecState9mathTableEPS0_
+__ZN3JSC9ExecState22regExpConstructorTableEPS0_
+__ZN3JSCL24regExpConstructorDollar8EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar9EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL22regExpConstructorInputEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL25setRegExpConstructorInputEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrE
+__ZN3JSCL26regExpConstructorLastMatchEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL26regExpConstructorLastParenEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL26regExpConstructorMultilineEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL29setRegExpConstructorMultilineEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrE
+__ZN3JSCL29regExpConstructorRightContextEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC16PostfixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC16PostfixErrorNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC16PostfixErrorNodeD1Ev
+__ZN3JSC6JSCell11getJSNumberEv
+__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrEj
+__ZN3JSCL25arrayProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL25numberConstructorMinValueEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL22regExpProtoFuncCompileEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL19arrayProtoFuncEveryEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL29objectProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC6JSCell14toThisJSStringEPNS_9ExecStateE
+__ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE
+__ZN3JSCL31dateProtoFuncSetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncSetUTCMonthEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL28arrayProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC12JSActivation18getArgumentsGetterEv
+__ZN3JSC12JSActivation15argumentsGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC9ExecState9dateTableEPS0_
+__ZN3JSC23createInvalidParamErrorEPNS_9ExecStateEPKcNS_10JSValuePtrEjPNS_9CodeBlockE
+__ZNK3JSC15DotAccessorNode17isDotAccessorNodeEv
+__ZNK3JSC14ExpressionNode17isDotAccessorNodeEv
+__ZN3JSC13JSNotAnObject3putEPNS_9ExecStateEjNS_10JSValuePtrE
+__ZN3JSC15DeleteValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15DeleteValueNodeD1Ev
+__ZN3JSC15DeleteValueNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC17BytecodeGenerator18emitUnexpectedLoadEPNS_10RegisterIDEd
+__ZN3JSC4WREC14CharacterClass9nondigitsEv
+__ZNK3JSC19JSStaticScopeObject12toThisObjectEPNS_9ExecStateE
+__ZNK3JSC16JSVariableObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
+__ZN3JSCL25dateProtoFuncToDateStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL25dateProtoFuncToTimeStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC17BytecodeGenerator35emitThrowExpressionTooDeepExceptionEv
+__ZN3JSC12JSGlobalData6createEv
+__ZN3WTF12isMainThreadEv
+__ZN3JSC4Heap7destroyEv
+__ZN3JSC12JSGlobalDataD1Ev
+__ZN3JSC11InterpreterD1Ev
+__ZN3JSC12RegisterFileD1Ev
+__ZNK3JSC9HashTable11deleteTableEv
+__ZN3JSC5LexerD1Ev
+__ZN3WTF20deleteAllPairSecondsIP24OpaqueJSClassContextDataKNS_7HashMapIP13OpaqueJSClassS2_NS_7PtrHashIS5_EENS_10HashTraitsIS5_EENS8_IS2_EEEEEEvRT0_
+__ZN3JSC17CommonIdentifiersD2Ev
+__ZN3JSC21deleteIdentifierTableEPNS_15IdentifierTableE
+__ZN3JSC4HeapD1Ev
+__ZN3JSC12SmallStringsD1Ev
+__ZN3JSC12JSGlobalData10ClientDataD2Ev
+__ZN3WTF8CollatorC1EPKc
+__ZN3WTF8Collator18setOrderLowerFirstEb
+__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
+__ZNK3JSC25InterruptedExecutionError19isWatchdogExceptionEv
diff --git a/JavaScriptCore/JavaScriptCore.pri b/JavaScriptCore/JavaScriptCore.pri
index 22dcbb1..6aee0aa 100644
--- a/JavaScriptCore/JavaScriptCore.pri
+++ b/JavaScriptCore/JavaScriptCore.pri
@@ -2,15 +2,30 @@
VPATH += $$PWD
INCLUDEPATH += tmp
-INCLUDEPATH += $$PWD $$PWD/kjs $$PWD/debugger $$PWD/runtime $$PWD/wtf $$PWD/wtf/unicode $$PWD/VM $$PWD/profiler $$PWD/API $$PWD/.. \
- $$PWD/ForwardingHeaders
+INCLUDEPATH += $$PWD $$PWD/parser $$PWD/bytecompiler $$PWD/debugger $$PWD/runtime $$PWD/wtf $$PWD/wtf/unicode $$PWD/interpreter $$PWD/jit $$PWD/profiler $$PWD/wrec $$PWD/API $$PWD/.. \
+ $$PWD/ForwardingHeaders $$PWD/bytecode $$PWD/assembler
DEFINES += BUILDING_QT__
isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = tmp
GENERATED_SOURCES_DIR_SLASH = $$GENERATED_SOURCES_DIR/
-win32-*: GENERATED_SOURCES_DIR_SLASH ~= s|/|\|
-win32-g++: LIBS += -lwinmm
+win32-* {
+ GENERATED_SOURCES_DIR_SLASH ~= s|/|\|
+ LIBS += -lwinmm
+}
+# Disable the JIT due to numerous observed miscompilations :(
+#CONFIG(release):isEqual(QT_ARCH,i386) {
+# JIT_DEFINES = ENABLE_JIT ENABLE_WREC ENABLE_JIT_OPTIMIZE_CALL ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS ENABLE_JIT_OPTIMIZE_ARITHMETIC
+# # gcc <= 4.1 is known to miscompile, so require >= 4.2, written as major > 3 and minor > 1
+# linux-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,1) {
+# DEFINES += $$JIT_DEFINES
+# SOURCES += wtf/TCSystemAlloc.cpp
+# DEFINES -= USE_SYSTEM_MALLOC
+# }
+# win32-msvc* {
+# DEFINES += $$JIT_DEFINES
+# }
+#}
include(pcre/pcre.pri)
@@ -24,15 +39,17 @@ LUT_FILES += \
runtime/RegExpObject.cpp
KEYWORDLUT_FILES += \
- kjs/keywords.table
+ parser/Keywords.table
-KJSBISON += \
- kjs/grammar.y
+JSCBISON += \
+ parser/Grammar.y
SOURCES += \
wtf/Assertions.cpp \
+ wtf/ByteArray.cpp \
wtf/HashTable.cpp \
wtf/MainThread.cpp \
+ wtf/RandomNumber.cpp \
wtf/RefCountedLeakCounter.cpp \
wtf/unicode/CollatorDefault.cpp \
wtf/unicode/icu/CollatorICU.cpp \
@@ -54,14 +71,30 @@ SOURCES += \
runtime/JSVariableObject.cpp \
runtime/JSActivation.cpp \
runtime/JSNotAnObject.cpp \
- VM/CodeBlock.cpp \
- VM/CodeGenerator.cpp \
- VM/ExceptionHelpers.cpp \
+ bytecode/CodeBlock.cpp \
+ bytecode/StructureStubInfo.cpp \
+ bytecode/JumpTable.cpp \
+ jit/JIT.cpp \
+ jit/JITCall.cpp \
+ jit/JITArithmetic.cpp \
+ jit/JITPropertyAccess.cpp \
+ jit/ExecutableAllocator.cpp \
+ bytecompiler/BytecodeGenerator.cpp \
+ runtime/ExceptionHelpers.cpp \
runtime/JSPropertyNameIterator.cpp \
- VM/Machine.cpp \
- VM/Opcode.cpp \
- VM/SamplingTool.cpp \
- VM/RegisterFile.cpp
+ interpreter/Interpreter.cpp \
+ bytecode/Opcode.cpp \
+ bytecode/SamplingTool.cpp \
+ wrec/CharacterClass.cpp \
+ wrec/CharacterClassConstructor.cpp \
+ wrec/WREC.cpp \
+ wrec/WRECFunctors.cpp \
+ wrec/WRECGenerator.cpp \
+ wrec/WRECParser.cpp \
+ interpreter/RegisterFile.cpp
+
+win32-*: SOURCES += jit/ExecutableAllocatorWin.cpp
+else: SOURCES += jit/ExecutableAllocatorPosix.cpp
# AllInOneFile.cpp helps gcc analize and optimize code
# Other compilers may be able to do this at link time
@@ -74,29 +107,32 @@ SOURCES += \
runtime/BooleanObject.cpp \
runtime/BooleanPrototype.cpp \
runtime/CallData.cpp \
- kjs/collector.cpp \
+ runtime/Collector.cpp \
runtime/CommonIdentifiers.cpp \
runtime/ConstructData.cpp \
+ wtf/CurrentTime.cpp \
runtime/DateConstructor.cpp \
runtime/DateInstance.cpp \
runtime/DateMath.cpp \
runtime/DatePrototype.cpp \
debugger/Debugger.cpp \
debugger/DebuggerCallFrame.cpp \
- kjs/dtoa.cpp \
+ debugger/DebuggerActivation.cpp \
+ wtf/dtoa.cpp \
runtime/Error.cpp \
runtime/ErrorConstructor.cpp \
runtime/ErrorInstance.cpp \
runtime/ErrorPrototype.cpp \
- runtime/ExecState.cpp \
+ interpreter/CallFrame.cpp \
runtime/FunctionConstructor.cpp \
runtime/FunctionPrototype.cpp \
runtime/GetterSetter.cpp \
runtime/GlobalEvalFunction.cpp \
- kjs/identifier.cpp \
+ runtime/Identifier.cpp \
runtime/InternalFunction.cpp \
- kjs/interpreter.cpp \
+ runtime/Completion.cpp \
runtime/JSArray.cpp \
+ runtime/JSByteArray.cpp \
runtime/JSCell.cpp \
runtime/JSFunction.cpp \
runtime/JSGlobalObjectFunctions.cpp \
@@ -107,24 +143,23 @@ SOURCES += \
runtime/JSString.cpp \
runtime/JSValue.cpp \
runtime/JSWrapperObject.cpp \
- kjs/lexer.cpp \
- kjs/lookup.cpp \
+ parser/Lexer.cpp \
+ runtime/Lookup.cpp \
runtime/MathObject.cpp \
runtime/NativeErrorConstructor.cpp \
runtime/NativeErrorPrototype.cpp \
- kjs/nodes.cpp \
- kjs/nodes2string.cpp \
+ parser/Nodes.cpp \
runtime/NumberConstructor.cpp \
runtime/NumberObject.cpp \
runtime/NumberPrototype.cpp \
runtime/ObjectConstructor.cpp \
runtime/ObjectPrototype.cpp \
- kjs/operations.cpp \
- kjs/Parser.cpp \
+ runtime/Operations.cpp \
+ parser/Parser.cpp \
runtime/PropertyNameArray.cpp \
runtime/PropertySlot.cpp \
runtime/PrototypeFunction.cpp \
- kjs/regexp.cpp \
+ runtime/RegExp.cpp \
runtime/RegExpConstructor.cpp \
runtime/RegExpObject.cpp \
runtime/RegExpPrototype.cpp \
@@ -133,9 +168,9 @@ SOURCES += \
runtime/StringConstructor.cpp \
runtime/StringObject.cpp \
runtime/StringPrototype.cpp \
- runtime/StructureID.cpp \
- runtime/StructureIDChain.cpp \
- kjs/ustring.cpp \
+ runtime/Structure.cpp \
+ runtime/StructureChain.cpp \
+ runtime/UString.cpp \
profiler/HeavyProfile.cpp \
profiler/Profile.cpp \
profiler/ProfileGenerator.cpp \
@@ -143,31 +178,33 @@ SOURCES += \
profiler/Profiler.cpp \
profiler/TreeProfile.cpp \
wtf/FastMalloc.cpp \
+ wtf/Threading.cpp \
wtf/ThreadingQt.cpp \
wtf/qt/MainThreadQt.cpp
# GENERATOR 1-A: LUT creator
lut.output = $$GENERATED_SOURCES_DIR/${QMAKE_FILE_BASE}.lut.h
-lut.commands = perl $$PWD/kjs/create_hash_table ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT}
+lut.commands = perl $$PWD/create_hash_table ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT}
lut.depend = ${QMAKE_FILE_NAME}
lut.input = LUT_FILES
lut.CONFIG += no_link
addExtraCompiler(lut)
# GENERATOR 1-B: particular LUT creator (for 1 file only)
-keywordlut.output = $$GENERATED_SOURCES_DIR/lexer.lut.h
-keywordlut.commands = perl $$PWD/kjs/create_hash_table ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT}
+keywordlut.output = $$GENERATED_SOURCES_DIR/Lexer.lut.h
+keywordlut.commands = perl $$PWD/create_hash_table ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT}
keywordlut.depend = ${QMAKE_FILE_NAME}
keywordlut.input = KEYWORDLUT_FILES
keywordlut.CONFIG += no_link
addExtraCompiler(keywordlut)
# GENERATOR 2: bison grammar
-kjsbison.output = $$GENERATED_SOURCES_DIR/${QMAKE_FILE_BASE}.cpp
-kjsbison.commands = bison -d -p kjsyy ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_BASE}.tab.c && $(MOVE) ${QMAKE_FILE_BASE}.tab.c ${QMAKE_FILE_OUT} && $(MOVE) ${QMAKE_FILE_BASE}.tab.h $$GENERATED_SOURCES_DIR/${QMAKE_FILE_BASE}.h
-kjsbison.depend = ${QMAKE_FILE_NAME}
-kjsbison.input = KJSBISON
-kjsbison.variable_out = GENERATED_SOURCES
-kjsbison.dependency_type = TYPE_C
-kjsbison.CONFIG = target_predeps
-addExtraCompilerWithHeader(kjsbison)
+jscbison.output = $$GENERATED_SOURCES_DIR/${QMAKE_FILE_BASE}.cpp
+jscbison.commands = bison -d -p jscyy ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_BASE}.tab.c && $(MOVE) ${QMAKE_FILE_BASE}.tab.c ${QMAKE_FILE_OUT} && $(MOVE) ${QMAKE_FILE_BASE}.tab.h $$GENERATED_SOURCES_DIR/${QMAKE_FILE_BASE}.h
+jscbison.depend = ${QMAKE_FILE_NAME}
+jscbison.input = JSCBISON
+jscbison.variable_out = GENERATED_SOURCES
+jscbison.dependency_type = TYPE_C
+jscbison.CONFIG = target_predeps
+addExtraCompilerWithHeader(jscbison)
+
diff --git a/JavaScriptCore/JavaScriptCore.pro b/JavaScriptCore/JavaScriptCore.pro
index 19fb0fd..56dae05 100644
--- a/JavaScriptCore/JavaScriptCore.pro
+++ b/JavaScriptCore/JavaScriptCore.pro
@@ -67,3 +67,6 @@ QMAKE_EXTRA_TARGETS += generated_files
qt-port: lessThan(QT_MINOR_VERSION, 4) {
DEFINES += QT_BEGIN_NAMESPACE="" QT_END_NAMESPACE=""
}
+
+*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2
+*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3
diff --git a/JavaScriptCore/JavaScriptCore.scons b/JavaScriptCore/JavaScriptCore.scons
new file mode 100644
index 0000000..24e5003
--- /dev/null
+++ b/JavaScriptCore/JavaScriptCore.scons
@@ -0,0 +1,307 @@
+# The keys in sources are the paths to the directories
+# the values are an array of source files in those directories to compile
+sources = {}
+sources['API'] = [
+ 'API/JSBase.cpp',
+ 'API/JSCallbackConstructor.cpp',
+ 'API/JSCallbackFunction.cpp',
+ 'API/JSCallbackObject.cpp',
+ 'API/JSClassRef.cpp',
+ 'API/JSContextRef.cpp',
+ 'API/JSObjectRef.cpp',
+ 'API/JSProfilerPrivate.cpp',
+ 'API/JSStringRef.cpp',
+ 'API/JSValueRef.cpp',
+ 'API/OpaqueJSString.cpp',
+]
+sources['bytecompiler'] = [
+ 'bytecompiler/BytecodeGenerator.cpp',
+]
+sources['debugger'] = [
+ 'debugger/Debugger.cpp',
+ 'debugger/DebuggerActivation.cpp',
+ 'debugger/DebuggerCallFrame.cpp',
+]
+sources['parser'] = [
+ 'parser/Lexer.cpp',
+ 'parser/Nodes.cpp',
+ 'parser/Parser.cpp',
+]
+sources['pcre'] = [
+ 'pcre/pcre_compile.cpp',
+ 'pcre/pcre_exec.cpp',
+ 'pcre/pcre_tables.cpp',
+ 'pcre/pcre_ucp_searchfuncs.cpp',
+ 'pcre/pcre_xclass.cpp',
+]
+sources['profiler'] = [
+ 'profiler/HeavyProfile.cpp',
+ 'profiler/Profile.cpp',
+ 'profiler/ProfileGenerator.cpp',
+ 'profiler/ProfileNode.cpp',
+ 'profiler/Profiler.cpp',
+ 'profiler/TreeProfile.cpp',
+]
+sources['runtime'] = [
+ 'runtime/ArgList.cpp',
+ 'runtime/Arguments.cpp',
+ 'runtime/ArrayConstructor.cpp',
+ 'runtime/ArrayPrototype.cpp',
+ 'runtime/BooleanConstructor.cpp',
+ 'runtime/BooleanObject.cpp',
+ 'runtime/BooleanPrototype.cpp',
+ 'runtime/CallData.cpp',
+ 'runtime/Collector.cpp',
+ 'runtime/Completion.cpp',
+ 'runtime/CommonIdentifiers.cpp',
+ 'runtime/ConstructData.cpp',
+ 'runtime/DateConstructor.cpp',
+ 'runtime/DateInstance.cpp',
+ 'runtime/DateMath.cpp',
+ 'runtime/DatePrototype.cpp',
+ 'runtime/Error.cpp',
+ 'runtime/ErrorConstructor.cpp',
+ 'runtime/ErrorInstance.cpp',
+ 'runtime/ErrorPrototype.cpp',
+ 'runtime/ExceptionHelpers.cpp',
+ 'runtime/FunctionConstructor.cpp',
+ 'runtime/FunctionPrototype.cpp',
+ 'runtime/GetterSetter.cpp',
+ 'runtime/GlobalEvalFunction.cpp',
+ 'runtime/Identifier.cpp',
+ 'runtime/InitializeThreading.cpp',
+ 'runtime/InternalFunction.cpp',
+ 'runtime/JSActivation.cpp',
+ 'runtime/JSArray.cpp',
+ 'runtime/JSByteArray.cpp',
+ 'runtime/JSCell.cpp',
+ 'runtime/JSFunction.cpp',
+ 'runtime/JSGlobalData.cpp',
+ 'runtime/JSGlobalObject.cpp',
+ 'runtime/JSGlobalObjectFunctions.cpp',
+ 'runtime/JSImmediate.cpp',
+ 'runtime/JSLock.cpp',
+ 'runtime/JSNotAnObject.cpp',
+ 'runtime/JSNumberCell.cpp',
+ 'runtime/JSObject.cpp',
+ 'runtime/JSPropertyNameIterator.cpp',
+ 'runtime/JSStaticScopeObject.cpp',
+ 'runtime/JSString.cpp',
+ 'runtime/JSValue.cpp',
+ 'runtime/JSVariableObject.cpp',
+ 'runtime/JSWrapperObject.cpp',
+ 'runtime/Lookup.cpp',
+ 'runtime/MathObject.cpp',
+ 'runtime/NativeErrorConstructor.cpp',
+ 'runtime/NativeErrorPrototype.cpp',
+ 'runtime/NumberConstructor.cpp',
+ 'runtime/NumberObject.cpp',
+ 'runtime/NumberPrototype.cpp',
+ 'runtime/ObjectConstructor.cpp',
+ 'runtime/ObjectPrototype.cpp',
+ 'runtime/Operations.cpp',
+ 'runtime/PropertyNameArray.cpp',
+ 'runtime/PropertySlot.cpp',
+ 'runtime/PrototypeFunction.cpp',
+ 'runtime/RegExp.cpp',
+ 'runtime/RegExpConstructor.cpp',
+ 'runtime/RegExpObject.cpp',
+ 'runtime/RegExpPrototype.cpp',
+ 'runtime/ScopeChain.cpp',
+ 'runtime/SmallStrings.cpp',
+ 'runtime/StringConstructor.cpp',
+ 'runtime/StringObject.cpp',
+ 'runtime/StringPrototype.cpp',
+ 'runtime/Structure.cpp',
+ 'runtime/StructureChain.cpp',
+ 'runtime/UString.cpp',
+]
+sources['bytecode'] = [
+ 'bytecode/CodeBlock.cpp',
+ 'bytecode/StructureStubInfo.cpp',
+ 'bytecode/JumpTable.cpp',
+ 'bytecode/Opcode.cpp',
+ 'bytecode/SamplingTool.cpp',
+]
+sources['interpreter'] = [
+ 'interpreter/CallFrame.cpp',
+ 'interpreter/Interpreter.cpp',
+ 'interpreter/RegisterFile.cpp',
+]
+sources['jit'] = [
+ 'jit/ExecutableAllocator.cpp',
+ 'jit/JIT.cpp',
+]
+sources['wrec'] = [
+ 'wrec/CharacterClass.cpp',
+ 'wrec/CharacterClassConstructor.cpp',
+ 'wrec/WREC.cpp',
+ 'wrec/WRECFunctors.cpp',
+ 'wrec/WRECGenerator.cpp',
+ 'wrec/WRECParser.cpp',
+]
+sources['wtf'] = [
+ 'wtf/Assertions.cpp',
+ 'wtf/ByteArray.cpp',
+ 'wtf/CurrentTime.cpp',
+ 'wtf/FastMalloc.cpp',
+ 'wtf/HashTable.cpp',
+ 'wtf/RandomNumber.cpp',
+ 'wtf/RefCountedLeakCounter.cpp',
+ 'wtf/Threading.cpp',
+ 'wtf/dtoa.cpp',
+]
+sources['wtf/unicode'] = [
+ 'wtf/unicode/CollatorDefault.cpp',
+ 'wtf/unicode/UTF8.cpp',
+]
+sources['wtf/unicode/icu'] = [
+ 'wtf/unicode/icu/CollatorICU.cpp',
+]
+
+env = Environment()
+
+building_on_win32 = env['PLATFORM'] == 'win32' or env['PLATFORM'] == 'cygwin'
+
+# Scons uses gcc when building under cygwin by default
+# We also have to manually force 8.0 or Scons will try and
+# look up what version to use using the registry and fail
+# due to lack of cygwin-python registry support
+if env['PLATFORM'] == 'cygwin':
+ env['MSVS_VERSION'] = '8.0'
+ # Some systems have PROGRAMFILES, some have ProgramFiles
+ # Scons msvc tool only expects 'ProgramFiles'
+ import os
+ if os.getenv('PROGRAMFILES') and not os.getenv('ProgramFiles'):
+ os.environ['ProgramFiles'] = os.getenv('PROGRAMFILES')
+
+ env.Tool('msvc')
+ env.Tool('mslink')
+ env.Tool('mslib')
+
+# Scons is failing to carry the %PATH% value through correctly
+# Hack IncrediBuild into our path so cl.exe doesn't crash
+if env['PLATFORM'] == 'win32':
+ env.AppendENVPath('PATH', 'c:/Program Files/Xoreax/IncrediBuild')
+
+if env['PLATFORM'] == 'darwin':
+ sources['API'].append('API/JSStringRefCF.cpp')
+ sources['profiler'].append('profiler/ProfilerServer.mm')
+ sources['wtf'].append('wtf/ThreadingPthreads.cpp')
+ sources['wtf'].append('wtf/MainThread.cpp')
+ sources['wtf/mac'] = ['wtf/mac/MainThreadMac.mm']
+ sources['wtf'].append('wtf/TCSystemAlloc.cpp')
+ sources['jit'].append('jit/ExecutableAllocatorPosix.cpp')
+elif building_on_win32:
+ sources['wtf'].append('wtf/ThreadingNone.cpp')
+ sources['jit'].append('jit/ExecutableAllocatorWin.cpp')
+ env.Append(CPPDEFINES = ['ENABLE_JSC_MULTIPLE_THREADS=0'])
+
+derived_sources_path = 'DerivedSources/JavaScriptCore/'
+def DerivedSources(path):
+ return derived_sources_path + path
+
+derived_sources_results = map(DerivedSources, [
+ 'ArrayPrototype.lut.h',
+ 'DatePrototype.lut.h',
+ 'MathObject.lut.h',
+ 'NumberConstructor.lut.h',
+ 'RegExpConstructor.lut.h',
+ 'RegExpObject.lut.h',
+ 'StringPrototype.lut.h'
+ 'chartables.c',
+ 'grammar.cpp',
+ 'grammar.h',
+ 'lexer.lut.h',
+])
+
+derived_sources_sources = [
+ 'runtime/ArrayPrototype.cpp',
+ 'runtime/DatePrototype.cpp',
+ 'runtime/MathObject.cpp',
+ 'runtime/NumberConstructor.cpp',
+ 'runtime/RegExpConstructor.cpp',
+ 'runtime/RegExpObject.cpp',
+ 'runtime/StringPrototype.cpp',
+ 'parser/Grammar.y',
+ 'parser/Lexer.cpp',
+]
+
+# Generate DerivedSources
+# Make sure Windows knows where bash (and all the other cygwin commands) live
+if env['PLATFORM'] == 'win32':
+ env.AppendENVPath('PATH', 'C:/cygwin/bin')
+env.Command(derived_sources_results, derived_sources_sources, 'bash make-generated-sources.sh')
+sources[derived_sources_path] = [DerivedSources('Grammar.cpp')]
+
+# Handle os-version specific build settings
+if env['PLATFORM'] == 'darwin':
+ from subprocess import Popen, PIPE
+ version_pieces = Popen(["sw_vers", "-productVersion"], stdout = PIPE).communicate()[0].split('.')
+ if map(int, version_pieces)[:2] > (10, 5):
+ # Dtrace doesn't exist in Tiger, and was broken in Leopard
+ env.Command(DerivedSources('TracingDtrace.h'), 'runtime/Tracing.d', '/usr/sbin/dtrace -h -o $TARGET -s $SOURCE')
+
+# This build file builds the Chromium port for now, support for
+# others could be added later.
+env.Append(CPPDEFINES = ['BUILDING_CHROMIUM__'])
+
+# I'm not certain how many of these windows defines are actually required.
+if building_on_win32:
+ env.Append(CPPDEFINES = ['_WIN32_WINNT=0x0600', 'WINVER=0x0600', 'WIN32', '_WINDOWS', 'NOMINMAX', 'UNICODE', '_UNICODE', '__STD_C', '_HAS_EXCEPTIONS=0'])
+
+# Scons out-of-the-box only supports precompiled headers for MSVC
+# remove this when we fix Scons to understand GCC precompiled headers
+if env['CC'] == 'gcc':
+ env['CCFLAGS'] = '-include JavaScriptCorePrefix.h'
+# Turns out the MSVC PCH support is badly broken
+# env['PCH'] = 'JavaScriptCorePrefix.h'
+# env['PCHSTOP'] = 'JavaScriptCorePrefix.h'
+
+if env['PLATFORM'] == 'darwin':
+ env['FRAMEWORKS'] = ['CoreFoundation', 'Foundation']
+ env['LIBS'] = ['icucore']
+ # Apple does not ship the ICU headers with Mac OS X, so WebKit includes a copy of 3.2 headers
+ env.Append(CPPPATH = 'icu')
+
+webkit_libraries_path = "../WebKitLibraries/win/"
+def WebKitLibraries(path):
+ return webkit_libraries_path + path
+
+include_paths = ['.', '..', 'ForwardingHeaders'] + sources.keys()
+env.Append(CPPPATH = include_paths)
+if building_on_win32:
+ env.Append(CPPPATH = ['os-win32', WebKitLibraries('include')])
+ env.Prepend(LIBPATH = [WebKitLibraries('lib')])
+ env.Append(LIBS = ['icuin', 'icuuc', 'user32', 'winmm'])
+
+# Save off a copy of the environment for use with jsc
+jsc_env = env.Clone()
+
+if building_on_win32:
+ env.StaticLibrary("JavaScriptCore", sources.values())
+else:
+ env.SharedLibrary("JavaScriptCore", sources.values())
+
+
+env = jsc_env
+
+# Build the jsc testing shell
+shell_sources = ['jsc.cpp']
+build_directory = '.' # This should be changed to point to wherever JavaScriptCore gets built to
+
+# It's hacky to re-use the same environment from JavaScriptCore
+# but it makes building on windows easier for now
+env['CPPPATH'] = include_paths
+env['LIBS'] = ['JavaScriptCore']
+env['LIBPATH'] = [build_directory]
+
+if env['PLATFORM'] == 'darwin':
+ env.Append(LIBS = ['edit'])
+ env.Append(CPPPATH = 'icu')
+elif building_on_win32:
+ env.Append(CPPPATH = ['os-win32', WebKitLibraries('include')])
+ env.Prepend(LIBPATH = [WebKitLibraries('lib')])
+ env.Append(LIBS = ['icuin', 'icuuc', 'user32', 'winmm'])
+
+env.Program('jsc', shell_sources)
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index 3c64f3c..e28adab 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -42,7 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../pcre/;../../kjs/;../../runtime/;../../VM/;../../wtf/;../../profiler;../../masm/;../../debugger/;../../wrec/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;../../../icu/include;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ 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\icu&quot;;../../../icu/include;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
PreprocessorDefinitions="__STD_C"
ForcedIncludeFiles=""
/>
@@ -73,7 +73,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\kjs\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\kjs\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&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\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -104,7 +104,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../pcre/;../../kjs/;../../runtime/;../../VM/;../../wtf/;../../profiler;../../masm/;../../debugger/;../../wrec/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;../../../icu/include;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ 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\icu&quot;;../../../icu/include;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
PreprocessorDefinitions="__STD_C"
ForcedIncludeFiles=""
/>
@@ -135,7 +135,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\kjs\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\kjs\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&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\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -165,7 +165,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../pcre/;../../kjs/;../../runtime/;../../VM/;../../wtf/;../../profiler;../../masm/;../../debugger/;../../wrec/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;../../../icu/include;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ 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\icu&quot;;../../../icu/include;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
PreprocessorDefinitions="__STD_C"
ForcedIncludeFiles=""
/>
@@ -196,7 +196,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\kjs\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\kjs\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&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\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -227,7 +227,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../pcre/;../../kjs/;../../runtime/;../../VM/;../../wtf/;../../profiler;../../masm/;../../debugger/;../../wrec/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;../../../icu/include;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ 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\icu&quot;;../../../icu/include;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
PreprocessorDefinitions="__STD_C"
ForcedIncludeFiles=""
/>
@@ -258,7 +258,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\kjs\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\kjs\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&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\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
@@ -266,7 +266,7 @@
</References>
<Files>
<Filter
- Name="KJS"
+ Name="JavaScriptCore"
>
<File
RelativePath="..\..\runtime\ArgList.cpp"
@@ -333,15 +333,23 @@
>
</File>
<File
+ RelativePath="..\..\interpreter\CallFrame.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\interpreter\CallFrame.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\ClassInfo.h"
>
</File>
<File
- RelativePath="..\..\kjs\collector.cpp"
+ RelativePath="..\..\runtime\Collector.cpp"
>
</File>
<File
- RelativePath="..\..\kjs\collector.h"
+ RelativePath="..\..\runtime\Collector.h"
>
</File>
<File
@@ -357,11 +365,15 @@
>
</File>
<File
- RelativePath="..\..\kjs\completion.h"
+ RelativePath="..\..\runtime\Completion.cpp"
>
</File>
<File
- RelativePath="..\..\kjs\config.h"
+ RelativePath="..\..\runtime\Completion.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\config.h"
>
</File>
<File
@@ -405,14 +417,6 @@
>
</File>
<File
- RelativePath="..\..\kjs\dtoa.cpp"
- >
- </File>
- <File
- RelativePath="..\..\kjs\dtoa.h"
- >
- </File>
- <File
RelativePath="..\..\runtime\Error.cpp"
>
</File>
@@ -445,14 +449,6 @@
>
</File>
<File
- RelativePath="..\..\runtime\ExecState.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\ExecState.h"
- >
- </File>
- <File
RelativePath="..\..\runtime\FunctionConstructor.cpp"
>
</File>
@@ -485,11 +481,11 @@
>
</File>
<File
- RelativePath="..\..\kjs\identifier.cpp"
+ RelativePath="..\..\runtime\Identifier.cpp"
>
</File>
<File
- RelativePath="..\..\kjs\identifier.h"
+ RelativePath="..\..\runtime\Identifier.h"
>
</File>
<File
@@ -509,11 +505,7 @@
>
</File>
<File
- RelativePath="..\..\kjs\interpreter.cpp"
- >
- </File>
- <File
- RelativePath="..\..\kjs\interpreter.h"
+ RelativePath="..\..\runtime\Interpreter.h"
>
</File>
<File
@@ -533,6 +525,14 @@
>
</File>
<File
+ RelativePath="..\..\runtime\JSByteArray.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\JSByteArray.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\JSCell.cpp"
>
</File>
@@ -657,15 +657,15 @@
>
</File>
<File
- RelativePath="..\..\kjs\LabelScope.h"
+ RelativePath="..\..\bytecompiler\LabelScope.h"
>
</File>
<File
- RelativePath="..\..\kjs\lookup.cpp"
+ RelativePath="..\..\runtime\Lookup.cpp"
>
</File>
<File
- RelativePath="..\..\kjs\lookup.h"
+ RelativePath="..\..\runtime\Lookup.h"
>
</File>
<File
@@ -693,7 +693,7 @@
>
</File>
<File
- RelativePath="..\..\kjs\NodeInfo.h"
+ RelativePath="..\..\parser\NodeInfo.h"
>
</File>
<File
@@ -737,11 +737,11 @@
>
</File>
<File
- RelativePath="..\..\kjs\operations.cpp"
+ RelativePath="..\..\runtime\Operations.cpp"
>
</File>
<File
- RelativePath="..\..\kjs\operations.h"
+ RelativePath="..\..\runtime\Operations.h"
>
</File>
<File
@@ -765,7 +765,7 @@
>
</File>
<File
- RelativePath="..\..\kjs\protect.h"
+ RelativePath="..\..\runtime\Protect.h"
>
</File>
<File
@@ -777,11 +777,11 @@
>
</File>
<File
- RelativePath="..\..\kjs\regexp.cpp"
+ RelativePath="..\..\runtime\RegExp.cpp"
>
</File>
<File
- RelativePath="..\..\kjs\regexp.h"
+ RelativePath="..\..\runtime\RegExp.h"
>
</File>
<File
@@ -829,11 +829,11 @@
>
</File>
<File
- RelativePath="..\..\kjs\SourceProvider.h"
+ RelativePath="..\..\parser\SourceCode.h"
>
</File>
<File
- RelativePath="..\..\kjs\SourceCode.h"
+ RelativePath="..\..\parser\SourceProvider.h"
>
</File>
<File
@@ -865,23 +865,23 @@
>
</File>
<File
- RelativePath="..\..\runtime\StructureID.cpp"
+ RelativePath="..\..\runtime\Structure.cpp"
>
</File>
<File
- RelativePath="..\..\runtime\StructureID.h"
+ RelativePath="..\..\runtime\Structure.h"
>
</File>
<File
- RelativePath="..\..\runtime\StructureIDChain.cpp"
+ RelativePath="..\..\runtime\StructureChain.cpp"
>
</File>
<File
- RelativePath="..\..\runtime\StructureIDChain.h"
+ RelativePath="..\..\runtime\StructureChain.h"
>
</File>
<File
- RelativePath="..\..\runtime\StructureIDTransitionTable.h"
+ RelativePath="..\..\runtime\StructureTransitionTable.h"
>
</File>
<File
@@ -889,11 +889,11 @@
>
</File>
<File
- RelativePath="..\..\kjs\ustring.cpp"
+ RelativePath="..\..\runtime\UString.cpp"
>
</File>
<File
- RelativePath="..\..\kjs\ustring.h"
+ RelativePath="..\..\runtime\UString.h"
>
</File>
<Filter
@@ -908,7 +908,7 @@
>
</File>
<File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\grammar.cpp"
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\Grammar.cpp"
>
<FileConfiguration
Name="Debug|Win32"
@@ -945,7 +945,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\grammar.h"
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\Grammar.h"
>
</File>
<File
@@ -1186,27 +1186,27 @@
Name="Compiler"
>
<File
- RelativePath="..\..\VM\CodeGenerator.cpp"
+ RelativePath="..\..\bytecompiler\BytecodeGenerator.cpp"
>
</File>
<File
- RelativePath="..\..\VM\CodeGenerator.h"
+ RelativePath="..\..\bytecompiler\BytecodeGenerator.h"
>
</File>
<File
- RelativePath="..\..\VM\LabelID.h"
+ RelativePath="..\..\bytecompiler\Label.h"
>
</File>
<File
- RelativePath="..\..\kjs\lexer.cpp"
+ RelativePath="..\..\parser\Lexer.cpp"
>
</File>
<File
- RelativePath="..\..\kjs\lexer.h"
+ RelativePath="..\..\parser\Lexer.h"
>
</File>
<File
- RelativePath="..\..\kjs\nodes.cpp"
+ RelativePath="..\..\parser\Nodes.cpp"
>
<FileConfiguration
Name="Release_PGO|Win32"
@@ -1218,111 +1218,111 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\..\kjs\nodes.h"
+ RelativePath="..\..\parser\Nodes.h"
>
</File>
<File
- RelativePath="..\..\kjs\nodes2string.cpp"
+ RelativePath="..\..\parser\Parser.cpp"
>
</File>
<File
- RelativePath="..\..\kjs\Parser.cpp"
+ RelativePath="..\..\parser\Parser.h"
>
</File>
<File
- RelativePath="..\..\kjs\Parser.h"
+ RelativePath="..\..\bytecompiler\RegisterID.h"
>
</File>
<File
- RelativePath="..\..\VM\RegisterID.h"
- >
- </File>
- <File
- RelativePath="..\..\VM\SegmentedVector.h"
+ RelativePath="..\..\bytecompiler\SegmentedVector.h"
>
</File>
</Filter>
<Filter
- Name="VM"
+ Name="bytecode"
>
<File
- RelativePath="..\..\VM\CodeBlock.cpp"
+ RelativePath="..\..\bytecode\StructureStubInfo.cpp"
>
</File>
<File
- RelativePath="..\..\VM\CodeBlock.h"
+ RelativePath="..\..\bytecode\StructureStubInfo.h"
>
</File>
<File
- RelativePath="..\..\VM\CTI.cpp"
+ RelativePath="..\..\bytecode\CodeBlock.cpp"
>
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WholeProgramOptimization="false"
- />
- </FileConfiguration>
</File>
<File
- RelativePath="..\..\VM\CTI.h"
+ RelativePath="..\..\bytecode\CodeBlock.h"
>
</File>
<File
- RelativePath="..\..\VM\ExceptionHelpers.cpp"
+ RelativePath="..\..\bytecode\JumpTable.cpp"
>
</File>
<File
- RelativePath="..\..\VM\ExceptionHelpers.h"
+ RelativePath="..\..\bytecode\JumpTable.h"
>
</File>
<File
- RelativePath="..\..\VM\Instruction.h"
+ RelativePath="..\..\bytecode\EvalCodeCache.h"
>
</File>
<File
- RelativePath="..\..\runtime\JSPropertyNameIterator.cpp"
+ RelativePath="..\..\runtime\ExceptionHelpers.cpp"
>
</File>
<File
- RelativePath="..\..\runtime\JSPropertyNameIterator.h"
+ RelativePath="..\..\interpreter\ExceptionHelpers.h"
>
</File>
<File
- RelativePath="..\..\VM\Machine.cpp"
+ RelativePath="..\..\bytecode\Instruction.h"
>
</File>
<File
- RelativePath="..\..\VM\Machine.h"
+ RelativePath="..\..\interpreter\Interpreter.cpp"
>
</File>
<File
- RelativePath="..\..\VM\Opcode.cpp"
+ RelativePath="..\..\interpreter\Interpreter.h"
>
</File>
<File
- RelativePath="..\..\VM\Opcode.h"
+ RelativePath="..\..\runtime\JSPropertyNameIterator.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\JSPropertyNameIterator.h"
>
</File>
<File
- RelativePath="..\..\VM\Register.h"
+ RelativePath="..\..\bytecode\Opcode.cpp"
>
</File>
<File
- RelativePath="..\..\VM\RegisterFile.cpp"
+ RelativePath="..\..\bytecode\Opcode.h"
>
</File>
<File
- RelativePath="..\..\VM\RegisterFile.h"
+ RelativePath="..\..\interpreter\Register.h"
>
</File>
<File
- RelativePath="..\..\VM\SamplingTool.cpp"
+ RelativePath="..\..\interpreter\RegisterFile.cpp"
>
</File>
<File
- RelativePath="..\..\VM\SamplingTool.h"
+ RelativePath="..\..\interpreter\RegisterFile.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\bytecode\SamplingTool.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\bytecode\SamplingTool.h"
>
</File>
</Filter>
@@ -1338,6 +1338,14 @@
>
</File>
<File
+ RelativePath="..\..\debugger\DebuggerActivation.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\debugger\DebuggerActivation.h"
+ >
+ </File>
+ <File
RelativePath="..\..\debugger\DebuggerCallFrame.cpp"
>
</File>
@@ -1347,10 +1355,14 @@
</File>
</Filter>
<Filter
- Name="masm"
+ Name="assembler"
>
<File
- RelativePath="..\..\masm\X86Assembler.h"
+ RelativePath="..\..\assembler\AssemblerBuffer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\assembler\X86Assembler.h"
>
</File>
</Filter>
@@ -1358,6 +1370,14 @@
Name="wrec"
>
<File
+ RelativePath="..\..\wrec\CharacterClass.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wrec\CharacterClass.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wrec\CharacterClassConstructor.cpp"
>
</File>
@@ -1366,6 +1386,10 @@
>
</File>
<File
+ RelativePath="..\..\wrec\Quantifier.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wrec\WREC.cpp"
>
</File>
@@ -1373,6 +1397,102 @@
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="jit"
+ >
+ <File
+ RelativePath="..\..\jit\JIT.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="false"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\jit\JIT.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\jit\ExecutableAllocator.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\jit\ExecutableAllocatorWin.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\jit\ExecutableAllocator.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\jit\JITArithmetic.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="false"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\jit\JITCall.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="false"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\jit\JITInlineMethods.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\jit\JITPropertyAccess.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="false"
+ />
+ </FileConfiguration>
+ </File>
</Filter>
</Files>
<Globals>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index 29d7a51..3934b15 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="Windows-1252"?>
+<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="8,00"
Name="WTF"
ProjectGUID="{AA8A5A85-592B-4357-BC60-E0E91E026AF6}"
RootNamespace="WTF"
@@ -42,7 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../kjs/;../../wtf/;../../wtf/unicode/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;../../../icu/include;../../bindings;../../bindings/c;../../bindings/jni;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../parser/;../../wtf/;../../wtf/unicode/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;../../../icu/include;../../bindings;../../bindings/c;../../bindings/jni;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
PreprocessorDefinitions="__STD_C"
ForcedIncludeFiles=""
/>
@@ -105,7 +105,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../kjs/;../../wtf/;../../wtf/unicode/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;../../../icu/include;../../bindings;../../bindings/c;../../bindings/jni;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../parser/;../../wtf/;../../wtf/unicode/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;../../../icu/include;../../bindings;../../bindings/c;../../bindings/jni;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
PreprocessorDefinitions="__STD_C"
ForcedIncludeFiles=""
/>
@@ -167,7 +167,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../kjs/;../../wtf/;../../wtf/unicode/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;../../../icu/include;../../bindings;../../bindings/c;../../bindings/jni;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../parser/;../../wtf/;../../wtf/unicode/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;../../../icu/include;../../bindings;../../bindings/c;../../bindings/jni;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
PreprocessorDefinitions="__STD_C"
ForcedIncludeFiles=""
/>
@@ -230,6 +230,14 @@
RelativePath="..\..\wtf\Assertions.h"
>
</File>
+ <File
+ RelativePath="..\..\wtf\ByteArray.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\ByteArray.h"
+ >
+ </File>
<File
RelativePath="..\..\wtf\unicode\Collator.h"
>
@@ -243,10 +251,26 @@
>
</File>
<File
+ RelativePath="..\..\wtf\CurrentTime.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\CurrentTime.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\Deque.h"
>
</File>
<File
+ RelativePath="..\..\wtf\dtoa.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\dtoa.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\FastMalloc.cpp"
>
</File>
@@ -351,6 +375,22 @@
>
</File>
<File
+ RelativePath="..\..\wtf\PtrAndFlags.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\RandomNumber.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\RandomNumber.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\RandomNumberSeed.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\RefCounted.h"
>
</File>
@@ -371,6 +411,10 @@
>
</File>
<File
+ RelativePath="..\..\wtf\StdLibExtras.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\StringExtras.h"
>
</File>
@@ -395,6 +439,10 @@
>
</File>
<File
+ RelativePath="..\..\wtf\Threading.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\Threading.h"
>
</File>
@@ -407,6 +455,10 @@
>
</File>
<File
+ RelativePath="..\..\wtf\ThreadSpecificWin.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\unicode\Unicode.h"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
index 4d2a32d..0b3a006 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
@@ -39,7 +39,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../kjs/;../../runtime/;../../VM/;../../wtf/;../../debugger/;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;;../../jit/"
PreprocessorDefinitions="__STD_C"
/>
<Tool
@@ -109,7 +109,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../kjs/;../../runtime/;../../VM/;../../wtf/;../../debugger/;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;;../../jit/"
PreprocessorDefinitions="__STD_C"
/>
<Tool
@@ -178,7 +178,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../kjs/;../../runtime/;../../VM/;../../wtf/;../../debugger/;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;;../../jit/"
PreprocessorDefinitions="__STD_C"
/>
<Tool
@@ -228,7 +228,7 @@
</References>
<Files>
<File
- RelativePath="..\..\kjs\Shell.cpp"
+ RelativePath="..\..\jsc.cpp"
>
</File>
</Files>
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index df4bfed..3c02898 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -36,11 +36,33 @@
/* Begin PBXBuildFile section */
06D358B30DAADAA4003B174E /* MainThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 06D358A20DAAD9C4003B174E /* MainThread.cpp */; };
06D358B40DAADAAA003B174E /* MainThreadMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 06D358A10DAAD9C4003B174E /* MainThreadMac.mm */; };
+ 088FA5BB0EF76D4300578E6F /* RandomNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 088FA5B90EF76D4300578E6F /* RandomNumber.cpp */; };
+ 088FA5BC0EF76D4300578E6F /* RandomNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 088FA5BA0EF76D4300578E6F /* RandomNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 08E279E90EF83B10007DB523 /* RandomNumberSeed.h in Headers */ = {isa = PBXBuildFile; fileRef = 08E279E80EF83B10007DB523 /* RandomNumberSeed.h */; };
+ 0B1F921D0F1753500036468E /* PtrAndFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B1F921B0F17502D0036468E /* PtrAndFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */; };
140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
141211310A48794D00480255 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
141211340A48795800480255 /* minidom.c in Sources */ = {isa = PBXBuildFile; fileRef = 141211020A48780900480255 /* minidom.c */; };
1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1421359A0A677F4F00A8195E /* JSBase.cpp */; };
+ 1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D77B0ED20D7300B89619 /* Interpreter.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1429D7D40ED2128200B89619 /* Interpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D7D30ED2128200B89619 /* Interpreter.cpp */; settings = {COMPILER_FLAGS = "-fno-var-tracking"; }; };
+ 1429D8780ED21ACD00B89619 /* ExceptionHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D8770ED21ACD00B89619 /* ExceptionHelpers.cpp */; };
+ 1429D8850ED21C3D00B89619 /* SamplingTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D8830ED21C3D00B89619 /* SamplingTool.cpp */; };
+ 1429D8860ED21C3D00B89619 /* SamplingTool.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D8840ED21C3D00B89619 /* SamplingTool.h */; };
+ 1429D8DD0ED2205B00B89619 /* CallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D8DB0ED2205B00B89619 /* CallFrame.cpp */; };
+ 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 */; };
143A97E60A4A06E200456B66 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
1440057F0A5335640005F061 /* JSNode.c in Sources */ = {isa = PBXBuildFile; fileRef = 1440F6420A4F8B6A0005F061 /* JSNode.c */; };
144005CB0A5338D10005F061 /* JSNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440F6410A4F8B6A0005F061 /* JSNode.h */; };
@@ -59,22 +81,21 @@
147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; };
1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B74C0A43032800517CFC /* JSStringRef.cpp */; };
1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B7E20A43076000517CFC /* JSObjectRef.cpp */; };
- 14909A2D0DCAF6CD00B29EB3 /* ExecState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD53F40A3E12D800BAF59C /* ExecState.cpp */; };
149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 149559ED0DDCDDF700648087 /* DebuggerCallFrame.cpp */; };
- 149B15EB0D81F986009CB8C7 /* Opcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 149B15E50D81F986009CB8C7 /* Opcode.cpp */; };
- 149B1AA00D86ED73009CB8C7 /* CodeBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 149B1A9E0D86ED73009CB8C7 /* CodeBlock.cpp */; };
14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14ABDF5E0A437FEF00ECCA01 /* JSCallbackObject.cpp */; };
14B8EC720A5652090062BE54 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
14BD59C50A3E8F9F00BAF59C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */; };
14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */; };
- 14E0FF120DBAAED00007C0AB /* Machine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 149B15E70D81F986009CB8C7 /* Machine.cpp */; settings = {COMPILER_FLAGS = "-fno-tree-pre"; }; };
14F3488F0E95EF8A003648BC /* CollectorHeapIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F3488E0E95EF8A003648BC /* CollectorHeapIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 180B9B080F16D94F009BDBC5 /* CurrentTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 180B9AF00F16C569009BDBC5 /* CurrentTime.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 180B9BFE0F16E94D009BDBC5 /* CurrentTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */; };
1C61516C0EBAC7A00031376F /* ProfilerServer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C61516A0EBAC7A00031376F /* ProfilerServer.mm */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; };
1C61516D0EBAC7A00031376F /* ProfilerServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C61516B0EBAC7A00031376F /* ProfilerServer.h */; };
5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
5D5D8AB60E0D0A7200F9C692 /* jsc in Copy Into Framework */ = {isa = PBXBuildFile; fileRef = 932F5BE10822A1C700736975 /* jsc */; };
5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
+ 5D6A566B0F05995500266145 /* Threading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D6A566A0F05995500266145 /* Threading.cpp */; };
5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */ = {isa = PBXBuildFile; fileRef = F692A8540255597D01FF60F7 /* create_hash_table */; settings = {ATTRIBUTES = (Private, ); }; };
6507D29E0E871E5E00D7D896 /* TypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6507D2970E871E4A00D7D896 /* TypeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
659126BD0BDD1728001921FB /* AllInOneFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 659126BC0BDD1728001921FB /* AllInOneFile.cpp */; };
@@ -82,17 +103,17 @@
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 /* StructureIDChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E4EE7080EBB7963005934AA /* StructureIDChain.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 7E4EE70F0EBB7A5B005934AA /* StructureIDChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E4EE70E0EBB7A5B005934AA /* StructureIDChain.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 */; };
- 8613F45A0E3A433E00C948FD /* SamplingTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8613F4580E3A433E00C948FD /* SamplingTool.cpp */; };
- 8613F45B0E3A433E00C948FD /* SamplingTool.h in Headers */ = {isa = PBXBuildFile; fileRef = 8613F4590E3A433E00C948FD /* SamplingTool.h */; };
- 8683B02E0E636482004C19EE /* CTI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8683B02B0E636482004C19EE /* CTI.cpp */; };
- 8683B02F0E636482004C19EE /* CTI.h in Headers */ = {isa = PBXBuildFile; fileRef = 8683B02C0E636482004C19EE /* CTI.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 869081410E640C89000D36ED /* X86Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 869081400E640C89000D36ED /* X86Assembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
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, ); }; };
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 */; };
+ 86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; };
+ 86CC85A10EE79A4700288682 /* JITInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CC85A00EE79A4700288682 /* JITInlineMethods.h */; };
+ 86CC85A30EE79B7400288682 /* JITCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CC85A20EE79B7400288682 /* JITCall.cpp */; };
+ 86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */; };
905B02AE0E28640F006DF882 /* RefCountedLeakCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 905B02AD0E28640F006DF882 /* RefCountedLeakCounter.cpp */; };
90D3469C0E285280009492EE /* RefCountedLeakCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D3469B0E285280009492EE /* RefCountedLeakCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
930754C108B0F68000AB3056 /* pcre_compile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 930754BF08B0F68000AB3056 /* pcre_compile.cpp */; };
@@ -103,7 +124,7 @@
932F5BD50822A1C700736975 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
932F5BD60822A1C700736975 /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */; };
932F5BD70822A1C700736975 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9322A00306C341D3009067BB /* libicucore.dylib */; };
- 932F5BDD0822A1C700736975 /* Shell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45E12D8806A49B0F00E9DF84 /* Shell.cpp */; };
+ 932F5BDD0822A1C700736975 /* jsc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45E12D8806A49B0F00E9DF84 /* jsc.cpp */; };
932F5BEA0822A1C700736975 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
933040040E6A749400786E6A /* SmallStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 93303FEA0E6A72C000786E6A /* SmallStrings.h */; settings = {ATTRIBUTES = (Private, ); }; };
9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93303FE80E6A72B500786E6A /* SmallStrings.cpp */; };
@@ -122,11 +143,29 @@
95FDFA140E22998F0006FB00 /* HeavyProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95FDFA130E22998F0006FB00 /* HeavyProfile.cpp */; };
95FDFA160E2299980006FB00 /* HeavyProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 95FDFA150E2299980006FB00 /* HeavyProfile.h */; };
960097A60EBABB58007A7297 /* LabelScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 960097A50EBABB58007A7297 /* LabelScope.h */; };
+ 9688CB150ED12B4E001D649F /* AssemblerBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */; };
+ 9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 9688CB140ED12B4E001D649F /* X86Assembler.h */; };
+ 969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07210ED1CE3300F1F681 /* BytecodeGenerator.h */; };
+ 969A072A0ED1CE6900F1F681 /* Label.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07270ED1CE6900F1F681 /* Label.h */; };
+ 969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07280ED1CE6900F1F681 /* RegisterID.h */; };
+ 969A072C0ED1CE6900F1F681 /* SegmentedVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07290ED1CE6900F1F681 /* SegmentedVector.h */; };
+ 969A07960ED1D3AE00F1F681 /* CodeBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */; };
+ 969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07910ED1D3AE00F1F681 /* CodeBlock.h */; settings = {ATTRIBUTES = (); }; };
+ 969A07980ED1D3AE00F1F681 /* EvalCodeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */; };
+ 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 */; };
A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72700780DAC605600E548D7 /* JSNotAnObject.cpp */; };
- A72701B60DADE94900E548D7 /* ExceptionHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72701B40DADE94900E548D7 /* ExceptionHelpers.cpp */; };
A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */; };
- A7C31DAA0DBEBA4300FDF8EB /* SegmentedVector.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C31DA80DBEBA4300FDF8EB /* SegmentedVector.h */; };
+ A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A782F1A50EEC9FA20036273F /* ExecutableAllocatorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A782F1A40EEC9FA20036273F /* ExecutableAllocatorPosix.cpp */; };
+ A791EF280F11E07900AE1F68 /* JSByteArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A791EF260F11E07900AE1F68 /* JSByteArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A791EF290F11E07900AE1F68 /* JSByteArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A791EF270F11E07900AE1F68 /* JSByteArray.cpp */; };
+ A7A1F7AC0F252B3C00E184E2 /* ByteArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7A1F7AA0F252B3C00E184E2 /* ByteArray.cpp */; };
+ A7A1F7AD0F252B3C00E184E2 /* ByteArray.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A1F7AB0F252B3C00E184E2 /* ByteArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */; };
BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9050E1839DB000F9297 /* ErrorConstructor.h */; };
BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9070E1839DB000F9297 /* ErrorPrototype.h */; };
BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9090E1839DB000F9297 /* NativeErrorConstructor.h */; };
@@ -144,12 +183,10 @@
BC18C3EB0E16F5CD00B34460 /* AVLTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A596370DE3E1C300C17E37 /* AVLTree.h */; };
BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 704FD35305697E6D003DBED9 /* BooleanObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */ = {isa = PBXBuildFile; fileRef = 145C507F0D9DF63B0088F6B9 /* CallData.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3EE0E16F5CD00B34460 /* CodeBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 149B1A9D0D86ED73009CB8C7 /* CodeBlock.h */; };
- BC18C3EF0E16F5CD00B34460 /* CodeGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 149B15E80D81F986009CB8C7 /* CodeGenerator.h */; };
BC18C3F00E16F5CD00B34460 /* Collator.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A862AA0D7EBB7D001EC6AA /* Collator.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3F10E16F5CD00B34460 /* collector.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8530255597D01FF60F7 /* collector.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C3F10E16F5CD00B34460 /* Collector.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8530255597D01FF60F7 /* Collector.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3F30E16F5CD00B34460 /* CommonIdentifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C3F40E16F5CD00B34460 /* completion.h in Headers */ = {isa = PBXBuildFile; fileRef = F5BB2BC5030F772101FCFE1D /* completion.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C3F40E16F5CD00B34460 /* Completion.h in Headers */ = {isa = PBXBuildFile; fileRef = F5BB2BC5030F772101FCFE1D /* Completion.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3F50E16F5CD00B34460 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = F68EBB8C0255D4C601FF60F7 /* config.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3F60E16F5CD00B34460 /* ConstructData.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8F3CCF0DAF17BA00577A80 /* ConstructData.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3F90E16F5CD00B34460 /* DateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateMath.h */; };
@@ -159,7 +196,6 @@
BC18C3FD0E16F5CD00B34460 /* DisallowCType.h in Headers */ = {isa = PBXBuildFile; fileRef = 938C4F6B0CA06BCE00D9310A /* DisallowCType.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C3FE0E16F5CD00B34460 /* dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 651F6413039D5B5F0078395C /* dtoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4000E16F5CD00B34460 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
- BC18C4010E16F5CD00B34460 /* ExecState.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BD53F30A3E12D800BAF59C /* ExecState.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4020E16F5CD00B34460 /* FastMalloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E217BA08E7EECC0023E5F6 /* FastMalloc.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4030E16F5CD00B34460 /* Forward.h in Headers */ = {isa = PBXBuildFile; fileRef = 935AF46909E9D9DB00ACD1D8 /* Forward.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4040E16F5CD00B34460 /* FunctionConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -172,14 +208,12 @@
BC18C40C0E16F5CD00B34460 /* HashSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92C08EA173A00F7300B /* HashSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C40D0E16F5CD00B34460 /* HashTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92E08EA173A00F7300B /* HashTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C40E0E16F5CD00B34460 /* HashTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92F08EA173A00F7300B /* HashTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C40F0E16F5CD00B34460 /* identifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 933A349A038AE7C6008635CE /* identifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 933A349A038AE7C6008635CE /* Identifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */ = {isa = PBXBuildFile; fileRef = E178633F0D9BEC0000D74E75 /* InitializeThreading.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4110E16F5CD00B34460 /* Instruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 149B1AA10D86ED7C009CB8C7 /* Instruction.h */; };
- BC18C4120E16F5CD00B34460 /* interpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8640255597D01FF60F7 /* interpreter.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4130E16F5CD00B34460 /* JavaScript.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC18C4140E16F5CD00B34460 /* JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */; };
- BC18C4160E16F5CD00B34460 /* JSActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DA818E0D99FD2000B0A4FB /* JSActivation.h */; };
+ BC18C4160E16F5CD00B34460 /* JSActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DA818E0D99FD2000B0A4FB /* JSActivation.h */; settings = {ATTRIBUTES = (); }; };
BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 938772E5038BFE19008635CE /* JSArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4180E16F5CD00B34460 /* JSBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 142711380A460BBB0080EEEA /* JSBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC18C4190E16F5CD00B34460 /* JSCallbackConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 1440F8AC0A508D200005F061 /* JSCallbackConstructor.h */; };
@@ -204,19 +238,17 @@
BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482B6EA0A4300B300517CFC /* JSValueRef.h */; settings = {ATTRIBUTES = (Public, ); }; };
BC18C42D0E16F5CD00B34460 /* JSVariableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F252560D08DD8D004ECFFF /* JSVariableObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C42E0E16F5CD00B34460 /* JSWrapperObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C42F0E16F5CD00B34460 /* LabelID.h in Headers */ = {isa = PBXBuildFile; fileRef = 149B20D70D8A0891009CB8C7 /* LabelID.h */; };
- BC18C4310E16F5CD00B34460 /* lexer.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8660255597D01FF60F7 /* lexer.h */; };
+ BC18C4310E16F5CD00B34460 /* Lexer.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8660255597D01FF60F7 /* Lexer.h */; };
BC18C4340E16F5CD00B34460 /* ListHashSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 657EB7450B708F540063461B /* ListHashSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4350E16F5CD00B34460 /* ListRefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 148A1626095D16BB00666D0D /* ListRefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4360E16F5CD00B34460 /* Locker.h in Headers */ = {isa = PBXBuildFile; fileRef = E1EE79270D6C964500FEA3BA /* Locker.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4370E16F5CD00B34460 /* lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8690255597D01FF60F7 /* lookup.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4380E16F5CD00B34460 /* Machine.h in Headers */ = {isa = PBXBuildFile; fileRef = 149B15E60D81F986009CB8C7 /* Machine.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C4370E16F5CD00B34460 /* Lookup.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8690255597D01FF60F7 /* Lookup.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4390E16F5CD00B34460 /* MainThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 06D358A30DAAD9C4003B174E /* MainThread.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C43A0E16F5CD00B34460 /* MallocZoneSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */; };
BC18C43B0E16F5CD00B34460 /* MathExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF6553B0A2048DE0038A194 /* MathExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A86B0255597D01FF60F7 /* MathObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C43E0E16F5CD00B34460 /* MessageQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = E1EE798B0D6CA53D00FEA3BA /* MessageQueue.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C43F0E16F5CD00B34460 /* nodes.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A86E0255597D01FF60F7 /* nodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A86E0255597D01FF60F7 /* Nodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4400E16F5CD00B34460 /* Noncopyable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F5690991190000AD71B8 /* Noncopyable.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C30E16D4E900A06E92 /* NumberConstructor.h */; };
BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680E60E16D52300A06E92 /* NumberConstructor.lut.h */; };
@@ -224,8 +256,7 @@
BC18C4440E16F5CD00B34460 /* NumberPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C50E16D4E900A06E92 /* NumberPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4450E16F5CD00B34460 /* ObjectConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C70E16D4E900A06E92 /* ObjectConstructor.h */; };
BC18C4460E16F5CD00B34460 /* ObjectPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4470E16F5CD00B34460 /* Opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 149B15E40D81F986009CB8C7 /* Opcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4480E16F5CD00B34460 /* operations.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8780255597D01FF60F7 /* operations.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C4480E16F5CD00B34460 /* Operations.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8780255597D01FF60F7 /* Operations.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4490E16F5CD00B34460 /* OwnArrayPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F5A409911A5800AD71B8 /* OwnArrayPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C44A0E16F5CD00B34460 /* OwnPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 9303F567099118FA00AD71B8 /* OwnPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F0B3AA09BB4DC00068FCE3 /* Parser.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -238,18 +269,16 @@
BC18C4520E16F5CD00B34460 /* Profiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 95AB832F0DA42CAD00BC83F3 /* Profiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4540E16F5CD00B34460 /* PropertyNameArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 65400C100A69BAF200509887 /* PropertyNameArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* PropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4560E16F5CD00B34460 /* protect.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C02FBB0637462A003E7EE6 /* protect.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C4560E16F5CD00B34460 /* Protect.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C02FBB0637462A003E7EE6 /* Protect.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4570E16F5CD00B34460 /* RefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 1419D32C0CEA7CDE00FF507A /* RefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4580E16F5CD00B34460 /* RefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C647B3093EF8D60022C380 /* RefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4590E16F5CD00B34460 /* RefPtrHashMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 148A1ECD0D10C23B0069A47C /* RefPtrHashMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C45A0E16F5CD00B34460 /* regexp.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87E0255597D01FF60F7 /* regexp.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C45A0E16F5CD00B34460 /* RegExp.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87E0255597D01FF60F7 /* RegExp.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87C0255597D01FF60F7 /* RegExpObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C45D0E16F5CD00B34460 /* Register.h in Headers */ = {isa = PBXBuildFile; fileRef = 149B24FF0D8AF6D1009CB8C7 /* Register.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C45E0E16F5CD00B34460 /* RegisterFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D792640DAA03FB001A9F05 /* RegisterFile.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C45F0E16F5CD00B34460 /* RegisterID.h in Headers */ = {isa = PBXBuildFile; fileRef = 149B16B80D82583F009CB8C7 /* RegisterID.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4600E16F5CD00B34460 /* RetainPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F648D60BB4E2CA0033D760 /* RetainPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4610E16F5CD00B34460 /* ScopeChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 9374D3A7038D9D74008635CE /* ScopeChain.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4620E16F5CD00B34460 /* SegmentedVector.h in Headers */ = {isa = PBXBuildFile; fileRef = A7C31DA80DBEBA4300FDF8EB /* SegmentedVector.h */; };
BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E866ED0DD59AFA00A2B2A1 /* SourceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4640E16F5CD00B34460 /* SourceCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E866EE0DD59AFA00A2B2A1 /* SourceCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C3C10E16EE3300B34460 /* StringConstructor.h */; };
@@ -268,7 +297,7 @@
BC18C4730E16F5CD00B34460 /* Unicode.h in Headers */ = {isa = PBXBuildFile; fileRef = E195679409E7CF1200B89D13 /* Unicode.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4740E16F5CD00B34460 /* UnicodeIcu.h in Headers */ = {isa = PBXBuildFile; fileRef = E195678F09E7CF1200B89D13 /* UnicodeIcu.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4750E16F5CD00B34460 /* UnusedParam.h in Headers */ = {isa = PBXBuildFile; fileRef = 935AF46B09E9D9DB00ACD1D8 /* UnusedParam.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC18C4760E16F5CD00B34460 /* ustring.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8860255597D01FF60F7 /* ustring.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC18C4760E16F5CD00B34460 /* UString.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A8860255597D01FF60F7 /* UString.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4770E16F5CD00B34460 /* UTF8.h in Headers */ = {isa = PBXBuildFile; fileRef = E1EF79A90CE97BA60088D500 /* UTF8.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4780E16F5CD00B34460 /* Vector.h in Headers */ = {isa = PBXBuildFile; fileRef = 6592C316098B7DE10003D4F6 /* Vector.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC18C4790E16F5CD00B34460 /* VectorTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 6592C317098B7DE10003D4F6 /* VectorTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -283,20 +312,26 @@
BC257DF00E1F52ED0016B6C9 /* GlobalEvalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DEE0E1F52ED0016B6C9 /* GlobalEvalFunction.h */; };
BC257DF40E1F53740016B6C9 /* PrototypeFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = BC257DF20E1F53740016B6C9 /* PrototypeFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC3046070E1F497F003232CF /* Error.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3046060E1F497F003232CF /* Error.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC3135640F302FA3003DFD3A /* DebuggerActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3135620F302FA3003DFD3A /* DebuggerActivation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3135630F302FA3003DFD3A /* DebuggerActivation.cpp */; };
BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; };
BC7F8FB90E19D1C3008632C0 /* JSNumberCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7F8FB80E19D1C3008632C0 /* JSNumberCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BC9041480EB9250900FE26FA /* StructureIDTransitionTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9041470EB9250900FE26FA /* StructureIDTransitionTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9041470EB9250900FE26FA /* StructureTransitionTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */; };
+ BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCCF0D0B0EF0B8A500413C8F /* StructureStubInfo.cpp */; };
BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */; };
BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202C00E1706A7002C7E82 /* RegExpPrototype.h */; };
BCD202D60E170708002C7E82 /* RegExpConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202D50E170708002C7E82 /* RegExpConstructor.lut.h */; };
BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD203460E17135E002C7E82 /* DateConstructor.h */; };
BCD2034C0E17135E002C7E82 /* DatePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD203480E17135E002C7E82 /* DatePrototype.h */; };
BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */; };
- BCDE3AB80E6C82F5001453A7 /* StructureID.h in Headers */ = {isa = PBXBuildFile; fileRef = BCDE3AB10E6C82CF001453A7 /* StructureID.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BCDE3B430E6C832D001453A7 /* StructureID.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCDE3AB00E6C82CF001453A7 /* StructureID.cpp */; };
+ BCDE3AB80E6C82F5001453A7 /* Structure.h in Headers */ = {isa = PBXBuildFile; fileRef = BCDE3AB10E6C82CF001453A7 /* Structure.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BCDE3B430E6C832D001453A7 /* Structure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCDE3AB00E6C82CF001453A7 /* Structure.cpp */; };
BCF605140E203EF800B9A64D /* ArgList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF605120E203EF800B9A64D /* ArgList.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCFD8C900EEB2EE700283848 /* JumpTable.cpp */; };
+ BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; };
C0A272630E50A06300E96E15 /* NotFound.h in Headers */ = {isa = PBXBuildFile; fileRef = C0A2723F0E509F1E00E96E15 /* NotFound.h */; settings = {ATTRIBUTES = (Private, ); }; };
E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; };
E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E124A8F60E555775003091F1 /* OpaqueJSString.cpp */; };
@@ -306,6 +341,7 @@
E1A862D60D7F2B5C001EC6AA /* CollatorDefault.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A862D50D7F2B5C001EC6AA /* CollatorDefault.cpp */; };
E1EE793D0D6C9B9200FEA3BA /* ThreadingPthreads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1EE793C0D6C9B9200FEA3BA /* ThreadingPthreads.cpp */; };
E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1EF79A80CE97BA60088D500 /* UTF8.cpp */; };
+ FE1B447A0ECCD73B004F4DD1 /* StdLibExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1B44790ECCD73B004F4DD1 /* StdLibExtras.h */; settings = {ATTRIBUTES = (Private, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -385,6 +421,10 @@
06D358A10DAAD9C4003B174E /* MainThreadMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MainThreadMac.mm; sourceTree = "<group>"; };
06D358A20DAAD9C4003B174E /* MainThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MainThread.cpp; sourceTree = "<group>"; };
06D358A30DAAD9C4003B174E /* MainThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainThread.h; sourceTree = "<group>"; };
+ 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>"; };
140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBasePrivate.h; sourceTree = "<group>"; };
141211020A48780900480255 /* minidom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minidom.c; path = tests/minidom.c; sourceTree = "<group>"; };
1412110D0A48788700480255 /* minidom.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = minidom.js; path = tests/minidom.js; sourceTree = "<group>"; };
@@ -392,6 +432,25 @@
1419D32C0CEA7CDE00FF507A /* RefCounted.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefCounted.h; sourceTree = "<group>"; };
1421359A0A677F4F00A8195E /* JSBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBase.cpp; sourceTree = "<group>"; };
142711380A460BBB0080EEEA /* JSBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBase.h; sourceTree = "<group>"; };
+ 1429D77B0ED20D7300B89619 /* Interpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Interpreter.h; sourceTree = "<group>"; };
+ 1429D7D30ED2128200B89619 /* Interpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Interpreter.cpp; sourceTree = "<group>"; };
+ 1429D85B0ED218E900B89619 /* RegisterFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterFile.cpp; sourceTree = "<group>"; };
+ 1429D8770ED21ACD00B89619 /* ExceptionHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExceptionHelpers.cpp; sourceTree = "<group>"; };
+ 1429D8830ED21C3D00B89619 /* SamplingTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingTool.cpp; sourceTree = "<group>"; };
+ 1429D8840ED21C3D00B89619 /* SamplingTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingTool.h; sourceTree = "<group>"; };
+ 1429D8DB0ED2205B00B89619 /* CallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallFrame.cpp; sourceTree = "<group>"; };
+ 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>"; };
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>"; };
144007480A536CC20005F061 /* NodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NodeList.h; path = tests/NodeList.h; sourceTree = "<group>"; };
@@ -423,39 +482,27 @@
148A1626095D16BB00666D0D /* ListRefPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ListRefPtr.h; sourceTree = "<group>"; };
148A1ECD0D10C23B0069A47C /* RefPtrHashMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefPtrHashMap.h; sourceTree = "<group>"; };
149559ED0DDCDDF700648087 /* DebuggerCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebuggerCallFrame.cpp; sourceTree = "<group>"; };
- 149B15E40D81F986009CB8C7 /* Opcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Opcode.h; path = VM/Opcode.h; sourceTree = "<group>"; };
- 149B15E50D81F986009CB8C7 /* Opcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Opcode.cpp; path = VM/Opcode.cpp; sourceTree = "<group>"; };
- 149B15E60D81F986009CB8C7 /* Machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Machine.h; path = VM/Machine.h; sourceTree = "<group>"; };
- 149B15E70D81F986009CB8C7 /* Machine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Machine.cpp; path = VM/Machine.cpp; sourceTree = "<group>"; };
- 149B15E80D81F986009CB8C7 /* CodeGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CodeGenerator.h; path = VM/CodeGenerator.h; sourceTree = "<group>"; };
- 149B15E90D81F986009CB8C7 /* CodeGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenerator.cpp; path = VM/CodeGenerator.cpp; sourceTree = "<group>"; };
- 149B16B80D82583F009CB8C7 /* RegisterID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterID.h; path = VM/RegisterID.h; sourceTree = "<group>"; };
- 149B1A9D0D86ED73009CB8C7 /* CodeBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CodeBlock.h; path = VM/CodeBlock.h; sourceTree = "<group>"; };
- 149B1A9E0D86ED73009CB8C7 /* CodeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CodeBlock.cpp; path = VM/CodeBlock.cpp; sourceTree = "<group>"; };
- 149B1AA10D86ED7C009CB8C7 /* Instruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Instruction.h; path = VM/Instruction.h; sourceTree = "<group>"; };
- 149B20D70D8A0891009CB8C7 /* LabelID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LabelID.h; path = VM/LabelID.h; sourceTree = "<group>"; };
- 149B24FF0D8AF6D1009CB8C7 /* Register.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Register.h; path = VM/Register.h; sourceTree = "<group>"; };
+ 149B24FF0D8AF6D1009CB8C7 /* Register.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Register.h; sourceTree = "<group>"; };
14A396A60CD2933100B5B4FF /* SymbolTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolTable.h; sourceTree = "<group>"; };
14ABB36E099C076400E2A24F /* JSValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSValue.h; sourceTree = "<group>"; };
14ABB454099C2A0F00E2A24F /* JSType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSType.h; sourceTree = "<group>"; };
14ABDF5D0A437FEF00ECCA01 /* JSCallbackObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObject.h; sourceTree = "<group>"; };
14ABDF5E0A437FEF00ECCA01 /* JSCallbackObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCallbackObject.cpp; sourceTree = "<group>"; };
14B8ECA60A5653980062BE54 /* JavaScriptCore.exp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.exports; path = JavaScriptCore.exp; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
- 14BD53F30A3E12D800BAF59C /* ExecState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecState.h; sourceTree = "<group>"; };
- 14BD53F40A3E12D800BAF59C /* ExecState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecState.cpp; sourceTree = "<group>"; };
14BD59BF0A3E8F9000BAF59C /* testapi */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testapi; sourceTree = BUILT_PRODUCTS_DIR; };
14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSContextRef.cpp; sourceTree = "<group>"; };
14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSContextRef.h; sourceTree = "<group>"; };
14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSValueRef.cpp; sourceTree = "<group>"; };
14BD5A2D0A3E91F600BAF59C /* testapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testapi.c; path = API/tests/testapi.c; sourceTree = "<group>"; };
- 14D792640DAA03FB001A9F05 /* RegisterFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterFile.h; path = VM/RegisterFile.h; sourceTree = "<group>"; };
- 14D792650DAA03FB001A9F05 /* RegisterFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterFile.cpp; path = VM/RegisterFile.cpp; sourceTree = "<group>"; };
+ 14D792640DAA03FB001A9F05 /* RegisterFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterFile.h; sourceTree = "<group>"; };
14D857740A4696C80032146C /* testapi.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = testapi.js; path = API/tests/testapi.js; sourceTree = "<group>"; };
14DA818E0D99FD2000B0A4FB /* JSActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSActivation.h; sourceTree = "<group>"; };
14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSActivation.cpp; sourceTree = "<group>"; };
14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObject.cpp; sourceTree = "<group>"; };
14F252560D08DD8D004ECFFF /* JSVariableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVariableObject.h; sourceTree = "<group>"; };
14F3488E0E95EF8A003648BC /* CollectorHeapIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectorHeapIterator.h; sourceTree = "<group>"; };
+ 180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CurrentTime.cpp; sourceTree = "<group>"; };
+ 180B9AF00F16C569009BDBC5 /* CurrentTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CurrentTime.h; sourceTree = "<group>"; };
1C61516A0EBAC7A00031376F /* ProfilerServer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ProfilerServer.mm; path = profiler/ProfilerServer.mm; sourceTree = "<group>"; };
1C61516B0EBAC7A00031376F /* ProfilerServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerServer.h; path = profiler/ProfilerServer.h; sourceTree = "<group>"; };
1C9051420BA9E8A70081E9D0 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; };
@@ -464,15 +511,16 @@
1C9051450BA9E8A70081E9D0 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScript.h; sourceTree = "<group>"; };
1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptCore.h; sourceTree = "<group>"; };
- 45E12D8806A49B0F00E9DF84 /* Shell.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Shell.cpp; path = kjs/Shell.cpp; sourceTree = "<group>"; tabWidth = 4; };
+ 45E12D8806A49B0F00E9DF84 /* jsc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jsc.cpp; sourceTree = "<group>"; tabWidth = 4; };
5186111D0CC824830081412B /* Deque.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Deque.h; sourceTree = "<group>"; };
51F0EB6105C86C6B00E6DF1B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libobjc.dylib; path = /usr/lib/libobjc.dylib; sourceTree = "<absolute>"; };
51F648D60BB4E2CA0033D760 /* RetainPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RetainPtr.h; sourceTree = "<group>"; };
- 5D53726D0E1C546B0021E549 /* Tracing.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = Tracing.d; sourceTree = "<group>"; };
+ 5D53726D0E1C546B0021E549 /* Tracing.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Tracing.d; sourceTree = "<group>"; };
5D53726E0E1C54880021E549 /* Tracing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tracing.h; sourceTree = "<group>"; };
5D53727D0E1C55EC0021E549 /* TracingDtrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TracingDtrace.h; sourceTree = "<group>"; };
5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libedit.dylib; path = /usr/lib/libedit.dylib; sourceTree = "<absolute>"; };
+ 5D6A566A0F05995500266145 /* Threading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Threading.cpp; sourceTree = "<group>"; };
5DA479650CFBCF56009328A0 /* TCPackedCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCPackedCache.h; sourceTree = "<group>"; };
5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MallocZoneSupport.h; sourceTree = "<group>"; };
5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitAvailability.h; sourceTree = "<group>"; };
@@ -498,7 +546,7 @@
6592C316098B7DE10003D4F6 /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = "<group>"; };
6592C317098B7DE10003D4F6 /* VectorTraits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VectorTraits.h; sourceTree = "<group>"; };
65B174BE09D1000200820339 /* chartables.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.c; fileEncoding = 30; path = chartables.c; sourceTree = "<group>"; };
- 65C02FBB0637462A003E7EE6 /* protect.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = protect.h; sourceTree = "<group>"; tabWidth = 8; };
+ 65C02FBB0637462A003E7EE6 /* Protect.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Protect.h; sourceTree = "<group>"; tabWidth = 8; };
65C647B3093EF8D60022C380 /* RefPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RefPtr.h; sourceTree = "<group>"; tabWidth = 8; };
65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSWrapperObject.cpp; sourceTree = "<group>"; };
65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSWrapperObject.h; sourceTree = "<group>"; };
@@ -524,17 +572,17 @@
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 /* StructureIDChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureIDChain.h; sourceTree = "<group>"; };
- 7E4EE70E0EBB7A5B005934AA /* StructureIDChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureIDChain.cpp; sourceTree = "<group>"; };
- 7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NodeInfo.h; path = kjs/NodeInfo.h; sourceTree = "<group>"; };
- 8613F4580E3A433E00C948FD /* SamplingTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SamplingTool.cpp; path = VM/SamplingTool.cpp; sourceTree = "<group>"; };
- 8613F4590E3A433E00C948FD /* SamplingTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SamplingTool.h; path = VM/SamplingTool.h; sourceTree = "<group>"; };
- 8683B02B0E636482004C19EE /* CTI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CTI.cpp; path = VM/CTI.cpp; sourceTree = "<group>"; };
- 8683B02C0E636482004C19EE /* CTI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CTI.h; path = VM/CTI.h; sourceTree = "<group>"; };
- 869081400E640C89000D36ED /* X86Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86Assembler.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>"; };
+ 7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NodeInfo.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>"; };
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>"; };
+ 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssembler.h; sourceTree = "<group>"; };
+ 86CC85A00EE79A4700288682 /* JITInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlineMethods.h; sourceTree = "<group>"; };
+ 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>"; };
905B02AD0E28640F006DF882 /* RefCountedLeakCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefCountedLeakCounter.cpp; sourceTree = "<group>"; };
90D3469B0E285280009492EE /* RefCountedLeakCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefCountedLeakCounter.h; sourceTree = "<group>"; };
9303F567099118FA00AD71B8 /* OwnPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnPtr.h; sourceTree = "<group>"; };
@@ -549,9 +597,9 @@
932F5BE10822A1C700736975 /* jsc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jsc; sourceTree = BUILT_PRODUCTS_DIR; };
93303FE80E6A72B500786E6A /* SmallStrings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SmallStrings.cpp; sourceTree = "<group>"; };
93303FEA0E6A72C000786E6A /* SmallStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmallStrings.h; sourceTree = "<group>"; };
- 933A3499038AE7C6008635CE /* grammar.y */ = {isa = PBXFileReference; explicitFileType = sourcecode.yacc; fileEncoding = 4; indentWidth = 4; path = grammar.y; sourceTree = "<group>"; tabWidth = 8; };
- 933A349A038AE7C6008635CE /* identifier.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = identifier.h; sourceTree = "<group>"; tabWidth = 8; };
- 933A349D038AE80F008635CE /* identifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = identifier.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ 933A3499038AE7C6008635CE /* Grammar.y */ = {isa = PBXFileReference; explicitFileType = sourcecode.yacc; fileEncoding = 4; indentWidth = 4; path = Grammar.y; sourceTree = "<group>"; tabWidth = 8; };
+ 933A349A038AE7C6008635CE /* Identifier.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Identifier.h; sourceTree = "<group>"; tabWidth = 8; };
+ 933A349D038AE80F008635CE /* Identifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Identifier.cpp; sourceTree = "<group>"; tabWidth = 8; };
935AF46909E9D9DB00ACD1D8 /* Forward.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Forward.h; sourceTree = "<group>"; };
935AF46B09E9D9DB00ACD1D8 /* UnusedParam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnusedParam.h; sourceTree = "<group>"; };
937013470CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pcre_ucp_searchfuncs.cpp; sourceTree = "<group>"; };
@@ -568,9 +616,9 @@
93E26BD308B1514100F85226 /* pcre_xclass.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pcre_xclass.cpp; sourceTree = "<group>"; tabWidth = 8; };
93E26BE508B1517100F85226 /* pcre_internal.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = pcre_internal.h; sourceTree = "<group>"; tabWidth = 8; };
93E26BFC08B151D400F85226 /* ucpinternal.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = ucpinternal.h; sourceTree = "<group>"; tabWidth = 8; };
- 93F0B3A909BB4DC00068FCE3 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Parser.cpp; path = kjs/Parser.cpp; sourceTree = "<group>"; };
- 93F0B3AA09BB4DC00068FCE3 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = kjs/Parser.h; sourceTree = "<group>"; };
- 93F1981A08245AAE001E9ABC /* keywords.table */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = text; path = keywords.table; sourceTree = "<group>"; tabWidth = 8; };
+ 93F0B3A909BB4DC00068FCE3 /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Parser.cpp; sourceTree = "<group>"; };
+ 93F0B3AA09BB4DC00068FCE3 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Parser.h; sourceTree = "<group>"; };
+ 93F1981A08245AAE001E9ABC /* Keywords.table */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = text; path = Keywords.table; sourceTree = "<group>"; tabWidth = 8; };
952C63AC0E4777D600C13936 /* JSProfilerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSProfilerPrivate.h; sourceTree = "<group>"; };
95742F630DD11F5A000917FB /* Profile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Profile.cpp; path = profiler/Profile.cpp; sourceTree = "<group>"; };
95742F640DD11F5A000917FB /* Profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Profile.h; path = profiler/Profile.h; sourceTree = "<group>"; };
@@ -587,14 +635,34 @@
95E3BC040E1AE68200B2D1C1 /* CallIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CallIdentifier.h; path = profiler/CallIdentifier.h; sourceTree = "<group>"; };
95FDFA130E22998F0006FB00 /* HeavyProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HeavyProfile.cpp; path = profiler/HeavyProfile.cpp; sourceTree = "<group>"; };
95FDFA150E2299980006FB00 /* HeavyProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HeavyProfile.h; path = profiler/HeavyProfile.h; sourceTree = "<group>"; };
- 960097A50EBABB58007A7297 /* LabelScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LabelScope.h; path = kjs/LabelScope.h; sourceTree = "<group>"; };
+ 960097A50EBABB58007A7297 /* LabelScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelScope.h; sourceTree = "<group>"; };
+ 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssemblerBuffer.h; sourceTree = "<group>"; };
+ 9688CB140ED12B4E001D649F /* X86Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86Assembler.h; sourceTree = "<group>"; };
+ 969A07200ED1CE3300F1F681 /* BytecodeGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BytecodeGenerator.cpp; sourceTree = "<group>"; };
+ 969A07210ED1CE3300F1F681 /* BytecodeGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeGenerator.h; sourceTree = "<group>"; };
+ 969A07270ED1CE6900F1F681 /* Label.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Label.h; sourceTree = "<group>"; };
+ 969A07280ED1CE6900F1F681 /* RegisterID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterID.h; sourceTree = "<group>"; };
+ 969A07290ED1CE6900F1F681 /* SegmentedVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SegmentedVector.h; sourceTree = "<group>"; };
+ 969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeBlock.cpp; sourceTree = "<group>"; };
+ 969A07910ED1D3AE00F1F681 /* CodeBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlock.h; sourceTree = "<group>"; };
+ 969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EvalCodeCache.h; sourceTree = "<group>"; };
+ 969A07930ED1D3AE00F1F681 /* Instruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Instruction.h; sourceTree = "<group>"; };
+ 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>"; };
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; name = ExceptionHelpers.h; path = VM/ExceptionHelpers.h; sourceTree = "<group>"; };
- A72701B40DADE94900E548D7 /* ExceptionHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExceptionHelpers.cpp; path = VM/ExceptionHelpers.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>"; };
- A7C31DA80DBEBA4300FDF8EB /* SegmentedVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SegmentedVector.h; path = VM/SegmentedVector.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>"; };
+ 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>"; };
+ A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocator.cpp; sourceTree = "<group>"; };
A7E42C180E3938830065A544 /* JSStaticScopeObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStaticScopeObject.h; sourceTree = "<group>"; };
A7E42C190E3938830065A544 /* JSStaticScopeObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStaticScopeObject.cpp; sourceTree = "<group>"; };
A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObjectFunctions.h; sourceTree = "<group>"; };
@@ -650,6 +718,8 @@
BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectPrototype.h; sourceTree = "<group>"; };
BC2680E60E16D52300A06E92 /* NumberConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NumberConstructor.lut.h; sourceTree = "<group>"; };
BC3046060E1F497F003232CF /* Error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Error.h; sourceTree = "<group>"; };
+ BC3135620F302FA3003DFD3A /* DebuggerActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerActivation.h; sourceTree = "<group>"; };
+ BC3135630F302FA3003DFD3A /* DebuggerActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebuggerActivation.cpp; sourceTree = "<group>"; };
BC337BDE0E1AF0B80076918A /* GetterSetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetterSetter.h; sourceTree = "<group>"; };
BC337BEA0E1B00CB0076918A /* Error.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Error.cpp; sourceTree = "<group>"; };
BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassInfo.h; sourceTree = "<group>"; };
@@ -664,11 +734,13 @@
BC7F8FB80E19D1C3008632C0 /* JSNumberCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNumberCell.h; sourceTree = "<group>"; };
BC7F8FBA0E19D1EF008632C0 /* JSCell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCell.cpp; sourceTree = "<group>"; };
BC8F3CCF0DAF17BA00577A80 /* ConstructData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstructData.h; sourceTree = "<group>"; };
- BC9041470EB9250900FE26FA /* StructureIDTransitionTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureIDTransitionTable.h; sourceTree = "<group>"; };
+ BC9041470EB9250900FE26FA /* StructureTransitionTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureTransitionTable.h; sourceTree = "<group>"; };
BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyMapHashTable.h; sourceTree = "<group>"; };
BC9BB95B0E19680600DF8855 /* InternalFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InternalFunction.cpp; sourceTree = "<group>"; };
BCA62DFE0E2826230004F30D /* CallData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallData.cpp; sourceTree = "<group>"; };
BCA62DFF0E2826310004F30D /* ConstructData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstructData.cpp; sourceTree = "<group>"; };
+ BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureStubInfo.h; sourceTree = "<group>"; };
+ BCCF0D0B0EF0B8A500413C8F /* StructureStubInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureStubInfo.cpp; sourceTree = "<group>"; };
BCD202BD0E1706A7002C7E82 /* RegExpConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpConstructor.cpp; sourceTree = "<group>"; };
BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpConstructor.h; sourceTree = "<group>"; };
BCD202BF0E1706A7002C7E82 /* RegExpPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpPrototype.cpp; sourceTree = "<group>"; };
@@ -679,11 +751,13 @@
BCD203470E17135E002C7E82 /* DatePrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatePrototype.cpp; sourceTree = "<group>"; };
BCD203480E17135E002C7E82 /* DatePrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatePrototype.h; sourceTree = "<group>"; };
BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatePrototype.lut.h; sourceTree = "<group>"; };
- BCDE3AB00E6C82CF001453A7 /* StructureID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureID.cpp; sourceTree = "<group>"; };
- BCDE3AB10E6C82CF001453A7 /* StructureID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureID.h; sourceTree = "<group>"; };
+ BCDE3AB00E6C82CF001453A7 /* Structure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Structure.cpp; sourceTree = "<group>"; };
+ BCDE3AB10E6C82CF001453A7 /* Structure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Structure.h; sourceTree = "<group>"; };
BCF605110E203EF800B9A64D /* ArgList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArgList.cpp; sourceTree = "<group>"; };
BCF605120E203EF800B9A64D /* ArgList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgList.h; sourceTree = "<group>"; };
BCF6553B0A2048DE0038A194 /* MathExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MathExtras.h; sourceTree = "<group>"; };
+ BCFD8C900EEB2EE700283848 /* JumpTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JumpTable.cpp; sourceTree = "<group>"; };
+ BCFD8C910EEB2EE700283848 /* JumpTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JumpTable.h; sourceTree = "<group>"; };
C0A2723F0E509F1E00E96E15 /* NotFound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotFound.h; sourceTree = "<group>"; };
D21202280AD4310C00ED79B6 /* DateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateMath.cpp; sourceTree = "<group>"; };
D21202290AD4310C00ED79B6 /* DateMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateMath.h; sourceTree = "<group>"; };
@@ -707,15 +781,14 @@
E1EE798B0D6CA53D00FEA3BA /* MessageQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageQueue.h; sourceTree = "<group>"; };
E1EF79A80CE97BA60088D500 /* UTF8.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UTF8.cpp; sourceTree = "<group>"; };
E1EF79A90CE97BA60088D500 /* UTF8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UTF8.h; sourceTree = "<group>"; };
- F5BB2BC5030F772101FCFE1D /* completion.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = completion.h; sourceTree = "<group>"; tabWidth = 8; };
+ F5BB2BC5030F772101FCFE1D /* Completion.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Completion.h; sourceTree = "<group>"; tabWidth = 8; };
F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptCorePrefix.h; sourceTree = "<group>"; tabWidth = 8; };
- F5FFE656026B47A6018635CA /* nodes2string.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; name = nodes2string.cpp; path = kjs/nodes2string.cpp; sourceTree = "<group>"; tabWidth = 8; };
F68EBB8C0255D4C601FF60F7 /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; tabWidth = 8; };
F692A84D0255597D01FF60F7 /* ArrayPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayPrototype.cpp; sourceTree = "<group>"; tabWidth = 8; };
F692A84E0255597D01FF60F7 /* ArrayPrototype.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = ArrayPrototype.h; sourceTree = "<group>"; tabWidth = 8; };
F692A8500255597D01FF60F7 /* BooleanObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BooleanObject.cpp; sourceTree = "<group>"; tabWidth = 8; };
- F692A8520255597D01FF60F7 /* collector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = collector.cpp; sourceTree = "<group>"; tabWidth = 8; };
- F692A8530255597D01FF60F7 /* collector.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = collector.h; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8520255597D01FF60F7 /* Collector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Collector.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8530255597D01FF60F7 /* Collector.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Collector.h; sourceTree = "<group>"; tabWidth = 8; };
F692A8540255597D01FF60F7 /* create_hash_table */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = text.script.perl; path = create_hash_table; sourceTree = "<group>"; tabWidth = 8; };
F692A8580255597D01FF60F7 /* Debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Debugger.cpp; sourceTree = "<group>"; tabWidth = 8; };
F692A8590255597D01FF60F7 /* Debugger.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Debugger.h; sourceTree = "<group>"; tabWidth = 8; };
@@ -724,27 +797,26 @@
F692A85E0255597D01FF60F7 /* JSFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFunction.cpp; sourceTree = "<group>"; tabWidth = 8; };
F692A85F0255597D01FF60F7 /* JSFunction.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = JSFunction.h; sourceTree = "<group>"; tabWidth = 8; };
F692A8620255597D01FF60F7 /* JSString.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = JSString.h; sourceTree = "<group>"; tabWidth = 8; };
- F692A8630255597D01FF60F7 /* interpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = interpreter.cpp; sourceTree = "<group>"; tabWidth = 8; };
- F692A8640255597D01FF60F7 /* interpreter.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = interpreter.h; sourceTree = "<group>"; tabWidth = 8; };
- F692A8650255597D01FF60F7 /* lexer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lexer.cpp; path = kjs/lexer.cpp; sourceTree = "<group>"; tabWidth = 8; };
- F692A8660255597D01FF60F7 /* lexer.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = lexer.h; path = kjs/lexer.h; sourceTree = "<group>"; tabWidth = 8; };
- F692A8680255597D01FF60F7 /* lookup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lookup.cpp; sourceTree = "<group>"; tabWidth = 8; };
- F692A8690255597D01FF60F7 /* lookup.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = lookup.h; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8650255597D01FF60F7 /* Lexer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lexer.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8660255597D01FF60F7 /* Lexer.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Lexer.h; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8680255597D01FF60F7 /* Lookup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lookup.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8690255597D01FF60F7 /* Lookup.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Lookup.h; sourceTree = "<group>"; tabWidth = 8; };
F692A86A0255597D01FF60F7 /* MathObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathObject.cpp; sourceTree = "<group>"; tabWidth = 8; };
F692A86B0255597D01FF60F7 /* MathObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = MathObject.h; sourceTree = "<group>"; tabWidth = 8; };
- F692A86D0255597D01FF60F7 /* nodes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; name = nodes.cpp; path = kjs/nodes.cpp; sourceTree = "<group>"; tabWidth = 8; };
- F692A86E0255597D01FF60F7 /* nodes.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = nodes.h; path = kjs/nodes.h; sourceTree = "<group>"; tabWidth = 8; };
+ F692A86D0255597D01FF60F7 /* Nodes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Nodes.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ F692A86E0255597D01FF60F7 /* Nodes.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Nodes.h; sourceTree = "<group>"; tabWidth = 8; };
F692A8700255597D01FF60F7 /* NumberObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NumberObject.cpp; sourceTree = "<group>"; tabWidth = 8; };
F692A8710255597D01FF60F7 /* NumberObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = NumberObject.h; sourceTree = "<group>"; tabWidth = 8; };
- F692A8770255597D01FF60F7 /* operations.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = operations.cpp; sourceTree = "<group>"; tabWidth = 8; };
- F692A8780255597D01FF60F7 /* operations.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = operations.h; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8770255597D01FF60F7 /* Operations.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Operations.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8780255597D01FF60F7 /* Operations.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Operations.h; sourceTree = "<group>"; tabWidth = 8; };
F692A87B0255597D01FF60F7 /* RegExpObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpObject.cpp; sourceTree = "<group>"; tabWidth = 8; };
F692A87C0255597D01FF60F7 /* RegExpObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RegExpObject.h; sourceTree = "<group>"; tabWidth = 8; };
- F692A87D0255597D01FF60F7 /* regexp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = regexp.cpp; sourceTree = "<group>"; tabWidth = 8; };
- F692A87E0255597D01FF60F7 /* regexp.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = regexp.h; sourceTree = "<group>"; tabWidth = 8; };
- F692A8850255597D01FF60F7 /* ustring.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ustring.cpp; sourceTree = "<group>"; tabWidth = 8; };
- F692A8860255597D01FF60F7 /* ustring.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = ustring.h; sourceTree = "<group>"; tabWidth = 8; };
+ F692A87D0255597D01FF60F7 /* RegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExp.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ F692A87E0255597D01FF60F7 /* RegExp.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RegExp.h; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8850255597D01FF60F7 /* UString.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UString.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ F692A8860255597D01FF60F7 /* UString.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = UString.h; sourceTree = "<group>"; tabWidth = 8; };
F692A8870255597D01FF60F7 /* JSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSValue.cpp; sourceTree = "<group>"; tabWidth = 8; };
+ FE1B44790ECCD73B004F4DD1 /* StdLibExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StdLibExtras.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -795,8 +867,8 @@
children = (
932F5BD90822A1C700736975 /* JavaScriptCore.framework */,
932F5BE10822A1C700736975 /* jsc */,
- 14BD59BF0A3E8F9000BAF59C /* testapi */,
141211200A48793C00480255 /* minidom */,
+ 14BD59BF0A3E8F9000BAF59C /* testapi */,
);
name = Products;
sourceTree = "<group>";
@@ -815,19 +887,24 @@
isa = PBXGroup;
children = (
937B63CC09E766D200A671DD /* DerivedSources.make */,
+ F692A8540255597D01FF60F7 /* create_hash_table */,
14B8ECA60A5653980062BE54 /* JavaScriptCore.exp */,
F5C290E60284F98E018635CA /* JavaScriptCorePrefix.h */,
659126BC0BDD1728001921FB /* AllInOneFile.cpp */,
+ 45E12D8806A49B0F00E9DF84 /* jsc.cpp */,
+ F68EBB8C0255D4C601FF60F7 /* config.h */,
1432EBD70A34CAD400717B9F /* API */,
- 149B15DF0D81F887009CB8C7 /* compiler */,
+ 9688CB120ED12B4E001D649F /* assembler */,
+ 969A078F0ED1D3AE00F1F681 /* bytecode */,
+ 7E39D81D0EC38EFA003AF11A /* bytecompiler */,
1480DB9A0DDC2231003CFDF2 /* debugger */,
- 65417200039E01BA0058BFEB /* kjs */,
- 8690813F0E640C89000D36ED /* masm */,
+ 1429D77A0ED20D7300B89619 /* interpreter */,
+ 1429D92C0ED22D7000B89619 /* jit */,
+ 7E39D8370EC3A388003AF11A /* parser */,
65417203039E01F90058BFEB /* pcre */,
95AB831A0DA42C6900BC83F3 /* profiler */,
7EF6E0BB0EB7A1EC0079AFAF /* runtime */,
141211000A48772600480255 /* tests */,
- 149B15E00D81F88D009CB8C7 /* vm */,
869083120E6518D7000D36ED /* wrec */,
65162EF108E6A21C007556CD /* wtf */,
1C90513E0BA9E8830081E9D0 /* Configurations */,
@@ -845,9 +922,9 @@
6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */,
6560A63D04B3B69F008AE952 /* CoreServices.framework */,
51F0EB6105C86C6B00E6DF1B /* Foundation.framework */,
+ 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */,
9322A00306C341D3009067BB /* libicucore.dylib */,
51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */,
- 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -860,22 +937,49 @@
144005170A531CB50005F061 /* minidom */,
14BD5A2D0A3E91F600BAF59C /* testapi.c */,
14D857740A4696C80032146C /* testapi.js */,
- 45E12D8806A49B0F00E9DF84 /* Shell.cpp */,
);
name = tests;
sourceTree = "<group>";
tabWidth = 4;
usesTabs = 0;
};
+ 1429D77A0ED20D7300B89619 /* interpreter */ = {
+ isa = PBXGroup;
+ children = (
+ 1429D8DB0ED2205B00B89619 /* CallFrame.cpp */,
+ 1429D8DC0ED2205B00B89619 /* CallFrame.h */,
+ 1429D7D30ED2128200B89619 /* Interpreter.cpp */,
+ 1429D77B0ED20D7300B89619 /* Interpreter.h */,
+ 149B24FF0D8AF6D1009CB8C7 /* Register.h */,
+ 1429D85B0ED218E900B89619 /* RegisterFile.cpp */,
+ 14D792640DAA03FB001A9F05 /* RegisterFile.h */,
+ );
+ path = interpreter;
+ sourceTree = "<group>";
+ };
+ 1429D92C0ED22D7000B89619 /* jit */ = {
+ isa = PBXGroup;
+ children = (
+ A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */,
+ A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */,
+ A782F1A40EEC9FA20036273F /* ExecutableAllocatorPosix.cpp */,
+ 1429D92D0ED22D7000B89619 /* JIT.cpp */,
+ 1429D92E0ED22D7000B89619 /* JIT.h */,
+ 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */,
+ 86CC85A20EE79B7400288682 /* JITCall.cpp */,
+ 86CC85A00EE79A4700288682 /* JITInlineMethods.h */,
+ 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */,
+ );
+ path = jit;
+ sourceTree = "<group>";
+ };
1432EBD70A34CAD400717B9F /* API */ = {
isa = PBXGroup;
children = (
- 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */,
1482B78A0A4305AB00517CFC /* APICast.h */,
- 1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */,
- 1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */,
1421359A0A677F4F00A8195E /* JSBase.cpp */,
142711380A460BBB0080EEEA /* JSBase.h */,
+ 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */,
1440F8AD0A508D200005F061 /* JSCallbackConstructor.cpp */,
1440F8AC0A508D200005F061 /* JSCallbackConstructor.h */,
1440F8900A508B100005F061 /* JSCallbackFunction.cpp */,
@@ -898,6 +1002,8 @@
146AAB2A0B66A84900E55F16 /* JSStringRefCF.h */,
14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */,
1482B6EA0A4300B300517CFC /* JSValueRef.h */,
+ 1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */,
+ 1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */,
E124A8F60E555775003091F1 /* OpaqueJSString.cpp */,
E124A8F50E555775003091F1 /* OpaqueJSString.h */,
5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */,
@@ -914,12 +1020,12 @@
1440F6410A4F8B6A0005F061 /* JSNode.h */,
144007560A5370D20005F061 /* JSNodeList.c */,
144007550A5370D20005F061 /* JSNodeList.h */,
- 141211020A48780900480255 /* minidom.c */,
- 1412110D0A48788700480255 /* minidom.js */,
144005200A531D3B0005F061 /* Node.c */,
1440051F0A531D3B0005F061 /* Node.h */,
144007490A536CC20005F061 /* NodeList.c */,
144007480A536CC20005F061 /* NodeList.h */,
+ 141211020A48780900480255 /* minidom.c */,
+ 1412110D0A48788700480255 /* minidom.js */,
);
name = minidom;
path = API;
@@ -932,54 +1038,12 @@
F692A8590255597D01FF60F7 /* Debugger.h */,
149559ED0DDCDDF700648087 /* DebuggerCallFrame.cpp */,
1480DB9B0DDC227F003CFDF2 /* DebuggerCallFrame.h */,
+ BC3135630F302FA3003DFD3A /* DebuggerActivation.cpp */,
+ BC3135620F302FA3003DFD3A /* DebuggerActivation.h */,
);
path = debugger;
sourceTree = "<group>";
};
- 149B15DF0D81F887009CB8C7 /* compiler */ = {
- isa = PBXGroup;
- children = (
- 960097A50EBABB58007A7297 /* LabelScope.h */,
- 149B15E90D81F986009CB8C7 /* CodeGenerator.cpp */,
- 149B15E80D81F986009CB8C7 /* CodeGenerator.h */,
- 149B20D70D8A0891009CB8C7 /* LabelID.h */,
- F692A8650255597D01FF60F7 /* lexer.cpp */,
- F692A8660255597D01FF60F7 /* lexer.h */,
- 7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */,
- F692A86D0255597D01FF60F7 /* nodes.cpp */,
- F692A86E0255597D01FF60F7 /* nodes.h */,
- F5FFE656026B47A6018635CA /* nodes2string.cpp */,
- 93F0B3A909BB4DC00068FCE3 /* Parser.cpp */,
- 93F0B3AA09BB4DC00068FCE3 /* Parser.h */,
- 149B16B80D82583F009CB8C7 /* RegisterID.h */,
- A7C31DA80DBEBA4300FDF8EB /* SegmentedVector.h */,
- );
- name = compiler;
- sourceTree = "<group>";
- };
- 149B15E00D81F88D009CB8C7 /* vm */ = {
- isa = PBXGroup;
- children = (
- 8683B02B0E636482004C19EE /* CTI.cpp */,
- 8683B02C0E636482004C19EE /* CTI.h */,
- 8613F4580E3A433E00C948FD /* SamplingTool.cpp */,
- 8613F4590E3A433E00C948FD /* SamplingTool.h */,
- 149B1A9E0D86ED73009CB8C7 /* CodeBlock.cpp */,
- 149B1A9D0D86ED73009CB8C7 /* CodeBlock.h */,
- A72701B40DADE94900E548D7 /* ExceptionHelpers.cpp */,
- A72701B30DADE94900E548D7 /* ExceptionHelpers.h */,
- 149B1AA10D86ED7C009CB8C7 /* Instruction.h */,
- 149B15E70D81F986009CB8C7 /* Machine.cpp */,
- 149B15E60D81F986009CB8C7 /* Machine.h */,
- 149B15E50D81F986009CB8C7 /* Opcode.cpp */,
- 149B15E40D81F986009CB8C7 /* Opcode.h */,
- 149B24FF0D8AF6D1009CB8C7 /* Register.h */,
- 14D792650DAA03FB001A9F05 /* RegisterFile.cpp */,
- 14D792640DAA03FB001A9F05 /* RegisterFile.h */,
- );
- name = vm;
- sourceTree = "<group>";
- };
1C90513E0BA9E8830081E9D0 /* Configurations */ = {
isa = PBXGroup;
children = (
@@ -997,17 +1061,17 @@
isa = PBXGroup;
children = (
BC18C5230E16FC8A00B34460 /* ArrayPrototype.lut.h */,
- 65B174BE09D1000200820339 /* chartables.c */,
BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */,
- 65FB3F4809D11B2400F49DEB /* grammar.cpp */,
- BC18C52F0E16FCEB00B34460 /* grammar.h */,
- BC18C52D0E16FCE100B34460 /* lexer.lut.h */,
BC18C5290E16FCC200B34460 /* MathObject.lut.h */,
BC2680E60E16D52300A06E92 /* NumberConstructor.lut.h */,
BCD202D50E170708002C7E82 /* RegExpConstructor.lut.h */,
BC18C52B0E16FCD200B34460 /* RegExpObject.lut.h */,
BC18C5250E16FCA700B34460 /* StringPrototype.lut.h */,
5D53727D0E1C55EC0021E549 /* TracingDtrace.h */,
+ 65B174BE09D1000200820339 /* chartables.c */,
+ 65FB3F4809D11B2400F49DEB /* grammar.cpp */,
+ BC18C52F0E16FCEB00B34460 /* grammar.h */,
+ BC18C52D0E16FCE100B34460 /* lexer.lut.h */,
);
name = "Derived Sources";
path = DerivedSources/JavaScriptCore;
@@ -1020,11 +1084,15 @@
children = (
06D358A00DAAD9C4003B174E /* mac */,
E195678D09E7CF1200B89D13 /* unicode */,
- 93AA4F770957251F0084B3A7 /* AlwaysInline.h */,
938C4F690CA06BC700D9310A /* ASCIICType.h */,
+ E1A596370DE3E1C300C17E37 /* AVLTree.h */,
+ 93AA4F770957251F0084B3A7 /* AlwaysInline.h */,
65E217B808E7EECC0023E5F6 /* Assertions.cpp */,
65E217B708E7EECC0023E5F6 /* Assertions.h */,
- E1A596370DE3E1C300C17E37 /* AVLTree.h */,
+ A7A1F7AA0F252B3C00E184E2 /* ByteArray.cpp */,
+ A7A1F7AB0F252B3C00E184E2 /* ByteArray.h */,
+ 180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */,
+ 180B9AF00F16C569009BDBC5 /* CurrentTime.h */,
5186111D0CC824830081412B /* Deque.h */,
938C4F6B0CA06BCE00D9310A /* DisallowCType.h */,
65E217B908E7EECC0023E5F6 /* FastMalloc.cpp */,
@@ -1053,61 +1121,34 @@
9303F567099118FA00AD71B8 /* OwnPtr.h */,
6580F795094070560082C219 /* PassRefPtr.h */,
65D6D87E09B5A32E0002E4D7 /* Platform.h */,
+ 0B1F921B0F17502D0036468E /* PtrAndFlags.h */,
+ 088FA5B90EF76D4300578E6F /* RandomNumber.cpp */,
+ 088FA5BA0EF76D4300578E6F /* RandomNumber.h */,
+ 08E279E80EF83B10007DB523 /* RandomNumberSeed.h */,
1419D32C0CEA7CDE00FF507A /* RefCounted.h */,
- 90D3469B0E285280009492EE /* RefCountedLeakCounter.h */,
905B02AD0E28640F006DF882 /* RefCountedLeakCounter.cpp */,
+ 90D3469B0E285280009492EE /* RefCountedLeakCounter.h */,
65C647B3093EF8D60022C380 /* RefPtr.h */,
148A1ECD0D10C23B0069A47C /* RefPtrHashMap.h */,
51F648D60BB4E2CA0033D760 /* RetainPtr.h */,
+ FE1B44790ECCD73B004F4DD1 /* StdLibExtras.h */,
E11D51750B2E798D0056C188 /* StringExtras.h */,
5DA479650CFBCF56009328A0 /* TCPackedCache.h */,
6541BD6E08E80A17002CBEE7 /* TCPageMap.h */,
6541BD6F08E80A17002CBEE7 /* TCSpinLock.h */,
6541BD7008E80A17002CBEE7 /* TCSystemAlloc.cpp */,
6541BD7108E80A17002CBEE7 /* TCSystemAlloc.h */,
+ E1B7C8BD0DA3A3360074B0DC /* ThreadSpecific.h */,
+ 5D6A566A0F05995500266145 /* Threading.cpp */,
E1EE79220D6C95CD00FEA3BA /* Threading.h */,
E1EE793C0D6C9B9200FEA3BA /* ThreadingPthreads.cpp */,
- E1B7C8BD0DA3A3360074B0DC /* ThreadSpecific.h */,
935AF46B09E9D9DB00ACD1D8 /* UnusedParam.h */,
6592C316098B7DE10003D4F6 /* Vector.h */,
6592C317098B7DE10003D4F6 /* VectorTraits.h */,
- );
- path = wtf;
- sourceTree = "<group>";
- tabWidth = 4;
- usesTabs = 0;
- };
- 65417200039E01BA0058BFEB /* kjs */ = {
- isa = PBXGroup;
- children = (
- 6507D2970E871E4A00D7D896 /* TypeInfo.h */,
- F692A8520255597D01FF60F7 /* collector.cpp */,
- F692A8530255597D01FF60F7 /* collector.h */,
- F5BB2BC5030F772101FCFE1D /* completion.h */,
- F68EBB8C0255D4C601FF60F7 /* config.h */,
- F692A8540255597D01FF60F7 /* create_hash_table */,
651F6412039D5B5F0078395C /* dtoa.cpp */,
651F6413039D5B5F0078395C /* dtoa.h */,
- 933A3499038AE7C6008635CE /* grammar.y */,
- 933A349D038AE80F008635CE /* identifier.cpp */,
- 933A349A038AE7C6008635CE /* identifier.h */,
- F692A8630255597D01FF60F7 /* interpreter.cpp */,
- F692A8640255597D01FF60F7 /* interpreter.h */,
- 93F1981A08245AAE001E9ABC /* keywords.table */,
- F692A8680255597D01FF60F7 /* lookup.cpp */,
- F692A8690255597D01FF60F7 /* lookup.h */,
- F692A8770255597D01FF60F7 /* operations.cpp */,
- F692A8780255597D01FF60F7 /* operations.h */,
- 65C02FBB0637462A003E7EE6 /* protect.h */,
- F692A87D0255597D01FF60F7 /* regexp.cpp */,
- F692A87E0255597D01FF60F7 /* regexp.h */,
- 869EBCB60E8C6D4A008722CC /* ResultType.h */,
- 65E866ED0DD59AFA00A2B2A1 /* SourceProvider.h */,
- 65E866EE0DD59AFA00A2B2A1 /* SourceCode.h */,
- F692A8850255597D01FF60F7 /* ustring.cpp */,
- F692A8860255597D01FF60F7 /* ustring.h */,
);
- path = kjs;
+ path = wtf;
sourceTree = "<group>";
tabWidth = 4;
usesTabs = 0;
@@ -1129,6 +1170,38 @@
tabWidth = 4;
usesTabs = 0;
};
+ 7E39D81D0EC38EFA003AF11A /* bytecompiler */ = {
+ isa = PBXGroup;
+ children = (
+ 969A07200ED1CE3300F1F681 /* BytecodeGenerator.cpp */,
+ 969A07210ED1CE3300F1F681 /* BytecodeGenerator.h */,
+ 969A07270ED1CE6900F1F681 /* Label.h */,
+ 960097A50EBABB58007A7297 /* LabelScope.h */,
+ 969A07280ED1CE6900F1F681 /* RegisterID.h */,
+ 969A07290ED1CE6900F1F681 /* SegmentedVector.h */,
+ );
+ path = bytecompiler;
+ sourceTree = "<group>";
+ };
+ 7E39D8370EC3A388003AF11A /* parser */ = {
+ isa = PBXGroup;
+ children = (
+ 933A3499038AE7C6008635CE /* Grammar.y */,
+ 93F1981A08245AAE001E9ABC /* Keywords.table */,
+ F692A8650255597D01FF60F7 /* Lexer.cpp */,
+ F692A8660255597D01FF60F7 /* Lexer.h */,
+ 7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */,
+ F692A86D0255597D01FF60F7 /* Nodes.cpp */,
+ F692A86E0255597D01FF60F7 /* Nodes.h */,
+ 93F0B3A909BB4DC00068FCE3 /* Parser.cpp */,
+ 93F0B3AA09BB4DC00068FCE3 /* Parser.h */,
+ 869EBCB60E8C6D4A008722CC /* ResultType.h */,
+ 65E866EE0DD59AFA00A2B2A1 /* SourceCode.h */,
+ 65E866ED0DD59AFA00A2B2A1 /* SourceProvider.h */,
+ );
+ path = parser;
+ sourceTree = "<group>";
+ };
7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
isa = PBXGroup;
children = (
@@ -1150,9 +1223,13 @@
BCA62DFE0E2826230004F30D /* CallData.cpp */,
145C507F0D9DF63B0088F6B9 /* CallData.h */,
BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */,
+ F692A8520255597D01FF60F7 /* Collector.cpp */,
+ F692A8530255597D01FF60F7 /* Collector.h */,
14F3488E0E95EF8A003648BC /* CollectorHeapIterator.h */,
65EA73620BAE35D1001BB560 /* CommonIdentifiers.cpp */,
65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */,
+ 969A09220ED1E09C00F1F681 /* Completion.cpp */,
+ F5BB2BC5030F772101FCFE1D /* Completion.h */,
BCA62DFF0E2826310004F30D /* ConstructData.cpp */,
BC8F3CCF0DAF17BA00577A80 /* ConstructData.h */,
BCD203450E17135E002C7E82 /* DateConstructor.cpp */,
@@ -1171,8 +1248,8 @@
BC02E98B0E183E38000F9297 /* ErrorInstance.h */,
BC02E9060E1839DB000F9297 /* ErrorPrototype.cpp */,
BC02E9070E1839DB000F9297 /* ErrorPrototype.h */,
- 14BD53F40A3E12D800BAF59C /* ExecState.cpp */,
- 14BD53F30A3E12D800BAF59C /* ExecState.h */,
+ 1429D8770ED21ACD00B89619 /* ExceptionHelpers.cpp */,
+ A72701B30DADE94900E548D7 /* ExceptionHelpers.h */,
BC2680C00E16D4E900A06E92 /* FunctionConstructor.cpp */,
BC2680C10E16D4E900A06E92 /* FunctionConstructor.h */,
F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
@@ -1181,6 +1258,8 @@
BC337BDE0E1AF0B80076918A /* GetterSetter.h */,
BC257DED0E1F52ED0016B6C9 /* GlobalEvalFunction.cpp */,
BC257DEE0E1F52ED0016B6C9 /* GlobalEvalFunction.h */,
+ 933A349D038AE80F008635CE /* Identifier.cpp */,
+ 933A349A038AE7C6008635CE /* Identifier.h */,
E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */,
E178633F0D9BEC0000D74E75 /* InitializeThreading.h */,
BC9BB95B0E19680600DF8855 /* InternalFunction.cpp */,
@@ -1189,6 +1268,8 @@
14DA818E0D99FD2000B0A4FB /* JSActivation.h */,
93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */,
938772E5038BFE19008635CE /* JSArray.h */,
+ A791EF270F11E07900AE1F68 /* JSByteArray.cpp */,
+ A791EF260F11E07900AE1F68 /* JSByteArray.h */,
BC7F8FBA0E19D1EF008632C0 /* JSCell.cpp */,
BC1167D80E19BCC9008066DD /* JSCell.h */,
F692A85E0255597D01FF60F7 /* JSFunction.cpp */,
@@ -1222,6 +1303,8 @@
14F252560D08DD8D004ECFFF /* JSVariableObject.h */,
65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */,
65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */,
+ F692A8680255597D01FF60F7 /* Lookup.cpp */,
+ F692A8690255597D01FF60F7 /* Lookup.h */,
F692A86A0255597D01FF60F7 /* MathObject.cpp */,
F692A86B0255597D01FF60F7 /* MathObject.h */,
BC02E9080E1839DB000F9297 /* NativeErrorConstructor.cpp */,
@@ -1238,14 +1321,19 @@
BC2680C70E16D4E900A06E92 /* ObjectConstructor.h */,
BC2680C80E16D4E900A06E92 /* ObjectPrototype.cpp */,
BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */,
+ F692A8770255597D01FF60F7 /* Operations.cpp */,
+ F692A8780255597D01FF60F7 /* Operations.h */,
BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */,
65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */,
65400C100A69BAF200509887 /* PropertyNameArray.h */,
65621E6B089E859700760F35 /* PropertySlot.cpp */,
65621E6C089E859700760F35 /* PropertySlot.h */,
+ 65C02FBB0637462A003E7EE6 /* Protect.h */,
BC257DF10E1F53740016B6C9 /* PrototypeFunction.cpp */,
BC257DF20E1F53740016B6C9 /* PrototypeFunction.h */,
147B84620E6DE6B1004775A4 /* PutPropertySlot.h */,
+ F692A87D0255597D01FF60F7 /* RegExp.cpp */,
+ F692A87E0255597D01FF60F7 /* RegExp.h */,
BCD202BD0E1706A7002C7E82 /* RegExpConstructor.cpp */,
BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */,
93CEDDFB0EA91EE600258EBE /* RegExpMatchesArray.h */,
@@ -1265,33 +1353,38 @@
BC18C3C40E16EE3300B34460 /* StringObjectThatMasqueradesAsUndefined.h */,
BC18C3C50E16EE3300B34460 /* StringPrototype.cpp */,
BC18C3C60E16EE3300B34460 /* StringPrototype.h */,
- BCDE3AB00E6C82CF001453A7 /* StructureID.cpp */,
- BCDE3AB10E6C82CF001453A7 /* StructureID.h */,
- 7E4EE70E0EBB7A5B005934AA /* StructureIDChain.cpp */,
- 7E4EE7080EBB7963005934AA /* StructureIDChain.h */,
- BC9041470EB9250900FE26FA /* StructureIDTransitionTable.h */,
+ BCDE3AB00E6C82CF001453A7 /* Structure.cpp */,
+ BCDE3AB10E6C82CF001453A7 /* Structure.h */,
+ 7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */,
+ 7E4EE7080EBB7963005934AA /* StructureChain.h */,
+ BC9041470EB9250900FE26FA /* StructureTransitionTable.h */,
14A396A60CD2933100B5B4FF /* SymbolTable.h */,
5D53726D0E1C546B0021E549 /* Tracing.d */,
5D53726E0E1C54880021E549 /* Tracing.h */,
+ 6507D2970E871E4A00D7D896 /* TypeInfo.h */,
+ F692A8850255597D01FF60F7 /* UString.cpp */,
+ F692A8860255597D01FF60F7 /* UString.h */,
);
path = runtime;
sourceTree = "<group>";
};
- 8690813F0E640C89000D36ED /* masm */ = {
- isa = PBXGroup;
- children = (
- 869081400E640C89000D36ED /* X86Assembler.h */,
- );
- path = masm;
- sourceTree = "<group>";
- };
869083120E6518D7000D36ED /* wrec */ = {
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;
sourceTree = "<group>";
@@ -1320,8 +1413,8 @@
95AB83550DA43B4400BC83F3 /* ProfileNode.h */,
95AB832E0DA42CAD00BC83F3 /* Profiler.cpp */,
95AB832F0DA42CAD00BC83F3 /* Profiler.h */,
- 1C61516A0EBAC7A00031376F /* ProfilerServer.mm */,
1C61516B0EBAC7A00031376F /* ProfilerServer.h */,
+ 1C61516A0EBAC7A00031376F /* ProfilerServer.mm */,
95CD41B10E1BF6560085358E /* TreeProfile.cpp */,
95CD41B20E1BF6560085358E /* TreeProfile.h */,
);
@@ -1329,15 +1422,44 @@
sourceTree = "<group>";
usesTabs = 0;
};
+ 9688CB120ED12B4E001D649F /* assembler */ = {
+ isa = PBXGroup;
+ children = (
+ 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */,
+ 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */,
+ 9688CB140ED12B4E001D649F /* X86Assembler.h */,
+ );
+ path = assembler;
+ sourceTree = "<group>";
+ };
+ 969A078F0ED1D3AE00F1F681 /* bytecode */ = {
+ isa = PBXGroup;
+ children = (
+ 969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */,
+ 969A07910ED1D3AE00F1F681 /* CodeBlock.h */,
+ 969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */,
+ 969A07930ED1D3AE00F1F681 /* Instruction.h */,
+ BCFD8C900EEB2EE700283848 /* JumpTable.cpp */,
+ BCFD8C910EEB2EE700283848 /* JumpTable.h */,
+ 969A07940ED1D3AE00F1F681 /* Opcode.cpp */,
+ 969A07950ED1D3AE00F1F681 /* Opcode.h */,
+ 1429D8830ED21C3D00B89619 /* SamplingTool.cpp */,
+ 1429D8840ED21C3D00B89619 /* SamplingTool.h */,
+ BCCF0D0B0EF0B8A500413C8F /* StructureStubInfo.cpp */,
+ BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */,
+ );
+ path = bytecode;
+ sourceTree = "<group>";
+ };
E195678D09E7CF1200B89D13 /* unicode */ = {
isa = PBXGroup;
children = (
E195678E09E7CF1200B89D13 /* icu */,
E1A862AA0D7EBB7D001EC6AA /* Collator.h */,
E1A862D50D7F2B5C001EC6AA /* CollatorDefault.cpp */,
- E195679409E7CF1200B89D13 /* Unicode.h */,
E1EF79A80CE97BA60088D500 /* UTF8.cpp */,
E1EF79A90CE97BA60088D500 /* UTF8.h */,
+ E195679409E7CF1200B89D13 /* Unicode.h */,
);
path = unicode;
sourceTree = "<group>";
@@ -1358,12 +1480,11 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */,
144005CB0A5338D10005F061 /* JSNode.h in Headers */,
144007570A5370D20005F061 /* JSNodeList.h in Headers */,
144005CC0A5338F80005F061 /* Node.h in Headers */,
1440074A0A536CC20005F061 /* NodeList.h in Headers */,
- A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */,
- A7C31DAA0DBEBA4300FDF8EB /* SegmentedVector.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1371,37 +1492,57 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- BC18C3E40E16F5CD00B34460 /* AlwaysInline.h in Headers */,
BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */,
+ BC18C3E90E16F5CD00B34460 /* ASCIICType.h in Headers */,
+ BC18C3EB0E16F5CD00B34460 /* AVLTree.h in Headers */,
+ BC18C3E40E16F5CD00B34460 /* AlwaysInline.h in Headers */,
+ BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
+ BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */,
BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */,
BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */,
- BC18C3E90E16F5CD00B34460 /* ASCIICType.h in Headers */,
+ BC18C5240E16FC8A00B34460 /* ArrayPrototype.lut.h in Headers */,
+ 9688CB150ED12B4E001D649F /* AssemblerBuffer.h in Headers */,
BC18C3EA0E16F5CD00B34460 /* Assertions.h in Headers */,
- BC18C3EB0E16F5CD00B34460 /* AVLTree.h in Headers */,
+ 147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */,
BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */,
+ 969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */,
BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */,
- BC18C3EE0E16F5CD00B34460 /* CodeBlock.h in Headers */,
- BC18C3EF0E16F5CD00B34460 /* CodeGenerator.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 */,
BC18C3F00E16F5CD00B34460 /* Collator.h in Headers */,
- BC18C3F10E16F5CD00B34460 /* collector.h in Headers */,
+ BC18C3F10E16F5CD00B34460 /* Collector.h in Headers */,
+ 14F3488F0E95EF8A003648BC /* CollectorHeapIterator.h in Headers */,
BC18C3F30E16F5CD00B34460 /* CommonIdentifiers.h in Headers */,
- BC18C3F40E16F5CD00B34460 /* completion.h in Headers */,
- BC18C3F50E16F5CD00B34460 /* config.h in Headers */,
+ BC18C3F40E16F5CD00B34460 /* Completion.h in Headers */,
BC18C3F60E16F5CD00B34460 /* ConstructData.h in Headers */,
- 5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
+ 180B9B080F16D94F009BDBC5 /* CurrentTime.h in Headers */,
+ BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
+ BC1166020E1997B4008066DD /* DateInstance.h in Headers */,
BC18C3F90E16F5CD00B34460 /* DateMath.h in Headers */,
+ BCD2034C0E17135E002C7E82 /* DatePrototype.h in Headers */,
+ BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */,
BC18C3FA0E16F5CD00B34460 /* Debugger.h in Headers */,
BC18C3FB0E16F5CD00B34460 /* DebuggerCallFrame.h in Headers */,
BC18C3FC0E16F5CD00B34460 /* Deque.h in Headers */,
BC18C3FD0E16F5CD00B34460 /* DisallowCType.h in Headers */,
- BC18C3FE0E16F5CD00B34460 /* dtoa.h in Headers */,
+ BC3046070E1F497F003232CF /* Error.h in Headers */,
+ 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 */,
- BC18C4010E16F5CD00B34460 /* ExecState.h in Headers */,
+ A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */,
BC18C4020E16F5CD00B34460 /* FastMalloc.h in Headers */,
BC18C4030E16F5CD00B34460 /* Forward.h in Headers */,
BC18C4040E16F5CD00B34460 /* FunctionConstructor.h in Headers */,
BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,
BC18C4060E16F5CD00B34460 /* GetPtr.h in Headers */,
+ BC257DF00E1F52ED0016B6C9 /* GlobalEvalFunction.h in Headers */,
BC18C4080E16F5CD00B34460 /* HashCountedSet.h in Headers */,
BC18C4090E16F5CD00B34460 /* HashFunctions.h in Headers */,
BC18C40A0E16F5CD00B34460 /* HashIterators.h in Headers */,
@@ -1409,29 +1550,36 @@
BC18C40C0E16F5CD00B34460 /* HashSet.h in Headers */,
BC18C40D0E16F5CD00B34460 /* HashTable.h in Headers */,
BC18C40E0E16F5CD00B34460 /* HashTraits.h in Headers */,
- BC18C40F0E16F5CD00B34460 /* identifier.h in Headers */,
+ 95FDFA160E2299980006FB00 /* HeavyProfile.h in Headers */,
+ BC18C40F0E16F5CD00B34460 /* Identifier.h in Headers */,
BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
- BC18C4110E16F5CD00B34460 /* Instruction.h in Headers */,
- BC18C4120E16F5CD00B34460 /* interpreter.h in Headers */,
- BC18C4130E16F5CD00B34460 /* JavaScript.h in Headers */,
- BC18C4140E16F5CD00B34460 /* JavaScriptCore.h in Headers */,
- BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */,
+ 969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */,
+ BC11667B0E199C05008066DD /* InternalFunction.h in Headers */,
+ 1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */,
+ 1429D9300ED22D7000B89619 /* JIT.h in Headers */,
+ 86CC85A10EE79A4700288682 /* JITInlineMethods.h in Headers */,
BC18C4160E16F5CD00B34460 /* JSActivation.h in Headers */,
BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */,
BC18C4180E16F5CD00B34460 /* JSBase.h in Headers */,
+ 140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */,
+ A791EF280F11E07900AE1F68 /* JSByteArray.h in Headers */,
BC18C4190E16F5CD00B34460 /* JSCallbackConstructor.h in Headers */,
BC18C41A0E16F5CD00B34460 /* JSCallbackFunction.h in Headers */,
BC18C41B0E16F5CD00B34460 /* JSCallbackObject.h in Headers */,
BC18C41C0E16F5CD00B34460 /* JSCallbackObjectFunctions.h in Headers */,
+ BC1167DA0E19BCC9008066DD /* JSCell.h in Headers */,
BC18C41D0E16F5CD00B34460 /* JSClassRef.h in Headers */,
BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */,
BC18C41F0E16F5CD00B34460 /* JSFunction.h in Headers */,
BC18C4200E16F5CD00B34460 /* JSGlobalData.h in Headers */,
BC18C4210E16F5CD00B34460 /* JSGlobalObject.h in Headers */,
+ BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */,
BC18C4220E16F5CD00B34460 /* JSImmediate.h in Headers */,
BC18C4230E16F5CD00B34460 /* JSLock.h in Headers */,
+ BC7F8FB90E19D1C3008632C0 /* JSNumberCell.h in Headers */,
BC18C4240E16F5CD00B34460 /* JSObject.h in Headers */,
BC18C4250E16F5CD00B34460 /* JSObjectRef.h in Headers */,
+ 9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */,
BC18C4260E16F5CD00B34460 /* JSRetainPtr.h in Headers */,
BC18C4270E16F5CD00B34460 /* JSString.h in Headers */,
BC18C4280E16F5CD00B34460 /* JSStringRef.h in Headers */,
@@ -1441,131 +1589,124 @@
BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */,
BC18C42D0E16F5CD00B34460 /* JSVariableObject.h in Headers */,
BC18C42E0E16F5CD00B34460 /* JSWrapperObject.h in Headers */,
- BC18C42F0E16F5CD00B34460 /* LabelID.h in Headers */,
- BC18C4310E16F5CD00B34460 /* lexer.h in Headers */,
+ BC18C4130E16F5CD00B34460 /* JavaScript.h in Headers */,
+ BC18C4140E16F5CD00B34460 /* JavaScriptCore.h in Headers */,
+ BC18C4150E16F5CD00B34460 /* JavaScriptCorePrefix.h in Headers */,
+ BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */,
+ 969A072A0ED1CE6900F1F681 /* Label.h in Headers */,
+ 960097A60EBABB58007A7297 /* LabelScope.h in Headers */,
+ BC18C4310E16F5CD00B34460 /* Lexer.h in Headers */,
BC18C4340E16F5CD00B34460 /* ListHashSet.h in Headers */,
BC18C4350E16F5CD00B34460 /* ListRefPtr.h in Headers */,
BC18C4360E16F5CD00B34460 /* Locker.h in Headers */,
- BC18C4370E16F5CD00B34460 /* lookup.h in Headers */,
- BC18C4380E16F5CD00B34460 /* Machine.h in Headers */,
+ BC18C4370E16F5CD00B34460 /* Lookup.h in Headers */,
+ 86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */,
BC18C4390E16F5CD00B34460 /* MainThread.h in Headers */,
BC18C43A0E16F5CD00B34460 /* MallocZoneSupport.h in Headers */,
BC18C43B0E16F5CD00B34460 /* MathExtras.h in Headers */,
BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */,
+ BC18C52A0E16FCC200B34460 /* MathObject.lut.h in Headers */,
BC18C43E0E16F5CD00B34460 /* MessageQueue.h in Headers */,
- BC18C43F0E16F5CD00B34460 /* nodes.h in Headers */,
+ BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */,
+ BC02E9130E1839DB000F9297 /* NativeErrorPrototype.h in Headers */,
+ 7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */,
+ BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */,
BC18C4400E16F5CD00B34460 /* Noncopyable.h in Headers */,
+ C0A272630E50A06300E96E15 /* NotFound.h in Headers */,
BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */,
BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */,
BC18C4430E16F5CD00B34460 /* NumberObject.h in Headers */,
BC18C4440E16F5CD00B34460 /* NumberPrototype.h in Headers */,
BC18C4450E16F5CD00B34460 /* ObjectConstructor.h in Headers */,
BC18C4460E16F5CD00B34460 /* ObjectPrototype.h in Headers */,
- BC18C4470E16F5CD00B34460 /* Opcode.h in Headers */,
- BC18C4480E16F5CD00B34460 /* operations.h in Headers */,
+ E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */,
+ 969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */,
+ BC18C4480E16F5CD00B34460 /* Operations.h in Headers */,
BC18C4490E16F5CD00B34460 /* OwnArrayPtr.h in Headers */,
BC18C44A0E16F5CD00B34460 /* OwnPtr.h in Headers */,
BC18C44B0E16F5CD00B34460 /* Parser.h in Headers */,
BC18C44C0E16F5CD00B34460 /* PassRefPtr.h in Headers */,
- BC18C44D0E16F5CD00B34460 /* pcre.h in Headers */,
- BC18C44E0E16F5CD00B34460 /* pcre_internal.h in Headers */,
BC18C44F0E16F5CD00B34460 /* Platform.h in Headers */,
BC18C4500E16F5CD00B34460 /* Profile.h in Headers */,
+ 95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */,
BC18C4510E16F5CD00B34460 /* ProfileNode.h in Headers */,
BC18C4520E16F5CD00B34460 /* Profiler.h in Headers */,
+ 1C61516D0EBAC7A00031376F /* ProfilerServer.h in Headers */,
+ BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */,
BC18C4540E16F5CD00B34460 /* PropertyNameArray.h in Headers */,
BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */,
- BC18C4560E16F5CD00B34460 /* protect.h in Headers */,
+ BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
+ BC257DF40E1F53740016B6C9 /* PrototypeFunction.h in Headers */,
+ 0B1F921D0F1753500036468E /* PtrAndFlags.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 */,
90D3469C0E285280009492EE /* RefCountedLeakCounter.h in Headers */,
BC18C4580E16F5CD00B34460 /* RefPtr.h in Headers */,
BC18C4590E16F5CD00B34460 /* RefPtrHashMap.h in Headers */,
- BC18C45A0E16F5CD00B34460 /* regexp.h in Headers */,
+ BC18C45A0E16F5CD00B34460 /* RegExp.h in Headers */,
+ BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */,
+ BCD202D60E170708002C7E82 /* RegExpConstructor.lut.h in Headers */,
BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */,
+ BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */,
+ BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */,
BC18C45D0E16F5CD00B34460 /* Register.h in Headers */,
BC18C45E0E16F5CD00B34460 /* RegisterFile.h in Headers */,
- BC18C45F0E16F5CD00B34460 /* RegisterID.h in Headers */,
+ 969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */,
+ 869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */,
BC18C4600E16F5CD00B34460 /* RetainPtr.h in Headers */,
+ 1429D8860ED21C3D00B89619 /* SamplingTool.h in Headers */,
BC18C4610E16F5CD00B34460 /* ScopeChain.h in Headers */,
- BC18C4620E16F5CD00B34460 /* SegmentedVector.h in Headers */,
- BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */,
+ 969A072C0ED1CE6900F1F681 /* SegmentedVector.h in Headers */,
+ 933040040E6A749400786E6A /* SmallStrings.h in Headers */,
BC18C4640E16F5CD00B34460 /* SourceCode.h in Headers */,
+ BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */,
+ FE1B447A0ECCD73B004F4DD1 /* StdLibExtras.h in Headers */,
BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */,
BC18C4670E16F5CD00B34460 /* StringExtras.h in Headers */,
BC18C4680E16F5CD00B34460 /* StringObject.h in Headers */,
BC18C4690E16F5CD00B34460 /* StringObjectThatMasqueradesAsUndefined.h in Headers */,
BC18C46A0E16F5CD00B34460 /* StringPrototype.h in Headers */,
+ BC18C5260E16FCA700B34460 /* StringPrototype.lut.h in Headers */,
+ BCDE3AB80E6C82F5001453A7 /* Structure.h in Headers */,
+ 7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */,
+ BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
+ BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */,
BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
- 6507D29E0E871E5E00D7D896 /* TypeInfo.h in Headers */,
BC18C46C0E16F5CD00B34460 /* TCPackedCache.h in Headers */,
BC18C46D0E16F5CD00B34460 /* TCPageMap.h in Headers */,
BC18C46E0E16F5CD00B34460 /* TCSpinLock.h in Headers */,
BC18C46F0E16F5CD00B34460 /* TCSystemAlloc.h in Headers */,
- BC18C4700E16F5CD00B34460 /* Threading.h in Headers */,
BC18C4710E16F5CD00B34460 /* ThreadSpecific.h in Headers */,
- BC18C4720E16F5CD00B34460 /* ucpinternal.h in Headers */,
+ BC18C4700E16F5CD00B34460 /* Threading.h in Headers */,
+ 5D53726F0E1C54880021E549 /* Tracing.h in Headers */,
+ 95CD41B40E1BF6560085358E /* TreeProfile.h in Headers */,
+ 6507D29E0E871E5E00D7D896 /* TypeInfo.h in Headers */,
+ BC18C4760E16F5CD00B34460 /* UString.h in Headers */,
+ BC18C4770E16F5CD00B34460 /* UTF8.h in Headers */,
BC18C4730E16F5CD00B34460 /* Unicode.h in Headers */,
BC18C4740E16F5CD00B34460 /* UnicodeIcu.h in Headers */,
BC18C4750E16F5CD00B34460 /* UnusedParam.h in Headers */,
- BC18C4760E16F5CD00B34460 /* ustring.h in Headers */,
- BC18C4770E16F5CD00B34460 /* UTF8.h in Headers */,
BC18C4780E16F5CD00B34460 /* Vector.h in Headers */,
BC18C4790E16F5CD00B34460 /* VectorTraits.h in Headers */,
+ 869083160E6518D7000D36ED /* WREC.h in Headers */,
+ 1429DA830ED2482900B89619 /* WRECFunctors.h in Headers */,
+ 1429DAE00ED2645B00B89619 /* WRECGenerator.h in Headers */,
+ 1429DABF0ED263E700B89619 /* WRECParser.h in Headers */,
BC18C47A0E16F5CD00B34460 /* WebKitAvailability.h in Headers */,
- BC18C5240E16FC8A00B34460 /* ArrayPrototype.lut.h in Headers */,
- BC18C5260E16FCA700B34460 /* StringPrototype.lut.h in Headers */,
- BC18C52A0E16FCC200B34460 /* MathObject.lut.h in Headers */,
- BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */,
- BC18C52E0E16FCE100B34460 /* lexer.lut.h in Headers */,
+ 9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
+ BC18C3F50E16F5CD00B34460 /* config.h in Headers */,
+ 5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
+ BC18C3FE0E16F5CD00B34460 /* dtoa.h in Headers */,
BC18C5300E16FCEB00B34460 /* grammar.h in Headers */,
- BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */,
- BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */,
- BCD202D60E170708002C7E82 /* RegExpConstructor.lut.h in Headers */,
- BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
- BCD2034C0E17135E002C7E82 /* DatePrototype.h in Headers */,
- BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */,
- BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */,
- BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */,
- BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */,
- BC02E9130E1839DB000F9297 /* NativeErrorPrototype.h in Headers */,
- BC02E98D0E183E38000F9297 /* ErrorInstance.h in Headers */,
- BC1166020E1997B4008066DD /* DateInstance.h in Headers */,
- 95E3BC050E1AE68200B2D1C1 /* CallIdentifier.h in Headers */,
- BC11667B0E199C05008066DD /* InternalFunction.h in Headers */,
- BC1167DA0E19BCC9008066DD /* JSCell.h in Headers */,
- BC7F8FB90E19D1C3008632C0 /* JSNumberCell.h in Headers */,
- 95CD41B40E1BF6560085358E /* TreeProfile.h in Headers */,
- 95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */,
- 5D53726F0E1C54880021E549 /* Tracing.h in Headers */,
- BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
- BC3046070E1F497F003232CF /* Error.h in Headers */,
- BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */,
- BC257DF00E1F52ED0016B6C9 /* GlobalEvalFunction.h in Headers */,
- BC257DF40E1F53740016B6C9 /* PrototypeFunction.h in Headers */,
- BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */,
- BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
- 95FDFA160E2299980006FB00 /* HeavyProfile.h in Headers */,
- 8613F45B0E3A433E00C948FD /* SamplingTool.h in Headers */,
- C0A272630E50A06300E96E15 /* NotFound.h in Headers */,
- E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */,
- 9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */,
- 8683B02F0E636482004C19EE /* CTI.h in Headers */,
- 869081410E640C89000D36ED /* X86Assembler.h in Headers */,
- 869083160E6518D7000D36ED /* WREC.h in Headers */,
- 933040040E6A749400786E6A /* SmallStrings.h in Headers */,
- BCDE3AB80E6C82F5001453A7 /* StructureID.h in Headers */,
- 147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */,
- 147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */,
- 7E2ADD8E0E79AAD500D50C51 /* CharacterClassConstructor.h in Headers */,
- 140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */,
- 869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */,
- 14F3488F0E95EF8A003648BC /* CollectorHeapIterator.h in Headers */,
- BC9041480EB9250900FE26FA /* StructureIDTransitionTable.h in Headers */,
- 960097A60EBABB58007A7297 /* LabelScope.h in Headers */,
- BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */,
- 1C61516D0EBAC7A00031376F /* ProfilerServer.h in Headers */,
- 7E4EE7090EBB7963005934AA /* StructureIDChain.h in Headers */,
- 7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */,
+ BC18C52E0E16FCE100B34460 /* lexer.lut.h in Headers */,
+ BC18C44D0E16F5CD00B34460 /* pcre.h in Headers */,
+ BC18C44E0E16F5CD00B34460 /* pcre_internal.h in Headers */,
+ BC18C4720E16F5CD00B34460 /* ucpinternal.h in Headers */,
+ A7A1F7AD0F252B3C00E184E2 /* ByteArray.h in Headers */,
+ BC3135640F302FA3003DFD3A /* DebuggerActivation.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1617,6 +1758,7 @@
932F5B3F0822A1C700736975 /* Headers */,
932F5B910822A1C700736975 /* Sources */,
9319586B09D9F91A00A56FD4 /* Check For Global Initializers */,
+ 933457200EBFDC3F00B80894 /* Check For Exit Time Destructors */,
5D29D8BE0E9860B400C3D2D0 /* Check For Weak VTables */,
932F5BD20822A1C700736975 /* Frameworks */,
1C395CBC0C6BCC16000D1E52 /* Generate 64-bit Export File */,
@@ -1754,7 +1896,7 @@
files = (
);
inputPaths = (
- "$(SRCROOT)/kjs/Tracing.d",
+ "$(SRCROOT)/runtime/Tracing.d",
);
name = "Generate DTrace header";
outputPaths = (
@@ -1762,7 +1904,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "TRACING_D=\"$SRCROOT/kjs/Tracing.d\";\nTRACING_H=\"$BUILT_PRODUCTS_DIR/DerivedSources/JavaScriptCore/TracingDtrace.h\";\n\nif [[ \"$MACOSX_DEPLOYMENT_TARGET\" > \"10.5\" ]];\nthen\n\tdtrace -h -o \"$TRACING_H\" -s \"$TRACING_D\";\nfi;\n";
+ shellScript = "TRACING_D=\"$SRCROOT/runtime/Tracing.d\";\nTRACING_H=\"$BUILT_PRODUCTS_DIR/DerivedSources/JavaScriptCore/TracingDtrace.h\";\n\nif [[ \"$MACOSX_DEPLOYMENT_TARGET\" > \"10.5\" ]];\nthen\n\tdtrace -h -o \"$TRACING_H\" -s \"$TRACING_D\";\nfi;\n";
};
5D5D8ABF0E0D0B0300F9C692 /* Fix Framework Reference */ = {
isa = PBXShellScriptBuildPhase;
@@ -1791,7 +1933,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\"\n\nln -sfh \"${SRCROOT}\" JavaScriptCore\nexport JavaScriptCore=\"JavaScriptCore\"\nexport BUILT_PRODUCTS_DIR=\"../..\"\n\nmake -f \"JavaScriptCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.ncpu`\n";
+ shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore/docs\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\"\n\nln -sfh \"${SRCROOT}\" JavaScriptCore\nexport JavaScriptCore=\"JavaScriptCore\"\nexport BUILT_PRODUCTS_DIR=\"../..\"\n\nmake -f \"JavaScriptCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.ncpu`\n";
};
9319586B09D9F91A00A56FD4 /* Check For Global Initializers */ = {
isa = PBXShellScriptBuildPhase;
@@ -1807,6 +1949,20 @@
shellPath = /bin/sh;
shellScript = "if [ -f ../WebKitTools/Scripts/check-for-global-initializers ]; then\n ../WebKitTools/Scripts/check-for-global-initializers || exit $?\nfi";
};
+ 933457200EBFDC3F00B80894 /* Check For Exit Time Destructors */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Check For Exit Time Destructors";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "if [ -f ../WebKitTools/Scripts/check-for-exit-time-destructors ]; then\n ../WebKitTools/Scripts/check-for-exit-time-destructors || exit $?\nfi";
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -1836,56 +1992,73 @@
files = (
659126BD0BDD1728001921FB /* AllInOneFile.cpp in Sources */,
65FDE49C0BDD1D4A00E80111 /* Assertions.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 */,
+ 180B9BFE0F16E94D009BDBC5 /* CurrentTime.cpp in Sources */,
+ 149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */,
+ 1429D8780ED21ACD00B89619 /* ExceptionHelpers.cpp in Sources */,
+ A7B48F490EE8936F00DCBDB6 /* ExecutableAllocator.cpp in Sources */,
+ A782F1A50EEC9FA20036273F /* ExecutableAllocatorPosix.cpp in Sources */,
65DFC93308EA173A00F7300B /* HashTable.cpp in Sources */,
+ 95FDFA140E22998F0006FB00 /* HeavyProfile.cpp in Sources */,
+ E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */,
+ 1429D7D40ED2128200B89619 /* Interpreter.cpp in Sources */,
+ 1429D92F0ED22D7000B89619 /* JIT.cpp in Sources */,
+ 86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */,
+ 86CC85A30EE79B7400288682 /* JITCall.cpp in Sources */,
+ 86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */,
+ 140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */,
1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */,
+ A791EF290F11E07900AE1F68 /* JSByteArray.cpp in Sources */,
1440F8AF0A508D200005F061 /* JSCallbackConstructor.cpp in Sources */,
1440F8920A508B100005F061 /* JSCallbackFunction.cpp in Sources */,
- 14909A2D0DCAF6CD00B29EB3 /* ExecState.cpp in Sources */,
14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */,
- 140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */,
1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */,
14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */,
+ E18E3A590DF9278C00D90B34 /* JSGlobalData.cpp in Sources */,
+ A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */,
1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */,
+ 95F6E6950E5B5F970091E860 /* JSProfilerPrivate.cpp in Sources */,
+ A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */,
1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */,
- 14E0FF120DBAAED00007C0AB /* Machine.cpp in Sources */,
- E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */,
- 930754C108B0F68000AB3056 /* pcre_compile.cpp in Sources */,
- 930754EB08B0F78500AB3056 /* pcre_exec.cpp in Sources */,
- 930754D008B0F74600AB3056 /* pcre_tables.cpp in Sources */,
- 937013480CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp in Sources */,
- 93E26BD408B1514100F85226 /* pcre_xclass.cpp in Sources */,
- E1EE793D0D6C9B9200FEA3BA /* ThreadingPthreads.cpp in Sources */,
- E1A862A90D7EBB76001EC6AA /* CollatorICU.cpp in Sources */,
- E1A862D60D7F2B5C001EC6AA /* CollatorDefault.cpp in Sources */,
- E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */,
- 95AB83420DA4322500BC83F3 /* Profiler.cpp in Sources */,
- 95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */,
+ BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */,
06D358B30DAADAA4003B174E /* MainThread.cpp in Sources */,
06D358B40DAADAAA003B174E /* MainThreadMac.mm in Sources */,
+ E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */,
+ 969A079A0ED1D3AE00F1F681 /* Opcode.cpp in Sources */,
95742F650DD11F5A000917FB /* Profile.cpp in Sources */,
- 149B15EB0D81F986009CB8C7 /* Opcode.cpp in Sources */,
- 149B1AA00D86ED73009CB8C7 /* CodeBlock.cpp in Sources */,
- A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */,
- A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */,
- A72701B60DADE94900E548D7 /* ExceptionHelpers.cpp in Sources */,
- 149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */,
- E18E3A590DF9278C00D90B34 /* JSGlobalData.cpp in Sources */,
- 95CD41B30E1BF6560085358E /* TreeProfile.cpp in Sources */,
95CD45760E1C4FDD0085358E /* ProfileGenerator.cpp in Sources */,
- 95FDFA140E22998F0006FB00 /* HeavyProfile.cpp in Sources */,
+ 95AB83560DA43C3000BC83F3 /* ProfileNode.cpp in Sources */,
+ 95AB83420DA4322500BC83F3 /* Profiler.cpp in Sources */,
+ 1C61516C0EBAC7A00031376F /* ProfilerServer.mm in Sources */,
+ 088FA5BB0EF76D4300578E6F /* RandomNumber.cpp in Sources */,
905B02AE0E28640F006DF882 /* RefCountedLeakCounter.cpp in Sources */,
- 8613F45A0E3A433E00C948FD /* SamplingTool.cpp in Sources */,
- E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */,
- 95F6E6950E5B5F970091E860 /* JSProfilerPrivate.cpp in Sources */,
- 8683B02E0E636482004C19EE /* CTI.cpp in Sources */,
- 869083150E6518D7000D36ED /* WREC.cpp in Sources */,
+ 1429D8850ED21C3D00B89619 /* SamplingTool.cpp in Sources */,
9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */,
- BCDE3B430E6C832D001453A7 /* StructureID.cpp in Sources */,
- 7E2ADD900E79AC1100D50C51 /* CharacterClassConstructor.cpp in Sources */,
- 1C61516C0EBAC7A00031376F /* ProfilerServer.mm in Sources */,
- 7E4EE70F0EBB7A5B005934AA /* StructureIDChain.cpp in Sources */,
+ BCDE3B430E6C832D001453A7 /* Structure.cpp in Sources */,
+ 7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */,
+ BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */,
+ 5D6A566B0F05995500266145 /* Threading.cpp in Sources */,
+ E1EE793D0D6C9B9200FEA3BA /* ThreadingPthreads.cpp in Sources */,
+ 95CD41B30E1BF6560085358E /* TreeProfile.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 */,
+ 930754C108B0F68000AB3056 /* pcre_compile.cpp in Sources */,
+ 930754EB08B0F78500AB3056 /* pcre_exec.cpp in Sources */,
+ 930754D008B0F74600AB3056 /* pcre_tables.cpp in Sources */,
+ 937013480CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp in Sources */,
+ 93E26BD408B1514100F85226 /* pcre_xclass.cpp in Sources */,
+ A7A1F7AC0F252B3C00E184E2 /* ByteArray.cpp in Sources */,
+ BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1893,7 +2066,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 932F5BDD0822A1C700736975 /* Shell.cpp in Sources */,
+ 932F5BDD0822A1C700736975 /* jsc.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/JavaScriptCore/JavaScriptCoreSources.bkl b/JavaScriptCore/JavaScriptCoreSources.bkl
index f328d8d..7ba3e09 100644
--- a/JavaScriptCore/JavaScriptCoreSources.bkl
+++ b/JavaScriptCore/JavaScriptCoreSources.bkl
@@ -29,7 +29,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Source files for JSCore.
-->
<makefile>
- <set append="1" var="JSCORE_SOURCES_API">
+ <set append="1" var="JSCORE_API_SOURCES">
API/JSBase.cpp
API/JSCallbackConstructor.cpp
API/JSCallbackFunction.cpp
@@ -41,32 +41,30 @@ Source files for JSCore.
API/JSValueRef.cpp
API/OpaqueJSString.cpp
</set>
+ <set append="1" var="JSCORE_BYTECOMPILER_SOURCES">
+ bytecompiler/BytecodeGenerator.cpp
+ </set>
<set append="1" var="JSCORE_DEBUGGER_SOURCES">
debugger/Debugger.cpp
+ debugger/DebuggerActivation.cpp
debugger/DebuggerCallFrame.cpp
</set>
- <set append="1" var="JSCORE_SOURCES_KJS">
- DerivedSources/JavaScriptCore/grammar.cpp
- kjs/collector.cpp
- kjs/dtoa.cpp
- kjs/identifier.cpp
- kjs/interpreter.cpp
- kjs/lexer.cpp
- kjs/lookup.cpp
- kjs/nodes.cpp
- kjs/nodes2string.cpp
- kjs/operations.cpp
- kjs/Parser.cpp
- kjs/regexp.cpp
- kjs/ustring.cpp
+ <set append="1" var="JSCORE_JSC_SOURCES">
+ DerivedSources/JavaScriptCore/Grammar.cpp
+ wtf/dtoa.cpp
</set>
- <set append="1" var="JSCORE_SOURCES_PCRE">
+ <set append="1" var="JSCORE_PCRE_SOURCES">
pcre/pcre_compile.cpp
pcre/pcre_exec.cpp
pcre/pcre_tables.cpp
pcre/pcre_ucp_searchfuncs.cpp
pcre/pcre_xclass.cpp
</set>
+ <set append="1" var="JSCORE_PARSER_SOURCES">
+ parser/Lexer.cpp
+ parser/Nodes.cpp
+ parser/Parser.cpp
+ </set>
<set append="1" var="JSCORE_PROFILER_SOURCES">
profiler/HeavyProfile.cpp
profiler/ProfileGenerator.cpp
@@ -84,6 +82,7 @@ Source files for JSCore.
runtime/BooleanObject.cpp
runtime/BooleanPrototype.cpp
runtime/CallData.cpp
+ runtime/Collector.cpp
runtime/CommonIdentifiers.cpp
runtime/ConstructData.cpp
runtime/DateConstructor.cpp
@@ -94,15 +93,18 @@ Source files for JSCore.
runtime/ErrorConstructor.cpp
runtime/ErrorInstance.cpp
runtime/ErrorPrototype.cpp
- runtime/ExecState.cpp
+ interpreter/CallFrame.cpp
runtime/FunctionConstructor.cpp
runtime/FunctionPrototype.cpp
runtime/GetterSetter.cpp
runtime/GlobalEvalFunction.cpp
+ runtime/Identifier.cpp
runtime/InitializeThreading.cpp
runtime/InternalFunction.cpp
+ runtime/Completion.cpp
runtime/JSActivation.cpp
runtime/JSArray.cpp
+ runtime/JSByteArray.cpp
runtime/JSCell.cpp
runtime/JSFunction.cpp
runtime/JSGlobalData.cpp
@@ -119,6 +121,7 @@ Source files for JSCore.
runtime/JSValue.cpp
runtime/JSVariableObject.cpp
runtime/JSWrapperObject.cpp
+ runtime/Lookup.cpp
runtime/MathObject.cpp
runtime/NativeErrorConstructor.cpp
runtime/NativeErrorPrototype.cpp
@@ -127,9 +130,11 @@ Source files for JSCore.
runtime/NumberPrototype.cpp
runtime/ObjectConstructor.cpp
runtime/ObjectPrototype.cpp
+ runtime/Operations.cpp
runtime/PropertyNameArray.cpp
runtime/PropertySlot.cpp
runtime/PrototypeFunction.cpp
+ runtime/RegExp.cpp
runtime/RegExpConstructor.cpp
runtime/RegExpObject.cpp
runtime/RegExpPrototype.cpp
@@ -138,25 +143,31 @@ Source files for JSCore.
runtime/StringConstructor.cpp
runtime/StringObject.cpp
runtime/StringPrototype.cpp
- runtime/StructureID.cpp
- runtime/StructureIDChain.cpp
+ runtime/Structure.cpp
+ runtime/StructureChain.cpp
+ runtime/UString.cpp
</set>
<set append="1" var="JSCORE_VM_SOURCES">
- VM/CodeBlock.cpp
- VM/CodeGenerator.cpp
- VM/ExceptionHelpers.cpp
- VM/Machine.cpp
- VM/Opcode.cpp
- VM/SamplingTool.cpp
- VM/RegisterFile.cpp
+ bytecode/CodeBlock.cpp
+ bytecode/StructureStubInfo.cpp
+ bytecode/JumpTable.cpp
+ runtime/ExceptionHelpers.cpp
+ interpreter/Interpreter.cpp
+ bytecode/Opcode.cpp
+ bytecode/SamplingTool.cpp
+ interpreter/RegisterFile.cpp
</set>
<set append="1" var="JSCORE_WTF_SOURCES">
wtf/Assertions.cpp
+ wtf/ByteArray.cpp
+ wtf/CurrentTime.cpp
wtf/FastMalloc.cpp
wtf/HashTable.cpp
wtf/MainThread.cpp
+ wtf/RandomNumber.cpp
wtf/RefCountedLeakCounter.cpp
wtf/TCSystemAlloc.cpp
+ wtf/Threading.cpp
wtf/ThreadingNone.cpp
wtf/wx/MainThreadWx.cpp
wtf/unicode/CollatorDefault.cpp
diff --git a/JavaScriptCore/SConstruct b/JavaScriptCore/SConstruct
new file mode 100644
index 0000000..b77d202
--- /dev/null
+++ b/JavaScriptCore/SConstruct
@@ -0,0 +1 @@
+SConscript(['JavaScriptCore.scons'])
diff --git a/JavaScriptCore/VM/CTI.cpp b/JavaScriptCore/VM/CTI.cpp
deleted file mode 100644
index 1ece843..0000000
--- a/JavaScriptCore/VM/CTI.cpp
+++ /dev/null
@@ -1,3532 +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 "CTI.h"
-
-#if ENABLE(CTI)
-
-#include "CodeBlock.h"
-#include "JSArray.h"
-#include "JSFunction.h"
-#include "Machine.h"
-#include "wrec/WREC.h"
-#include "ResultType.h"
-#include "SamplingTool.h"
-
-#ifndef NDEBUG
-#include <stdio.h>
-#endif
-
-using namespace std;
-
-namespace JSC {
-
-#if PLATFORM(MAC)
-
-static inline bool isSSE2Present()
-{
- return true; // All X86 Macs are guaranteed to support at least SSE2
-}
-
-#else
-
-static bool isSSE2Present()
-{
- static const int SSE2FeatureBit = 1 << 26;
- struct SSE2Check {
- SSE2Check()
- {
- int flags;
-#if COMPILER(MSVC)
- _asm {
- mov eax, 1 // cpuid function 1 gives us the standard feature set
- cpuid;
- mov flags, edx;
- }
-#else
- flags = 0;
- // FIXME: Add GCC code to do above asm
-#endif
- present = (flags & SSE2FeatureBit) != 0;
- }
- bool present;
- };
- static SSE2Check check;
- return check.present;
-}
-
-#endif
-
-COMPILE_ASSERT(CTI_ARGS_code == 0xC, CTI_ARGS_code_is_C);
-COMPILE_ASSERT(CTI_ARGS_callFrame == 0xE, CTI_ARGS_callFrame_is_E);
-
-#if COMPILER(GCC) && PLATFORM(X86)
-
-#if PLATFORM(DARWIN)
-#define SYMBOL_STRING(name) "_" #name
-#else
-#define SYMBOL_STRING(name) #name
-#endif
-
-asm(
-".globl " SYMBOL_STRING(ctiTrampoline) "\n"
-SYMBOL_STRING(ctiTrampoline) ":" "\n"
- "pushl %esi" "\n"
- "pushl %edi" "\n"
- "pushl %ebx" "\n"
- "subl $0x20, %esp" "\n"
- "movl $512, %esi" "\n"
- "movl 0x38(%esp), %edi" "\n" // Ox38 = 0x0E * 4, 0x0E = CTI_ARGS_callFrame (see assertion above)
- "call *0x30(%esp)" "\n" // Ox30 = 0x0C * 4, 0x0C = CTI_ARGS_code (see assertion above)
- "addl $0x20, %esp" "\n"
- "popl %ebx" "\n"
- "popl %edi" "\n"
- "popl %esi" "\n"
- "ret" "\n"
-);
-
-asm(
-".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
-SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
-#if USE(CTI_ARGUMENT)
-#if USE(FAST_CALL_CTI_ARGUMENT)
- "movl %esp, %ecx" "\n"
-#else
- "movl %esp, 0(%esp)" "\n"
-#endif
- "call " SYMBOL_STRING(_ZN3JSC7Machine12cti_vm_throwEPPv) "\n"
-#else
- "call " SYMBOL_STRING(_ZN3JSC7Machine12cti_vm_throwEPvz) "\n"
-#endif
- "addl $0x20, %esp" "\n"
- "popl %ebx" "\n"
- "popl %edi" "\n"
- "popl %esi" "\n"
- "ret" "\n"
-);
-
-#elif COMPILER(MSVC)
-
-extern "C" {
-
- __declspec(naked) JSValue* ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue** exception, Profiler**, JSGlobalData*)
- {
- __asm {
- push esi;
- push edi;
- push ebx;
- sub esp, 0x20;
- mov esi, 512;
- mov ecx, esp;
- mov edi, [esp + 0x38];
- call [esp + 0x30]; // Ox30 = 0x0C * 4, 0x0C = CTI_ARGS_code (see assertion above)
- add esp, 0x20;
- pop ebx;
- pop edi;
- pop esi;
- ret;
- }
- }
-
- __declspec(naked) void ctiVMThrowTrampoline()
- {
- __asm {
- mov ecx, esp;
- call JSC::Machine::cti_vm_throw;
- add esp, 0x20;
- pop ebx;
- pop edi;
- pop esi;
- ret;
- }
- }
-
-}
-
-#endif
-
-ALWAYS_INLINE bool CTI::isConstant(int src)
-{
- return src >= m_codeBlock->numVars && src < m_codeBlock->numVars + m_codeBlock->numConstants;
-}
-
-ALWAYS_INLINE JSValue* CTI::getConstant(CallFrame* callFrame, int src)
-{
- return m_codeBlock->constantRegisters[src - m_codeBlock->numVars].jsValue(callFrame);
-}
-
-inline uintptr_t CTI::asInteger(JSValue* value)
-{
- return reinterpret_cast<uintptr_t>(value);
-}
-
-// get arg puts an arg from the SF register array into a h/w register
-ALWAYS_INLINE void CTI::emitGetArg(int src, X86Assembler::RegisterID dst)
-{
- // TODO: we want to reuse values that are already in registers if we can - add a register allocator!
- if (isConstant(src)) {
- JSValue* js = getConstant(m_callFrame, src);
- m_jit.movl_i32r(asInteger(js), dst);
- } else
- m_jit.movl_mr(src * sizeof(Register), X86::edi, dst);
-}
-
-// get arg puts an arg from the SF register array onto the stack, as an arg to a context threaded function.
-ALWAYS_INLINE void CTI::emitGetPutArg(unsigned src, unsigned offset, X86Assembler::RegisterID scratch)
-{
- if (isConstant(src)) {
- JSValue* js = getConstant(m_callFrame, src);
- m_jit.movl_i32m(asInteger(js), offset + sizeof(void*), X86::esp);
- } else {
- m_jit.movl_mr(src * sizeof(Register), X86::edi, scratch);
- m_jit.movl_rm(scratch, offset + sizeof(void*), X86::esp);
- }
-}
-
-// puts an arg onto the stack, as an arg to a context threaded function.
-ALWAYS_INLINE void CTI::emitPutArg(X86Assembler::RegisterID src, unsigned offset)
-{
- m_jit.movl_rm(src, offset + sizeof(void*), X86::esp);
-}
-
-ALWAYS_INLINE void CTI::emitPutArgConstant(unsigned value, unsigned offset)
-{
- m_jit.movl_i32m(value, offset + sizeof(void*), X86::esp);
-}
-
-ALWAYS_INLINE JSValue* CTI::getConstantImmediateNumericArg(unsigned src)
-{
- if (isConstant(src)) {
- JSValue* js = getConstant(m_callFrame, src);
- return JSImmediate::isNumber(js) ? js : noValue();
- }
- return noValue();
-}
-
-ALWAYS_INLINE void CTI::emitPutCTIParam(void* value, unsigned name)
-{
- m_jit.movl_i32m(reinterpret_cast<intptr_t>(value), name * sizeof(void*), X86::esp);
-}
-
-ALWAYS_INLINE void CTI::emitPutCTIParam(X86Assembler::RegisterID from, unsigned name)
-{
- m_jit.movl_rm(from, name * sizeof(void*), X86::esp);
-}
-
-ALWAYS_INLINE void CTI::emitGetCTIParam(unsigned name, X86Assembler::RegisterID to)
-{
- m_jit.movl_mr(name * sizeof(void*), X86::esp, to);
-}
-
-ALWAYS_INLINE void CTI::emitPutToCallFrameHeader(X86Assembler::RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
-{
- m_jit.movl_rm(from, entry * sizeof(Register), X86::edi);
-}
-
-ALWAYS_INLINE void CTI::emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, X86Assembler::RegisterID to)
-{
- m_jit.movl_mr(entry * sizeof(Register), X86::edi, to);
-}
-
-ALWAYS_INLINE void CTI::emitPutResult(unsigned dst, X86Assembler::RegisterID from)
-{
- m_jit.movl_rm(from, dst * sizeof(Register), X86::edi);
- // FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
-}
-
-ALWAYS_INLINE void CTI::emitInitRegister(unsigned dst)
-{
- m_jit.movl_i32m(asInteger(jsUndefined()), dst * sizeof(Register), X86::edi);
- // FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
-}
-
-void ctiSetReturnAddress(void** where, void* what)
-{
- *where = what;
-}
-
-void ctiRepatchCallByReturnAddress(void* where, void* what)
-{
- (static_cast<void**>(where))[-1] = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(what) - reinterpret_cast<uintptr_t>(where));
-}
-
-#ifndef NDEBUG
-
-void CTI::printOpcodeOperandTypes(unsigned src1, unsigned src2)
-{
- char which1 = '*';
- if (isConstant(src1)) {
- JSValue* js = getConstant(m_callFrame, src1);
- which1 =
- JSImmediate::isImmediate(js) ?
- (JSImmediate::isNumber(js) ? 'i' :
- JSImmediate::isBoolean(js) ? 'b' :
- js->isUndefined() ? 'u' :
- js->isNull() ? 'n' : '?')
- :
- (js->isString() ? 's' :
- js->isObject() ? 'o' :
- 'k');
- }
- char which2 = '*';
- if (isConstant(src2)) {
- JSValue* js = getConstant(m_callFrame, src2);
- which2 =
- JSImmediate::isImmediate(js) ?
- (JSImmediate::isNumber(js) ? 'i' :
- JSImmediate::isBoolean(js) ? 'b' :
- js->isUndefined() ? 'u' :
- js->isNull() ? 'n' : '?')
- :
- (js->isString() ? 's' :
- js->isObject() ? 'o' :
- 'k');
- }
- if ((which1 != '*') | (which2 != '*'))
- fprintf(stderr, "Types %c %c\n", which1, which2);
-}
-
-#endif
-
-extern "C" {
- static JSValue* FASTCALL allocateNumber(JSGlobalData* globalData) {
- JSValue* result = new (globalData) JSNumberCell(globalData);
- ASSERT(result);
- return result;
- }
-}
-
-ALWAYS_INLINE void CTI::emitAllocateNumber(JSGlobalData* globalData, unsigned opcodeIndex)
-{
- m_jit.movl_i32r(reinterpret_cast<intptr_t>(globalData), X86::ecx);
- emitNakedFastCall(opcodeIndex, (void*)allocateNumber);
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitNakedCall(unsigned opcodeIndex, X86::RegisterID r)
-{
- X86Assembler::JmpSrc call = m_jit.emitCall(r);
- m_calls.append(CallRecord(call, opcodeIndex));
-
- return call;
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitNakedCall(unsigned opcodeIndex, void(*function)())
-{
- X86Assembler::JmpSrc call = m_jit.emitCall();
- m_calls.append(CallRecord(call, reinterpret_cast<CTIHelper_v>(function), opcodeIndex));
- return call;
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitNakedFastCall(unsigned opcodeIndex, void* function)
-{
- X86Assembler::JmpSrc call = m_jit.emitCall();
- m_calls.append(CallRecord(call, reinterpret_cast<CTIHelper_v>(function), opcodeIndex));
- return call;
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_j helper)
-{
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot());
-#else
- UNUSED_PARAM(vPC);
-#endif
- m_jit.emitRestoreArgumentReference();
- emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
- X86Assembler::JmpSrc call = m_jit.emitCall();
- m_calls.append(CallRecord(call, helper, opcodeIndex));
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot());
-#endif
-
- return call;
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_o helper)
-{
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot());
-#else
- UNUSED_PARAM(vPC);
-#endif
- m_jit.emitRestoreArgumentReference();
- emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
- X86Assembler::JmpSrc call = m_jit.emitCall();
- m_calls.append(CallRecord(call, helper, opcodeIndex));
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot());
-#endif
-
- return call;
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_p helper)
-{
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot());
-#else
- UNUSED_PARAM(vPC);
-#endif
- m_jit.emitRestoreArgumentReference();
- emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
- X86Assembler::JmpSrc call = m_jit.emitCall();
- m_calls.append(CallRecord(call, helper, opcodeIndex));
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot());
-#endif
-
- return call;
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_b helper)
-{
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot());
-#else
- UNUSED_PARAM(vPC);
-#endif
- m_jit.emitRestoreArgumentReference();
- emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
- X86Assembler::JmpSrc call = m_jit.emitCall();
- m_calls.append(CallRecord(call, helper, opcodeIndex));
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot());
-#endif
-
- return call;
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_v helper)
-{
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot());
-#else
- UNUSED_PARAM(vPC);
-#endif
- m_jit.emitRestoreArgumentReference();
- emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
- X86Assembler::JmpSrc call = m_jit.emitCall();
- m_calls.append(CallRecord(call, helper, opcodeIndex));
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot());
-#endif
-
- return call;
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_s helper)
-{
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot());
-#else
- UNUSED_PARAM(vPC);
-#endif
- m_jit.emitRestoreArgumentReference();
- emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
- X86Assembler::JmpSrc call = m_jit.emitCall();
- m_calls.append(CallRecord(call, helper, opcodeIndex));
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot());
-#endif
-
- return call;
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCTICall(Instruction* vPC, unsigned opcodeIndex, CTIHelper_2 helper)
-{
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, true), m_machine->sampler()->sampleSlot());
-#else
- UNUSED_PARAM(vPC);
-#endif
- m_jit.emitRestoreArgumentReference();
- emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
- X86Assembler::JmpSrc call = m_jit.emitCall();
- m_calls.append(CallRecord(call, helper, opcodeIndex));
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(vPC, false), m_machine->sampler()->sampleSlot());
-#endif
-
- return call;
-}
-
-ALWAYS_INLINE void CTI::emitJumpSlowCaseIfNotJSCell(X86Assembler::RegisterID reg, unsigned opcodeIndex)
-{
- m_jit.testl_i32r(JSImmediate::TagMask, reg);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), opcodeIndex));
-}
-
-ALWAYS_INLINE void CTI::emitJumpSlowCaseIfNotImmNum(X86Assembler::RegisterID reg, unsigned opcodeIndex)
-{
- m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, reg);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), opcodeIndex));
-}
-
-ALWAYS_INLINE void CTI::emitJumpSlowCaseIfNotImmNums(X86Assembler::RegisterID reg1, X86Assembler::RegisterID reg2, unsigned opcodeIndex)
-{
- m_jit.movl_rr(reg1, X86::ecx);
- m_jit.andl_rr(reg2, X86::ecx);
- emitJumpSlowCaseIfNotImmNum(X86::ecx, opcodeIndex);
-}
-
-ALWAYS_INLINE unsigned CTI::getDeTaggedConstantImmediate(JSValue* imm)
-{
- ASSERT(JSImmediate::isNumber(imm));
- return asInteger(imm) & ~JSImmediate::TagBitTypeInteger;
-}
-
-ALWAYS_INLINE void CTI::emitFastArithDeTagImmediate(X86Assembler::RegisterID reg)
-{
- m_jit.subl_i8r(JSImmediate::TagBitTypeInteger, reg);
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitFastArithDeTagImmediateJumpIfZero(X86Assembler::RegisterID reg)
-{
- m_jit.subl_i8r(JSImmediate::TagBitTypeInteger, reg);
- return m_jit.emitUnlinkedJe();
-}
-
-ALWAYS_INLINE void CTI::emitFastArithReTagImmediate(X86Assembler::RegisterID reg)
-{
- m_jit.addl_i8r(JSImmediate::TagBitTypeInteger, reg);
-}
-
-ALWAYS_INLINE void CTI::emitFastArithPotentiallyReTagImmediate(X86Assembler::RegisterID reg)
-{
- m_jit.orl_i32r(JSImmediate::TagBitTypeInteger, reg);
-}
-
-ALWAYS_INLINE void CTI::emitFastArithImmToInt(X86Assembler::RegisterID reg)
-{
- m_jit.sarl_i8r(1, reg);
-}
-
-ALWAYS_INLINE void CTI::emitFastArithIntToImmOrSlowCase(X86Assembler::RegisterID reg, unsigned opcodeIndex)
-{
- m_jit.addl_rr(reg, reg);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), opcodeIndex));
- emitFastArithReTagImmediate(reg);
-}
-
-ALWAYS_INLINE void CTI::emitFastArithIntToImmNoCheck(X86Assembler::RegisterID reg)
-{
- m_jit.addl_rr(reg, reg);
- emitFastArithReTagImmediate(reg);
-}
-
-ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitArithIntToImmWithJump(X86Assembler::RegisterID reg)
-{
- m_jit.addl_rr(reg, reg);
- X86Assembler::JmpSrc jmp = m_jit.emitUnlinkedJo();
- emitFastArithReTagImmediate(reg);
- return jmp;
-}
-
-ALWAYS_INLINE void CTI::emitTagAsBoolImmediate(X86Assembler::RegisterID reg)
-{
- m_jit.shl_i8r(JSImmediate::ExtendedPayloadShift, reg);
- m_jit.orl_i32r(JSImmediate::FullTagTypeBool, reg);
-}
-
-CTI::CTI(Machine* machine, CallFrame* callFrame, CodeBlock* codeBlock)
- : m_jit(machine->jitCodeBuffer())
- , m_machine(machine)
- , m_callFrame(callFrame)
- , m_codeBlock(codeBlock)
- , m_labels(codeBlock ? codeBlock->instructions.size() : 0)
- , m_propertyAccessCompilationInfo(codeBlock ? codeBlock->propertyAccessInstructions.size() : 0)
- , m_callStructureStubCompilationInfo(codeBlock ? codeBlock->callLinkInfos.size() : 0)
-{
-}
-
-#define CTI_COMPILE_BINARY_OP(name) \
- case name: { \
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \
- emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); \
- emitCTICall(instruction + i, i, Machine::cti_##name); \
- emitPutResult(instruction[i + 1].u.operand); \
- i += 4; \
- break; \
- }
-
-#define CTI_COMPILE_UNARY_OP(name) \
- case name: { \
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \
- emitCTICall(instruction + i, i, Machine::cti_##name); \
- emitPutResult(instruction[i + 1].u.operand); \
- i += 3; \
- break; \
- }
-
-static void unreachable()
-{
- ASSERT_NOT_REACHED();
- exit(1);
-}
-
-void CTI::compileOpCallInitializeCallFrame(unsigned callee, unsigned argCount)
-{
- emitGetArg(callee, X86::ecx); // Load callee JSFunction into ecx
- m_jit.movl_rm(X86::eax, RegisterFile::CodeBlock * static_cast<int>(sizeof(Register)), X86::edx); // callee CodeBlock was returned in eax
- m_jit.movl_i32m(asInteger(noValue()), RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)), X86::edx);
- m_jit.movl_rm(X86::ecx, RegisterFile::Callee * static_cast<int>(sizeof(Register)), X86::edx);
-
- m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_scopeChain) + OBJECT_OFFSET(ScopeChain, m_node), X86::ecx, X86::ebx); // newScopeChain
- m_jit.movl_i32m(argCount, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)), X86::edx);
- m_jit.movl_rm(X86::edi, RegisterFile::CallerFrame * static_cast<int>(sizeof(Register)), X86::edx);
- m_jit.movl_rm(X86::ebx, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)), X86::edx);
-}
-
-void CTI::compileOpCallSetupArgs(Instruction* instruction, bool isConstruct, bool isEval)
-{
- int firstArg = instruction[4].u.operand;
- int argCount = instruction[5].u.operand;
- int registerOffset = instruction[6].u.operand;
-
- emitPutArg(X86::ecx, 0);
- emitPutArgConstant(registerOffset, 4);
- emitPutArgConstant(argCount, 8);
- emitPutArgConstant(reinterpret_cast<unsigned>(instruction), 12);
- if (isConstruct) {
- emitGetPutArg(instruction[3].u.operand, 16, X86::eax);
- emitPutArgConstant(firstArg, 20);
- } else if (isEval)
- emitGetPutArg(instruction[3].u.operand, 16, X86::eax);
-}
-
-void CTI::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned i, unsigned callLinkInfoIndex)
-{
- int dst = instruction[1].u.operand;
- int callee = instruction[2].u.operand;
- int firstArg = instruction[4].u.operand;
- int argCount = instruction[5].u.operand;
- int registerOffset = instruction[6].u.operand;
-
- // Setup this value as the first argument (does not apply to constructors)
- if (opcodeID != op_construct) {
- int thisVal = instruction[3].u.operand;
- if (thisVal == missingThisObjectMarker()) {
- // FIXME: should this be loaded dynamically off m_callFrame?
- m_jit.movl_i32m(asInteger(m_callFrame->globalThisValue()), firstArg * sizeof(Register), X86::edi);
- } else {
- emitGetArg(thisVal, X86::eax);
- emitPutResult(firstArg);
- }
- }
-
- // Handle eval
- X86Assembler::JmpSrc wasEval;
- if (opcodeID == op_call_eval) {
- emitGetArg(callee, X86::ecx);
- compileOpCallSetupArgs(instruction, false, true);
-
- emitCTICall(instruction, i, Machine::cti_op_call_eval);
- m_jit.cmpl_i32r(asInteger(JSImmediate::impossibleValue()), X86::eax);
- wasEval = m_jit.emitUnlinkedJne();
- }
-
- // This plants a check for a cached JSFunction value, so we can plant a fast link to the callee.
- // This deliberately leaves the callee in ecx, used when setting up the stack frame below
- emitGetArg(callee, X86::ecx);
- m_jit.cmpl_i32r(asInteger(JSImmediate::impossibleValue()), X86::ecx);
- X86Assembler::JmpDst addressOfLinkedFunctionCheck = m_jit.label();
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
- ASSERT(X86Assembler::getDifferenceBetweenLabels(addressOfLinkedFunctionCheck, m_jit.label()) == repatchOffsetOpCallCall);
- m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
-
- // The following is the fast case, only used whan a callee can be linked.
-
- // In the case of OpConstruct, call oout to a cti_ function to create the new object.
- if (opcodeID == op_construct) {
- emitPutArg(X86::ecx, 0);
- emitGetPutArg(instruction[3].u.operand, 4, X86::eax);
- emitCTICall(instruction, i, Machine::cti_op_construct_JSConstructFast);
- emitPutResult(instruction[4].u.operand);
- emitGetArg(callee, X86::ecx);
- }
-
- // Fast version of stack frame initialization, directly relative to edi.
- // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
- m_jit.movl_i32m(asInteger(noValue()), (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register)), X86::edi);
- m_jit.movl_rm(X86::ecx, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register)), X86::edi);
- m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_scopeChain) + OBJECT_OFFSET(ScopeChain, m_node), X86::ecx, X86::edx); // newScopeChain
- m_jit.movl_i32m(argCount, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register)), X86::edi);
- m_jit.movl_rm(X86::edi, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register)), X86::edi);
- m_jit.movl_rm(X86::edx, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register)), X86::edi);
- m_jit.addl_i32r(registerOffset * sizeof(Register), X86::edi);
-
- // Call to the callee
- m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(i, unreachable);
-
- if (opcodeID == op_call_eval)
- m_jit.link(wasEval, m_jit.label());
-
- // Put the return value in dst. In the interpreter, op_ret does this.
- emitPutResult(dst);
-
-#if ENABLE(CODEBLOCK_SAMPLING)
- m_jit.movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_machine->sampler()->codeBlockSlot());
-#endif
-}
-
-void CTI::compileOpStrictEq(Instruction* instruction, unsigned i, CompileOpStrictEqType type)
-{
- bool negated = (type == OpNStrictEq);
-
- unsigned dst = instruction[1].u.operand;
- unsigned src1 = instruction[2].u.operand;
- unsigned src2 = instruction[3].u.operand;
-
- emitGetArg(src1, X86::eax);
- emitGetArg(src2, X86::edx);
-
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc firstNotImmediate = m_jit.emitUnlinkedJe();
- m_jit.testl_i32r(JSImmediate::TagMask, X86::edx);
- X86Assembler::JmpSrc secondNotImmediate = m_jit.emitUnlinkedJe();
-
- m_jit.cmpl_rr(X86::edx, X86::eax);
- if (negated)
- m_jit.setne_r(X86::eax);
- else
- m_jit.sete_r(X86::eax);
- m_jit.movzbl_rr(X86::eax, X86::eax);
- emitTagAsBoolImmediate(X86::eax);
-
- X86Assembler::JmpSrc bothWereImmediates = m_jit.emitUnlinkedJmp();
-
- m_jit.link(firstNotImmediate, m_jit.label());
-
- // check that edx is immediate but not the zero immediate
- m_jit.testl_i32r(JSImmediate::TagMask, X86::edx);
- m_jit.setz_r(X86::ecx);
- m_jit.movzbl_rr(X86::ecx, X86::ecx); // ecx is now 1 if edx was nonimmediate
- m_jit.cmpl_i32r(asInteger(JSImmediate::zeroImmediate()), X86::edx);
- m_jit.sete_r(X86::edx);
- m_jit.movzbl_rr(X86::edx, X86::edx); // edx is now 1 if edx was the 0 immediate
- m_jit.orl_rr(X86::ecx, X86::edx);
-
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJnz(), i));
-
- m_jit.movl_i32r(asInteger(jsBoolean(negated)), X86::eax);
-
- X86Assembler::JmpSrc firstWasNotImmediate = m_jit.emitUnlinkedJmp();
-
- m_jit.link(secondNotImmediate, m_jit.label());
- // check that eax is not the zero immediate (we know it must be immediate)
- m_jit.cmpl_i32r(asInteger(JSImmediate::zeroImmediate()), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i));
-
- m_jit.movl_i32r(asInteger(jsBoolean(negated)), X86::eax);
-
- m_jit.link(bothWereImmediates, m_jit.label());
- m_jit.link(firstWasNotImmediate, m_jit.label());
-
- emitPutResult(dst);
-}
-
-void CTI::emitSlowScriptCheck(Instruction* vPC, unsigned opcodeIndex)
-{
- m_jit.subl_i8r(1, X86::esi);
- X86Assembler::JmpSrc skipTimeout = m_jit.emitUnlinkedJne();
- emitCTICall(vPC, opcodeIndex, Machine::cti_timeout_check);
-
- emitGetCTIParam(CTI_ARGS_globalData, X86::ecx);
- m_jit.movl_mr(OBJECT_OFFSET(JSGlobalData, machine), X86::ecx, X86::ecx);
- m_jit.movl_mr(OBJECT_OFFSET(Machine, m_ticksUntilNextTimeoutCheck), X86::ecx, X86::esi);
- m_jit.link(skipTimeout, m_jit.label());
-}
-
-/*
- This is required since number representation is canonical - values representable as a JSImmediate should not be stored in a JSNumberCell.
-
- In the common case, the double value from 'xmmSource' is written to the reusable JSNumberCell pointed to by 'jsNumberCell', then 'jsNumberCell'
- is written to the output SF Register 'dst', and then a jump is planted (stored into *wroteJSNumberCell).
-
- However if the value from xmmSource is representable as a JSImmediate, then the JSImmediate value will be written to the output, and flow
- control will fall through from the code planted.
-*/
-void CTI::putDoubleResultToJSNumberCellOrJSImmediate(X86::XMMRegisterID xmmSource, X86::RegisterID jsNumberCell, unsigned dst, X86Assembler::JmpSrc* wroteJSNumberCell, X86::XMMRegisterID tempXmm, X86::RegisterID tempReg1, X86::RegisterID tempReg2)
-{
- // convert (double -> JSImmediate -> double), and check if the value is unchanged - in which case the value is representable as a JSImmediate.
- m_jit.cvttsd2si_rr(xmmSource, tempReg1);
- m_jit.addl_rr(tempReg1, tempReg1);
- m_jit.sarl_i8r(1, tempReg1);
- m_jit.cvtsi2sd_rr(tempReg1, tempXmm);
- // Compare & branch if immediate.
- m_jit.ucomis_rr(tempXmm, xmmSource);
- X86Assembler::JmpSrc resultIsImm = m_jit.emitUnlinkedJe();
- X86Assembler::JmpDst resultLookedLikeImmButActuallyIsnt = m_jit.label();
-
- // Store the result to the JSNumberCell and jump.
- m_jit.movsd_rm(xmmSource, OBJECT_OFFSET(JSNumberCell, m_value), jsNumberCell);
- emitPutResult(dst, jsNumberCell);
- *wroteJSNumberCell = m_jit.emitUnlinkedJmp();
-
- m_jit.link(resultIsImm, m_jit.label());
- // value == (double)(JSImmediate)value... or at least, it looks that way...
- // ucomi will report that (0 == -0), and will report true if either input in NaN (result is unordered).
- m_jit.link(m_jit.emitUnlinkedJp(), resultLookedLikeImmButActuallyIsnt); // Actually was a NaN
- m_jit.pextrw_irr(3, xmmSource, tempReg2);
- m_jit.cmpl_i32r(0x8000, tempReg2);
- m_jit.link(m_jit.emitUnlinkedJe(), resultLookedLikeImmButActuallyIsnt); // Actually was -0
- // Yes it really really really is representable as a JSImmediate.
- emitFastArithIntToImmNoCheck(tempReg1);
- emitPutResult(dst, tempReg1);
-}
-
-void CTI::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes types, unsigned i)
-{
- StructureID* numberStructureID = m_callFrame->globalData().numberStructureID.get();
- X86Assembler::JmpSrc wasJSNumberCell1, wasJSNumberCell1b, wasJSNumberCell2, wasJSNumberCell2b;
-
- emitGetArg(src1, X86::eax);
- emitGetArg(src2, X86::edx);
-
- if (types.second().isReusable() && isSSE2Present()) {
- ASSERT(types.second().mightBeNumber());
-
- // Check op2 is a number
- m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::edx);
- X86Assembler::JmpSrc op2imm = m_jit.emitUnlinkedJne();
- if (!types.second().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(X86::edx, i);
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::edx);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
- }
-
- // (1) In this case src2 is a reusable number cell.
- // Slow case if src1 is not a number type.
- m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
- X86Assembler::JmpSrc op1imm = m_jit.emitUnlinkedJne();
- if (!types.first().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(X86::eax, i);
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
- }
-
- // (1a) if we get here, src1 is also a number cell
- m_jit.movsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
- X86Assembler::JmpSrc loadedDouble = m_jit.emitUnlinkedJmp();
- // (1b) if we get here, src1 is an immediate
- m_jit.link(op1imm, m_jit.label());
- emitFastArithImmToInt(X86::eax);
- m_jit.cvtsi2sd_rr(X86::eax, X86::xmm0);
- // (1c)
- m_jit.link(loadedDouble, m_jit.label());
- if (opcodeID == op_add)
- m_jit.addsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
- else if (opcodeID == op_sub)
- m_jit.subsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
- else {
- ASSERT(opcodeID == op_mul);
- m_jit.mulsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
- }
-
- putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::edx, dst, &wasJSNumberCell2, X86::xmm1, X86::ecx, X86::eax);
- wasJSNumberCell2b = m_jit.emitUnlinkedJmp();
-
- // (2) This handles cases where src2 is an immediate number.
- // Two slow cases - either src1 isn't an immediate, or the subtract overflows.
- m_jit.link(op2imm, m_jit.label());
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- } else if (types.first().isReusable() && isSSE2Present()) {
- ASSERT(types.first().mightBeNumber());
-
- // Check op1 is a number
- m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
- X86Assembler::JmpSrc op1imm = m_jit.emitUnlinkedJne();
- if (!types.first().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(X86::eax, i);
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
- }
-
- // (1) In this case src1 is a reusable number cell.
- // Slow case if src2 is not a number type.
- m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::edx);
- X86Assembler::JmpSrc op2imm = m_jit.emitUnlinkedJne();
- if (!types.second().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(X86::edx, i);
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::edx);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
- }
-
- // (1a) if we get here, src2 is also a number cell
- m_jit.movsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm1);
- X86Assembler::JmpSrc loadedDouble = m_jit.emitUnlinkedJmp();
- // (1b) if we get here, src2 is an immediate
- m_jit.link(op2imm, m_jit.label());
- emitFastArithImmToInt(X86::edx);
- m_jit.cvtsi2sd_rr(X86::edx, X86::xmm1);
- // (1c)
- m_jit.link(loadedDouble, m_jit.label());
- m_jit.movsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
- if (opcodeID == op_add)
- m_jit.addsd_rr(X86::xmm1, X86::xmm0);
- else if (opcodeID == op_sub)
- m_jit.subsd_rr(X86::xmm1, X86::xmm0);
- else {
- ASSERT(opcodeID == op_mul);
- m_jit.mulsd_rr(X86::xmm1, X86::xmm0);
- }
- m_jit.movsd_rm(X86::xmm0, OBJECT_OFFSET(JSNumberCell, m_value), X86::eax);
- emitPutResult(dst);
-
- putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::eax, dst, &wasJSNumberCell1, X86::xmm1, X86::ecx, X86::edx);
- wasJSNumberCell1b = m_jit.emitUnlinkedJmp();
-
- // (2) This handles cases where src1 is an immediate number.
- // Two slow cases - either src2 isn't an immediate, or the subtract overflows.
- m_jit.link(op1imm, m_jit.label());
- emitJumpSlowCaseIfNotImmNum(X86::edx, i);
- } else
- emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
-
- if (opcodeID == op_add) {
- emitFastArithDeTagImmediate(X86::eax);
- m_jit.addl_rr(X86::edx, X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- } else if (opcodeID == op_sub) {
- m_jit.subl_rr(X86::edx, X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- emitFastArithReTagImmediate(X86::eax);
- } else {
- ASSERT(opcodeID == op_mul);
- // convert eax & edx from JSImmediates to ints, and check if either are zero
- emitFastArithImmToInt(X86::edx);
- X86Assembler::JmpSrc op1Zero = emitFastArithDeTagImmediateJumpIfZero(X86::eax);
- m_jit.testl_rr(X86::edx, X86::edx);
- X86Assembler::JmpSrc op2NonZero = m_jit.emitUnlinkedJne();
- m_jit.link(op1Zero, m_jit.label());
- // if either input is zero, add the two together, and check if the result is < 0.
- // If it is, we have a problem (N < 0), (N * 0) == -0, not representatble as a JSImmediate.
- m_jit.movl_rr(X86::eax, X86::ecx);
- m_jit.addl_rr(X86::edx, X86::ecx);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJs(), i));
- // Skip the above check if neither input is zero
- m_jit.link(op2NonZero, m_jit.label());
- m_jit.imull_rr(X86::edx, X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- emitFastArithReTagImmediate(X86::eax);
- }
- emitPutResult(dst);
-
- if (types.second().isReusable() && isSSE2Present()) {
- m_jit.link(wasJSNumberCell2, m_jit.label());
- m_jit.link(wasJSNumberCell2b, m_jit.label());
- }
- else if (types.first().isReusable() && isSSE2Present()) {
- m_jit.link(wasJSNumberCell1, m_jit.label());
- m_jit.link(wasJSNumberCell1b, m_jit.label());
- }
-}
-
-void CTI::compileBinaryArithOpSlowCase(Instruction* vPC, OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes types, unsigned i)
-{
- X86Assembler::JmpDst here = m_jit.label();
- m_jit.link(iter->from, here);
- if (types.second().isReusable() && isSSE2Present()) {
- if (!types.first().definitelyIsNumber()) {
- m_jit.link((++iter)->from, here);
- m_jit.link((++iter)->from, here);
- }
- if (!types.second().definitelyIsNumber()) {
- m_jit.link((++iter)->from, here);
- m_jit.link((++iter)->from, here);
- }
- m_jit.link((++iter)->from, here);
- } else if (types.first().isReusable() && isSSE2Present()) {
- if (!types.first().definitelyIsNumber()) {
- m_jit.link((++iter)->from, here);
- m_jit.link((++iter)->from, here);
- }
- if (!types.second().definitelyIsNumber()) {
- m_jit.link((++iter)->from, here);
- m_jit.link((++iter)->from, here);
- }
- m_jit.link((++iter)->from, here);
- } else
- m_jit.link((++iter)->from, here);
-
- // additional entry point to handle -0 cases.
- if (opcodeID == op_mul)
- m_jit.link((++iter)->from, here);
-
- emitGetPutArg(src1, 0, X86::ecx);
- emitGetPutArg(src2, 4, X86::ecx);
- if (opcodeID == op_add)
- emitCTICall(vPC, i, Machine::cti_op_add);
- else if (opcodeID == op_sub)
- emitCTICall(vPC, i, Machine::cti_op_sub);
- else {
- ASSERT(opcodeID == op_mul);
- emitCTICall(vPC, i, Machine::cti_op_mul);
- }
- emitPutResult(dst);
-}
-
-void CTI::privateCompileMainPass()
-{
- Instruction* instruction = m_codeBlock->instructions.begin();
- unsigned instructionCount = m_codeBlock->instructions.size();
-
- unsigned propertyAccessInstructionIndex = 0;
- unsigned callLinkInfoIndex = 0;
-
- for (unsigned i = 0; i < instructionCount; ) {
- ASSERT_WITH_MESSAGE(m_machine->isOpcode(instruction[i].u.opcode), "privateCompileMainPass gone bad @ %d", i);
-
-#if ENABLE(OPCODE_SAMPLING)
- if (i > 0) // Avoid the overhead of sampling op_enter twice.
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(instruction + i), m_machine->sampler()->sampleSlot());
-#endif
-
- m_labels[i] = m_jit.label();
- OpcodeID opcodeID = m_machine->getOpcodeID(instruction[i].u.opcode);
- switch (opcodeID) {
- case op_mov: {
- unsigned src = instruction[i + 2].u.operand;
- if (isConstant(src))
- m_jit.movl_i32r(asInteger(getConstant(m_callFrame, src)), X86::eax);
- else
- emitGetArg(src, X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_add: {
- unsigned dst = instruction[i + 1].u.operand;
- unsigned src1 = instruction[i + 2].u.operand;
- unsigned src2 = instruction[i + 3].u.operand;
-
- if (JSValue* value = getConstantImmediateNumericArg(src1)) {
- emitGetArg(src2, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::edx, i);
- m_jit.addl_i32r(getDeTaggedConstantImmediate(value), X86::edx);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- emitPutResult(dst, X86::edx);
- } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
- emitGetArg(src1, X86::eax);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- m_jit.addl_i32r(getDeTaggedConstantImmediate(value), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- emitPutResult(dst);
- } else {
- OperandTypes types = OperandTypes::fromInt(instruction[i + 4].u.operand);
- if (types.first().mightBeNumber() && types.second().mightBeNumber())
- compileBinaryArithOp(op_add, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
- else {
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
- emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_add);
- emitPutResult(instruction[i + 1].u.operand);
- }
- }
-
- i += 5;
- break;
- }
- case op_end: {
- if (m_codeBlock->needsFullScopeChain)
- emitCTICall(instruction + i, i, Machine::cti_op_end);
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
- m_jit.pushl_m(RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)), X86::edi);
- m_jit.ret();
- i += 2;
- break;
- }
- case op_jmp: {
- unsigned target = instruction[i + 1].u.operand;
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 1 + target));
- i += 2;
- break;
- }
- case op_pre_inc: {
- int srcDst = instruction[i + 1].u.operand;
- emitGetArg(srcDst, X86::eax);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- m_jit.addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- emitPutResult(srcDst);
- i += 2;
- break;
- }
- case op_loop: {
- emitSlowScriptCheck(instruction + i, i);
-
- unsigned target = instruction[i + 1].u.operand;
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 1 + target));
- i += 2;
- break;
- }
- case op_loop_if_less: {
- emitSlowScriptCheck(instruction + i, i);
-
- unsigned target = instruction[i + 3].u.operand;
- JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
- if (src2imm) {
- emitGetArg(instruction[i + 1].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::edx, i);
- m_jit.cmpl_i32r(asInteger(src2imm), X86::edx);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJl(), i + 3 + target));
- } else {
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
- emitGetArg(instruction[i + 2].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- emitJumpSlowCaseIfNotImmNum(X86::edx, i);
- m_jit.cmpl_rr(X86::edx, X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJl(), i + 3 + target));
- }
- i += 4;
- break;
- }
- case op_loop_if_lesseq: {
- emitSlowScriptCheck(instruction + i, i);
-
- unsigned target = instruction[i + 3].u.operand;
- JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
- if (src2imm) {
- emitGetArg(instruction[i + 1].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::edx, i);
- m_jit.cmpl_i32r(asInteger(src2imm), X86::edx);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJle(), i + 3 + target));
- } else {
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
- emitGetArg(instruction[i + 2].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- emitJumpSlowCaseIfNotImmNum(X86::edx, i);
- m_jit.cmpl_rr(X86::edx, X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJle(), i + 3 + target));
- }
- i += 4;
- break;
- }
- case op_new_object: {
- emitCTICall(instruction + i, i, Machine::cti_op_new_object);
- emitPutResult(instruction[i + 1].u.operand);
- i += 2;
- break;
- }
- case op_put_by_id: {
- // In order to be able to repatch both the StructureID, and the object offset, we store one pointer,
- // to just after the arguments have been loaded into registers 'hotPathBegin', and we generate code
- // such that the StructureID & offset are always at the same distance from this.
-
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::edx);
-
- ASSERT(m_codeBlock->propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i);
- X86Assembler::JmpDst hotPathBegin = m_jit.label();
- m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
- ++propertyAccessInstructionIndex;
-
- // Jump to a slow case if either the base object is an immediate, or if the StructureID does not match.
- emitJumpSlowCaseIfNotJSCell(X86::eax, i);
- // It is important that the following instruction plants a 32bit immediate, in order that it can be patched over.
- m_jit.cmpl_i32m(repatchGetByIdDefaultStructureID, OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- ASSERT(X86Assembler::getDifferenceBetweenLabels(hotPathBegin, m_jit.label()) == repatchOffsetPutByIdStructureID);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
-
- // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used.
- m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
- m_jit.movl_rm(X86::edx, repatchGetByIdDefaultOffset, X86::eax);
- ASSERT(X86Assembler::getDifferenceBetweenLabels(hotPathBegin, m_jit.label()) == repatchOffsetPutByIdPropertyMapOffset);
-
- i += 8;
- break;
- }
- case op_get_by_id: {
- // As for put_by_id, get_by_id requires the offset of the StructureID and the offset of the access to be repatched.
- // Additionally, for get_by_id we need repatch the offset of the branch to the slow case (we repatch this to jump
- // to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
- // to jump back to if one of these trampolies finds a match.
-
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
-
- ASSERT(m_codeBlock->propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i);
-
- X86Assembler::JmpDst hotPathBegin = m_jit.label();
- m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
- ++propertyAccessInstructionIndex;
-
- emitJumpSlowCaseIfNotJSCell(X86::eax, i);
- m_jit.cmpl_i32m(repatchGetByIdDefaultStructureID, OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- ASSERT(X86Assembler::getDifferenceBetweenLabels(hotPathBegin, m_jit.label()) == repatchOffsetGetByIdStructureID);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
- ASSERT(X86Assembler::getDifferenceBetweenLabels(hotPathBegin, m_jit.label()) == repatchOffsetGetByIdBranchToSlowCase);
-
- m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
- m_jit.movl_mr(repatchGetByIdDefaultOffset, X86::eax, X86::ecx);
- ASSERT(X86Assembler::getDifferenceBetweenLabels(hotPathBegin, m_jit.label()) == repatchOffsetGetByIdPropertyMapOffset);
- emitPutResult(instruction[i + 1].u.operand, X86::ecx);
-
- i += 8;
- break;
- }
- case op_instanceof: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax); // value
- emitGetArg(instruction[i + 3].u.operand, X86::ecx); // baseVal
- emitGetArg(instruction[i + 4].u.operand, X86::edx); // proto
-
- // check if any are immediates
- m_jit.orl_rr(X86::eax, X86::ecx);
- m_jit.orl_rr(X86::edx, X86::ecx);
- m_jit.testl_i32r(JSImmediate::TagMask, X86::ecx);
-
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJnz(), i));
-
- // check that all are object type - this is a bit of a bithack to avoid excess branching;
- // we check that the sum of the three type codes from StructureIDs is exactly 3 * ObjectType,
- // this works because NumberType and StringType are smaller
- m_jit.movl_i32r(3 * ObjectType, X86::ecx);
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::eax);
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::edx, X86::edx);
- m_jit.subl_mr(OBJECT_OFFSET(StructureID, m_typeInfo.m_type), X86::eax, X86::ecx);
- m_jit.subl_mr(OBJECT_OFFSET(StructureID, m_typeInfo.m_type), X86::edx, X86::ecx);
- emitGetArg(instruction[i + 3].u.operand, X86::edx); // reload baseVal
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::edx, X86::edx);
- m_jit.cmpl_rm(X86::ecx, OBJECT_OFFSET(StructureID, m_typeInfo.m_type), X86::edx);
-
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
-
- // check that baseVal's flags include ImplementsHasInstance but not OverridesHasInstance
- m_jit.movl_mr(OBJECT_OFFSET(StructureID, m_typeInfo.m_flags), X86::edx, X86::ecx);
- m_jit.andl_i32r(ImplementsHasInstance | OverridesHasInstance, X86::ecx);
- m_jit.cmpl_i32r(ImplementsHasInstance, X86::ecx);
-
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
-
- emitGetArg(instruction[i + 2].u.operand, X86::ecx); // reload value
- emitGetArg(instruction[i + 4].u.operand, X86::edx); // reload proto
-
- // optimistically load true result
- m_jit.movl_i32r(asInteger(jsBoolean(true)), X86::eax);
-
- X86Assembler::JmpDst loop = m_jit.label();
-
- // load value's prototype
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::ecx, X86::ecx);
- m_jit.movl_mr(OBJECT_OFFSET(StructureID, m_prototype), X86::ecx, X86::ecx);
-
- m_jit.cmpl_rr(X86::ecx, X86::edx);
- X86Assembler::JmpSrc exit = m_jit.emitUnlinkedJe();
-
- m_jit.cmpl_i32r(asInteger(jsNull()), X86::ecx);
- X86Assembler::JmpSrc goToLoop = m_jit.emitUnlinkedJne();
- m_jit.link(goToLoop, loop);
-
- m_jit.movl_i32r(asInteger(jsBoolean(false)), X86::eax);
-
- m_jit.link(exit, m_jit.label());
-
- emitPutResult(instruction[i + 1].u.operand);
-
- i += 5;
- break;
- }
- case op_del_by_id: {
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
- emitCTICall(instruction + i, i, Machine::cti_op_del_by_id);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_mul: {
- unsigned dst = instruction[i + 1].u.operand;
- unsigned src1 = instruction[i + 2].u.operand;
- unsigned src2 = instruction[i + 3].u.operand;
-
- // For now, only plant a fast int case if the constant operand is greater than zero.
- JSValue* src1Value = getConstantImmediateNumericArg(src1);
- JSValue* src2Value = getConstantImmediateNumericArg(src2);
- int32_t value;
- if (src1Value && ((value = JSImmediate::intValue(src1Value)) > 0)) {
- emitGetArg(src2, X86::eax);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- emitFastArithDeTagImmediate(X86::eax);
- m_jit.imull_i32r(X86::eax, value, X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- emitFastArithReTagImmediate(X86::eax);
- emitPutResult(dst);
- } else if (src2Value && ((value = JSImmediate::intValue(src2Value)) > 0)) {
- emitGetArg(src1, X86::eax);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- emitFastArithDeTagImmediate(X86::eax);
- m_jit.imull_i32r(X86::eax, value, X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- emitFastArithReTagImmediate(X86::eax);
- emitPutResult(dst);
- } else
- compileBinaryArithOp(op_mul, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
-
- i += 5;
- break;
- }
- case op_new_func: {
- FuncDeclNode* func = (m_codeBlock->functions[instruction[i + 2].u.operand]).get();
- emitPutArgConstant(reinterpret_cast<unsigned>(func), 0);
- emitCTICall(instruction + i, i, Machine::cti_op_new_func);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_call: {
- compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++);
- i += 7;
- break;
- }
- case op_get_global_var: {
- JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 2].u.jsCell);
- m_jit.movl_i32r(asInteger(globalObject), X86::eax);
- emitGetVariableObjectRegister(X86::eax, instruction[i + 3].u.operand, X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_put_global_var: {
- JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 1].u.jsCell);
- m_jit.movl_i32r(asInteger(globalObject), X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::edx);
- emitPutVariableObjectRegister(X86::edx, X86::eax, instruction[i + 2].u.operand);
- i += 4;
- break;
- }
- case op_get_scoped_var: {
- int skip = instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain;
-
- emitGetArg(RegisterFile::ScopeChain, X86::eax);
- while (skip--)
- m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, next), X86::eax, X86::eax);
-
- m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, object), X86::eax, X86::eax);
- emitGetVariableObjectRegister(X86::eax, instruction[i + 2].u.operand, X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_put_scoped_var: {
- int skip = instruction[i + 2].u.operand + m_codeBlock->needsFullScopeChain;
-
- emitGetArg(RegisterFile::ScopeChain, X86::edx);
- emitGetArg(instruction[i + 3].u.operand, X86::eax);
- while (skip--)
- m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, next), X86::edx, X86::edx);
-
- m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, object), X86::edx, X86::edx);
- emitPutVariableObjectRegister(X86::eax, X86::edx, instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_tear_off_activation: {
- emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_tear_off_activation);
- i += 2;
- break;
- }
- case op_tear_off_arguments: {
- emitCTICall(instruction + i, i, Machine::cti_op_tear_off_arguments);
- i += 1;
- break;
- }
- case op_ret: {
- // We could JIT generate the deref, only calling out to C when the refcount hits zero.
- if (m_codeBlock->needsFullScopeChain)
- emitCTICall(instruction + i, i, Machine::cti_op_ret_scopeChain);
-
- // Return the result in %eax.
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
-
- // Grab the return address.
- emitGetArg(RegisterFile::ReturnPC, X86::edx);
-
- // Restore our caller's "r".
- emitGetArg(RegisterFile::CallerFrame, X86::edi);
-
- // Return.
- m_jit.pushl_r(X86::edx);
- m_jit.ret();
-
- i += 2;
- break;
- }
- case op_new_array: {
- m_jit.leal_mr(sizeof(Register) * instruction[i + 2].u.operand, X86::edi, X86::edx);
- emitPutArg(X86::edx, 0);
- emitPutArgConstant(instruction[i + 3].u.operand, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_new_array);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_resolve: {
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
- emitCTICall(instruction + i, i, Machine::cti_op_resolve);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_construct: {
- compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++);
- i += 7;
- break;
- }
- case op_construct_verify: {
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
-
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc isImmediate = m_jit.emitUnlinkedJne();
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
- m_jit.cmpl_i32m(ObjectType, OBJECT_OFFSET(StructureID, m_typeInfo) + OBJECT_OFFSET(TypeInfo, m_type), X86::ecx);
- X86Assembler::JmpSrc isObject = m_jit.emitUnlinkedJe();
-
- m_jit.link(isImmediate, m_jit.label());
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- m_jit.link(isObject, m_jit.label());
-
- i += 3;
- break;
- }
- case op_get_by_val: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::edx, i);
- emitFastArithImmToInt(X86::edx);
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
-
- // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
- m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::ecx);
- m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(JSArray, m_fastAccessCutoff), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJbe(), i));
-
- // Get the value from the vector
- m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_vector[0]), X86::ecx, X86::edx, sizeof(JSValue*), X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_resolve_func: {
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
- emitCTICall(instruction + i, i, Machine::cti_op_resolve_func);
- emitPutResult(instruction[i + 1].u.operand);
- emitPutResult(instruction[i + 2].u.operand, X86::edx);
- i += 4;
- break;
- }
- case op_sub: {
- compileBinaryArithOp(op_sub, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
- i += 5;
- break;
- }
- case op_put_by_val: {
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
- emitGetArg(instruction[i + 2].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::edx, i);
- emitFastArithImmToInt(X86::edx);
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
-
- // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
- m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::ecx);
- m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(JSArray, m_fastAccessCutoff), X86::eax);
- X86Assembler::JmpSrc inFastVector = m_jit.emitUnlinkedJa();
- // No; oh well, check if the access if within the vector - if so, we may still be okay.
- m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(ArrayStorage, m_vectorLength), X86::ecx);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJbe(), i));
-
- // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.
- // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff.
- m_jit.cmpl_i8m(0, OBJECT_OFFSET(ArrayStorage, m_vector[0]), X86::ecx, X86::edx, sizeof(JSValue*));
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i));
-
- // All good - put the value into the array.
- m_jit.link(inFastVector, m_jit.label());
- emitGetArg(instruction[i + 3].u.operand, X86::eax);
- m_jit.movl_rm(X86::eax, OBJECT_OFFSET(ArrayStorage, m_vector[0]), X86::ecx, X86::edx, sizeof(JSValue*));
- i += 4;
- break;
- }
- CTI_COMPILE_BINARY_OP(op_lesseq)
- case op_loop_if_true: {
- emitSlowScriptCheck(instruction + i, i);
-
- unsigned target = instruction[i + 2].u.operand;
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
-
- m_jit.cmpl_i32r(asInteger(JSImmediate::zeroImmediate()), X86::eax);
- X86Assembler::JmpSrc isZero = m_jit.emitUnlinkedJe();
- m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJne(), i + 2 + target));
-
- m_jit.cmpl_i32r(asInteger(JSImmediate::trueImmediate()), X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
- m_jit.cmpl_i32r(asInteger(JSImmediate::falseImmediate()), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
-
- m_jit.link(isZero, m_jit.label());
- i += 3;
- break;
- };
- case op_resolve_base: {
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
- emitCTICall(instruction + i, i, Machine::cti_op_resolve_base);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_negate: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
- X86Assembler::JmpSrc notImmediate = m_jit.emitUnlinkedJe();
-
- m_jit.cmpl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
- X86Assembler::JmpSrc zeroImmediate = m_jit.emitUnlinkedJe();
- emitFastArithImmToInt(X86::eax);
- m_jit.negl_r(X86::eax); // This can't overflow as we only have a 31bit int at this point
- X86Assembler::JmpSrc overflow = emitArithIntToImmWithJump(X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- X86Assembler::JmpSrc immediateNegateSuccess = m_jit.emitUnlinkedJmp();
-
- if (!isSSE2Present()) {
- m_jit.link(zeroImmediate, m_jit.label());
- m_jit.link(overflow, m_jit.label());
- m_jit.link(notImmediate, m_jit.label());
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_negate);
- emitPutResult(instruction[i + 1].u.operand);
- } else {
- // Slow case immediates
- m_slowCases.append(SlowCaseEntry(zeroImmediate, i));
- m_slowCases.append(SlowCaseEntry(overflow, i));
- m_jit.link(notImmediate, m_jit.label());
- ResultType resultType(instruction[i + 3].u.resultType);
- if (!resultType.definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(X86::eax, i);
- StructureID* numberStructureID = m_callFrame->globalData().numberStructureID.get();
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
- }
- m_jit.movsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
- // We need 3 copies of the sign bit mask so we can assure alignment and pad for the 128bit load
- static double doubleSignBit[] = { -0.0, -0.0, -0.0 };
- m_jit.xorpd_mr((void*)((((uintptr_t)doubleSignBit)+15)&~15), X86::xmm0);
- X86Assembler::JmpSrc wasCell;
- if (!resultType.isReusableNumber())
- emitAllocateNumber(&m_callFrame->globalData(), i);
-
- putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::eax, instruction[i + 1].u.operand, &wasCell,
- X86::xmm1, X86::ecx, X86::edx);
- m_jit.link(wasCell, m_jit.label());
- }
- m_jit.link(immediateNegateSuccess, m_jit.label());
- i += 4;
- break;
- }
- case op_resolve_skip: {
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
- emitPutArgConstant(instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_resolve_skip);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_resolve_global: {
- // Fast case
- unsigned globalObject = asInteger(instruction[i + 2].u.jsCell);
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
- void* structureIDAddr = reinterpret_cast<void*>(instruction + i + 4);
- void* offsetAddr = reinterpret_cast<void*>(instruction + i + 5);
-
- // Check StructureID of global object
- m_jit.movl_i32r(globalObject, X86::eax);
- m_jit.movl_mr(structureIDAddr, X86::edx);
- m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- X86Assembler::JmpSrc noMatch = m_jit.emitUnlinkedJne(); // StructureIDs don't match
-
- // Load cached property
- m_jit.movl_mr(OBJECT_OFFSET(JSGlobalObject, m_propertyStorage), X86::eax, X86::eax);
- m_jit.movl_mr(offsetAddr, X86::edx);
- m_jit.movl_mr(0, X86::eax, X86::edx, sizeof(JSValue*), X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- X86Assembler::JmpSrc end = m_jit.emitUnlinkedJmp();
-
- // Slow case
- m_jit.link(noMatch, m_jit.label());
- emitPutArgConstant(globalObject, 0);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
- emitPutArgConstant(reinterpret_cast<unsigned>(instruction + i), 8);
- emitCTICall(instruction + i, i, Machine::cti_op_resolve_global);
- emitPutResult(instruction[i + 1].u.operand);
- m_jit.link(end, m_jit.label());
- i += 6;
- break;
- }
- CTI_COMPILE_BINARY_OP(op_div)
- case op_pre_dec: {
- int srcDst = instruction[i + 1].u.operand;
- emitGetArg(srcDst, X86::eax);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- m_jit.subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- emitPutResult(srcDst);
- i += 2;
- break;
- }
- case op_jnless: {
- unsigned target = instruction[i + 3].u.operand;
- JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
- if (src2imm) {
- emitGetArg(instruction[i + 1].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::edx, i);
- m_jit.cmpl_i32r(asInteger(src2imm), X86::edx);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJge(), i + 3 + target));
- } else {
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
- emitGetArg(instruction[i + 2].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- emitJumpSlowCaseIfNotImmNum(X86::edx, i);
- m_jit.cmpl_rr(X86::edx, X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJge(), i + 3 + target));
- }
- i += 4;
- break;
- }
- case op_not: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- m_jit.xorl_i8r(JSImmediate::FullTagTypeBool, X86::eax);
- m_jit.testl_i32r(JSImmediate::FullTagTypeMask, X86::eax); // i8?
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
- m_jit.xorl_i8r((JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue), X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_jfalse: {
- unsigned target = instruction[i + 2].u.operand;
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
-
- m_jit.cmpl_i32r(asInteger(JSImmediate::zeroImmediate()), X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
- m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
- X86Assembler::JmpSrc isNonZero = m_jit.emitUnlinkedJne();
-
- m_jit.cmpl_i32r(asInteger(JSImmediate::falseImmediate()), X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
- m_jit.cmpl_i32r(asInteger(JSImmediate::trueImmediate()), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
-
- m_jit.link(isNonZero, m_jit.label());
- i += 3;
- break;
- };
- case op_jeq_null: {
- unsigned src = instruction[i + 1].u.operand;
- unsigned target = instruction[i + 2].u.operand;
-
- emitGetArg(src, X86::eax);
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc isImmediate = m_jit.emitUnlinkedJnz();
-
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
- m_jit.testl_i32m(MasqueradesAsUndefined, OBJECT_OFFSET(StructureID, m_typeInfo.m_flags), X86::ecx);
- m_jit.setnz_r(X86::eax);
-
- X86Assembler::JmpSrc wasNotImmediate = m_jit.emitUnlinkedJmp();
-
- m_jit.link(isImmediate, m_jit.label());
-
- m_jit.movl_i32r(~JSImmediate::ExtendedTagBitUndefined, X86::ecx);
- m_jit.andl_rr(X86::eax, X86::ecx);
- m_jit.cmpl_i32r(JSImmediate::FullTagTypeNull, X86::ecx);
- m_jit.sete_r(X86::eax);
-
- m_jit.link(wasNotImmediate, m_jit.label());
-
- m_jit.movzbl_rr(X86::eax, X86::eax);
- m_jit.cmpl_i32r(0, X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJnz(), i + 2 + target));
-
- i += 3;
- break;
- };
- case op_jneq_null: {
- unsigned src = instruction[i + 1].u.operand;
- unsigned target = instruction[i + 2].u.operand;
-
- emitGetArg(src, X86::eax);
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc isImmediate = m_jit.emitUnlinkedJnz();
-
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
- m_jit.testl_i32m(MasqueradesAsUndefined, OBJECT_OFFSET(StructureID, m_typeInfo.m_flags), X86::ecx);
- m_jit.setz_r(X86::eax);
-
- X86Assembler::JmpSrc wasNotImmediate = m_jit.emitUnlinkedJmp();
-
- m_jit.link(isImmediate, m_jit.label());
-
- m_jit.movl_i32r(~JSImmediate::ExtendedTagBitUndefined, X86::ecx);
- m_jit.andl_rr(X86::eax, X86::ecx);
- m_jit.cmpl_i32r(JSImmediate::FullTagTypeNull, X86::ecx);
- m_jit.setne_r(X86::eax);
-
- m_jit.link(wasNotImmediate, m_jit.label());
-
- m_jit.movzbl_rr(X86::eax, X86::eax);
- m_jit.cmpl_i32r(0, X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJnz(), i + 2 + target));
-
- i += 3;
- break;
- }
- case op_post_inc: {
- int srcDst = instruction[i + 2].u.operand;
- emitGetArg(srcDst, X86::eax);
- m_jit.movl_rr(X86::eax, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- m_jit.addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::edx);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- emitPutResult(srcDst, X86::edx);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_unexpected_load: {
- JSValue* v = m_codeBlock->unexpectedConstants[instruction[i + 2].u.operand];
- m_jit.movl_i32r(asInteger(v), X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_jsr: {
- int retAddrDst = instruction[i + 1].u.operand;
- int target = instruction[i + 2].u.operand;
- m_jit.movl_i32m(0, sizeof(Register) * retAddrDst, X86::edi);
- X86Assembler::JmpDst addrPosition = m_jit.label();
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 2 + target));
- X86Assembler::JmpDst sretTarget = m_jit.label();
- m_jsrSites.append(JSRInfo(addrPosition, sretTarget));
- i += 3;
- break;
- }
- case op_sret: {
- m_jit.jmp_m(sizeof(Register) * instruction[i + 1].u.operand, X86::edi);
- i += 2;
- break;
- }
- case op_eq: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
- m_jit.cmpl_rr(X86::edx, X86::eax);
- m_jit.sete_r(X86::eax);
- m_jit.movzbl_rr(X86::eax, X86::eax);
- emitTagAsBoolImmediate(X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_lshift: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::ecx);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- emitJumpSlowCaseIfNotImmNum(X86::ecx, i);
- emitFastArithImmToInt(X86::eax);
- emitFastArithImmToInt(X86::ecx);
- m_jit.shll_CLr(X86::eax);
- emitFastArithIntToImmOrSlowCase(X86::eax, i);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_bitand: {
- unsigned src1 = instruction[i + 2].u.operand;
- unsigned src2 = instruction[i + 3].u.operand;
- unsigned dst = instruction[i + 1].u.operand;
- if (JSValue* value = getConstantImmediateNumericArg(src1)) {
- emitGetArg(src2, X86::eax);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- m_jit.andl_i32r(asInteger(value), X86::eax); // FIXME: make it more obvious this is relying on the format of JSImmediate
- emitPutResult(dst);
- } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
- emitGetArg(src1, X86::eax);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- m_jit.andl_i32r(asInteger(value), X86::eax);
- emitPutResult(dst);
- } else {
- emitGetArg(src1, X86::eax);
- emitGetArg(src2, X86::edx);
- m_jit.andl_rr(X86::edx, X86::eax);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- emitPutResult(dst);
- }
- i += 5;
- break;
- }
- case op_rshift: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::ecx);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- emitJumpSlowCaseIfNotImmNum(X86::ecx, i);
- emitFastArithImmToInt(X86::ecx);
- m_jit.sarl_CLr(X86::eax);
- emitFastArithPotentiallyReTagImmediate(X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_bitnot: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- m_jit.xorl_i8r(~JSImmediate::TagBitTypeInteger, X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_resolve_with_base: {
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
- emitCTICall(instruction + i, i, Machine::cti_op_resolve_with_base);
- emitPutResult(instruction[i + 1].u.operand);
- emitPutResult(instruction[i + 2].u.operand, X86::edx);
- i += 4;
- break;
- }
- case op_new_func_exp: {
- FuncExprNode* func = (m_codeBlock->functionExpressions[instruction[i + 2].u.operand]).get();
- emitPutArgConstant(reinterpret_cast<unsigned>(func), 0);
- emitCTICall(instruction + i, i, Machine::cti_op_new_func_exp);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_mod: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::ecx);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- emitJumpSlowCaseIfNotImmNum(X86::ecx, i);
- emitFastArithDeTagImmediate(X86::eax);
- m_slowCases.append(SlowCaseEntry(emitFastArithDeTagImmediateJumpIfZero(X86::ecx), i));
- m_jit.cdq();
- m_jit.idivl_r(X86::ecx);
- emitFastArithReTagImmediate(X86::edx);
- m_jit.movl_rr(X86::edx, X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_jtrue: {
- unsigned target = instruction[i + 2].u.operand;
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
-
- m_jit.cmpl_i32r(asInteger(JSImmediate::zeroImmediate()), X86::eax);
- X86Assembler::JmpSrc isZero = m_jit.emitUnlinkedJe();
- m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJne(), i + 2 + target));
-
- m_jit.cmpl_i32r(asInteger(JSImmediate::trueImmediate()), X86::eax);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
- m_jit.cmpl_i32r(asInteger(JSImmediate::falseImmediate()), X86::eax);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
-
- m_jit.link(isZero, m_jit.label());
- i += 3;
- break;
- }
- CTI_COMPILE_BINARY_OP(op_less)
- case op_neq: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
- m_jit.cmpl_rr(X86::eax, X86::edx);
-
- m_jit.setne_r(X86::eax);
- m_jit.movzbl_rr(X86::eax, X86::eax);
- emitTagAsBoolImmediate(X86::eax);
-
- emitPutResult(instruction[i + 1].u.operand);
-
- i += 4;
- break;
- }
- case op_post_dec: {
- int srcDst = instruction[i + 2].u.operand;
- emitGetArg(srcDst, X86::eax);
- m_jit.movl_rr(X86::eax, X86::edx);
- emitJumpSlowCaseIfNotImmNum(X86::eax, i);
- m_jit.subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::edx);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
- emitPutResult(srcDst, X86::edx);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- CTI_COMPILE_BINARY_OP(op_urshift)
- case op_bitxor: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
- m_jit.xorl_rr(X86::edx, X86::eax);
- emitFastArithReTagImmediate(X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 5;
- break;
- }
- case op_new_regexp: {
- RegExp* regExp = m_codeBlock->regexps[instruction[i + 2].u.operand].get();
- emitPutArgConstant(reinterpret_cast<unsigned>(regExp), 0);
- emitCTICall(instruction + i, i, Machine::cti_op_new_regexp);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_bitor: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
- m_jit.orl_rr(X86::edx, X86::eax);
- emitPutResult(instruction[i + 1].u.operand);
- i += 5;
- break;
- }
- case op_call_eval: {
- compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++);
- i += 7;
- break;
- }
- case op_throw: {
- emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_throw);
- m_jit.addl_i8r(0x20, X86::esp);
- m_jit.popl_r(X86::ebx);
- m_jit.popl_r(X86::edi);
- m_jit.popl_r(X86::esi);
- m_jit.ret();
- i += 2;
- break;
- }
- case op_get_pnames: {
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_get_pnames);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_next_pname: {
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
- unsigned target = instruction[i + 3].u.operand;
- emitCTICall(instruction + i, i, Machine::cti_op_next_pname);
- m_jit.testl_rr(X86::eax, X86::eax);
- X86Assembler::JmpSrc endOfIter = m_jit.emitUnlinkedJe();
- emitPutResult(instruction[i + 1].u.operand);
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 3 + target));
- m_jit.link(endOfIter, m_jit.label());
- i += 4;
- break;
- }
- case op_push_scope: {
- emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_push_scope);
- i += 2;
- break;
- }
- case op_pop_scope: {
- emitCTICall(instruction + i, i, Machine::cti_op_pop_scope);
- i += 1;
- break;
- }
- CTI_COMPILE_UNARY_OP(op_typeof)
- CTI_COMPILE_UNARY_OP(op_is_undefined)
- CTI_COMPILE_UNARY_OP(op_is_boolean)
- CTI_COMPILE_UNARY_OP(op_is_number)
- CTI_COMPILE_UNARY_OP(op_is_string)
- CTI_COMPILE_UNARY_OP(op_is_object)
- CTI_COMPILE_UNARY_OP(op_is_function)
- case op_stricteq: {
- compileOpStrictEq(instruction + i, i, OpStrictEq);
- i += 4;
- break;
- }
- case op_nstricteq: {
- compileOpStrictEq(instruction + i, i, OpNStrictEq);
- i += 4;
- break;
- }
- case op_to_jsnumber: {
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
-
- m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
- X86Assembler::JmpSrc wasImmediate = m_jit.emitUnlinkedJnz();
-
- emitJumpSlowCaseIfNotJSCell(X86::eax, i);
-
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
- m_jit.cmpl_i32m(NumberType, OBJECT_OFFSET(StructureID, m_typeInfo.m_type), X86::ecx);
-
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
-
- m_jit.link(wasImmediate, m_jit.label());
-
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_in: {
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
- emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_in);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_push_new_scope: {
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
- emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_push_new_scope);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_catch: {
- emitGetCTIParam(CTI_ARGS_callFrame, X86::edi); // edi := r
- emitPutResult(instruction[i + 1].u.operand);
- i += 2;
- break;
- }
- case op_jmp_scopes: {
- unsigned count = instruction[i + 1].u.operand;
- emitPutArgConstant(count, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_jmp_scopes);
- unsigned target = instruction[i + 2].u.operand;
- m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 2 + target));
- i += 3;
- break;
- }
- case op_put_by_index: {
- emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
- emitPutArgConstant(instruction[i + 2].u.operand, 4);
- emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_put_by_index);
- i += 4;
- break;
- }
- case op_switch_imm: {
- unsigned tableIndex = instruction[i + 1].u.operand;
- unsigned defaultOffset = instruction[i + 2].u.operand;
- unsigned scrutinee = instruction[i + 3].u.operand;
-
- // create jump table for switch destinations, track this switch statement.
- SimpleJumpTable* jumpTable = &m_codeBlock->immediateSwitchJumpTables[tableIndex];
- m_switches.append(SwitchRecord(jumpTable, i, defaultOffset, SwitchRecord::Immediate));
- jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
-
- emitGetPutArg(scrutinee, 0, X86::ecx);
- emitPutArgConstant(tableIndex, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_switch_imm);
- m_jit.jmp_r(X86::eax);
- i += 4;
- break;
- }
- case op_switch_char: {
- unsigned tableIndex = instruction[i + 1].u.operand;
- unsigned defaultOffset = instruction[i + 2].u.operand;
- unsigned scrutinee = instruction[i + 3].u.operand;
-
- // create jump table for switch destinations, track this switch statement.
- SimpleJumpTable* jumpTable = &m_codeBlock->characterSwitchJumpTables[tableIndex];
- m_switches.append(SwitchRecord(jumpTable, i, defaultOffset, SwitchRecord::Character));
- jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
-
- emitGetPutArg(scrutinee, 0, X86::ecx);
- emitPutArgConstant(tableIndex, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_switch_char);
- m_jit.jmp_r(X86::eax);
- i += 4;
- break;
- }
- case op_switch_string: {
- unsigned tableIndex = instruction[i + 1].u.operand;
- unsigned defaultOffset = instruction[i + 2].u.operand;
- unsigned scrutinee = instruction[i + 3].u.operand;
-
- // create jump table for switch destinations, track this switch statement.
- StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTables[tableIndex];
- m_switches.append(SwitchRecord(jumpTable, i, defaultOffset));
-
- emitGetPutArg(scrutinee, 0, X86::ecx);
- emitPutArgConstant(tableIndex, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_switch_string);
- m_jit.jmp_r(X86::eax);
- i += 4;
- break;
- }
- case op_del_by_val: {
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
- emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_del_by_val);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_put_getter: {
- emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
- emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_put_getter);
- i += 4;
- break;
- }
- case op_put_setter: {
- emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
- emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_put_setter);
- i += 4;
- break;
- }
- case op_new_error: {
- JSValue* message = m_codeBlock->unexpectedConstants[instruction[i + 3].u.operand];
- emitPutArgConstant(instruction[i + 2].u.operand, 0);
- emitPutArgConstant(asInteger(message), 4);
- emitPutArgConstant(m_codeBlock->lineNumberForVPC(&instruction[i]), 8);
- emitCTICall(instruction + i, i, Machine::cti_op_new_error);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_debug: {
- emitPutArgConstant(instruction[i + 1].u.operand, 0);
- emitPutArgConstant(instruction[i + 2].u.operand, 4);
- emitPutArgConstant(instruction[i + 3].u.operand, 8);
- emitCTICall(instruction + i, i, Machine::cti_op_debug);
- i += 4;
- break;
- }
- case op_eq_null: {
- unsigned dst = instruction[i + 1].u.operand;
- unsigned src1 = instruction[i + 2].u.operand;
-
- emitGetArg(src1, X86::eax);
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc isImmediate = m_jit.emitUnlinkedJnz();
-
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
- m_jit.testl_i32m(MasqueradesAsUndefined, OBJECT_OFFSET(StructureID, m_typeInfo.m_flags), X86::ecx);
- m_jit.setnz_r(X86::eax);
-
- X86Assembler::JmpSrc wasNotImmediate = m_jit.emitUnlinkedJmp();
-
- m_jit.link(isImmediate, m_jit.label());
-
- m_jit.movl_i32r(~JSImmediate::ExtendedTagBitUndefined, X86::ecx);
- m_jit.andl_rr(X86::eax, X86::ecx);
- m_jit.cmpl_i32r(JSImmediate::FullTagTypeNull, X86::ecx);
- m_jit.sete_r(X86::eax);
-
- m_jit.link(wasNotImmediate, m_jit.label());
-
- m_jit.movzbl_rr(X86::eax, X86::eax);
- emitTagAsBoolImmediate(X86::eax);
- emitPutResult(dst);
-
- i += 3;
- break;
- }
- case op_neq_null: {
- unsigned dst = instruction[i + 1].u.operand;
- unsigned src1 = instruction[i + 2].u.operand;
-
- emitGetArg(src1, X86::eax);
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc isImmediate = m_jit.emitUnlinkedJnz();
-
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
- m_jit.testl_i32m(MasqueradesAsUndefined, OBJECT_OFFSET(StructureID, m_typeInfo.m_flags), X86::ecx);
- m_jit.setz_r(X86::eax);
-
- X86Assembler::JmpSrc wasNotImmediate = m_jit.emitUnlinkedJmp();
-
- m_jit.link(isImmediate, m_jit.label());
-
- m_jit.movl_i32r(~JSImmediate::ExtendedTagBitUndefined, X86::ecx);
- m_jit.andl_rr(X86::eax, X86::ecx);
- m_jit.cmpl_i32r(JSImmediate::FullTagTypeNull, X86::ecx);
- m_jit.setne_r(X86::eax);
-
- m_jit.link(wasNotImmediate, m_jit.label());
-
- m_jit.movzbl_rr(X86::eax, X86::eax);
- emitTagAsBoolImmediate(X86::eax);
- emitPutResult(dst);
-
- i += 3;
- break;
- }
- case op_enter: {
- // Even though CTI doesn't use them, we initialize our constant
- // registers to zap stale pointers, to avoid unnecessarily prolonging
- // object lifetime and increasing GC pressure.
- size_t count = m_codeBlock->numVars + m_codeBlock->constantRegisters.size();
- for (size_t j = 0; j < count; ++j)
- emitInitRegister(j);
-
- i+= 1;
- break;
- }
- case op_enter_with_activation: {
- // Even though CTI doesn't use them, we initialize our constant
- // registers to zap stale pointers, to avoid unnecessarily prolonging
- // object lifetime and increasing GC pressure.
- size_t count = m_codeBlock->numVars + m_codeBlock->constantRegisters.size();
- for (size_t j = 0; j < count; ++j)
- emitInitRegister(j);
-
- emitCTICall(instruction + i, i, Machine::cti_op_push_activation);
- emitPutResult(instruction[i + 1].u.operand);
-
- i+= 2;
- break;
- }
- case op_create_arguments: {
- emitCTICall(instruction + i, i, (m_codeBlock->numParameters == 1) ? Machine::cti_op_create_arguments_no_params : Machine::cti_op_create_arguments);
- i += 1;
- break;
- }
- case op_convert_this: {
- emitGetArg(instruction[i + 1].u.operand, X86::eax);
-
- emitJumpSlowCaseIfNotJSCell(X86::eax, i);
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::edx);
- m_jit.testl_i32m(NeedsThisConversion, OBJECT_OFFSET(StructureID, m_typeInfo.m_flags), X86::edx);
- m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJnz(), i));
-
- i += 2;
- break;
- }
- case op_profile_will_call: {
- emitGetCTIParam(CTI_ARGS_profilerReference, X86::eax);
- m_jit.cmpl_i32m(0, X86::eax);
- X86Assembler::JmpSrc noProfiler = m_jit.emitUnlinkedJe();
- emitGetPutArg(instruction[i + 1].u.operand, 0, X86::eax);
- emitCTICall(instruction + i, i, Machine::cti_op_profile_will_call);
- m_jit.link(noProfiler, m_jit.label());
-
- i += 2;
- break;
- }
- case op_profile_did_call: {
- emitGetCTIParam(CTI_ARGS_profilerReference, X86::eax);
- m_jit.cmpl_i32m(0, X86::eax);
- X86Assembler::JmpSrc noProfiler = m_jit.emitUnlinkedJe();
- emitGetPutArg(instruction[i + 1].u.operand, 0, X86::eax);
- emitCTICall(instruction + i, i, Machine::cti_op_profile_did_call);
- m_jit.link(noProfiler, m_jit.label());
-
- i += 2;
- break;
- }
- case op_get_array_length:
- case op_get_by_id_chain:
- case op_get_by_id_generic:
- case op_get_by_id_proto:
- case op_get_by_id_self:
- case op_get_string_length:
- case op_put_by_id_generic:
- case op_put_by_id_replace:
- case op_put_by_id_transition:
- ASSERT_NOT_REACHED();
- }
- }
-
- ASSERT(propertyAccessInstructionIndex == m_codeBlock->propertyAccessInstructions.size());
- ASSERT(callLinkInfoIndex == m_codeBlock->callLinkInfos.size());
-}
-
-
-void CTI::privateCompileLinkPass()
-{
- unsigned jmpTableCount = m_jmpTable.size();
- for (unsigned i = 0; i < jmpTableCount; ++i)
- m_jit.link(m_jmpTable[i].from, m_labels[m_jmpTable[i].to]);
- m_jmpTable.clear();
-}
-
-#define CTI_COMPILE_BINARY_OP_SLOW_CASE(name) \
- case name: { \
- m_jit.link(iter->from, m_jit.label()); \
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \
- emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); \
- emitCTICall(instruction + i, i, Machine::cti_##name); \
- emitPutResult(instruction[i + 1].u.operand); \
- i += 4; \
- break; \
- }
-
-void CTI::privateCompileSlowCases()
-{
- unsigned propertyAccessInstructionIndex = 0;
- unsigned callLinkInfoIndex = 0;
-
- Instruction* instruction = m_codeBlock->instructions.begin();
- for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end(); ++iter) {
- unsigned i = iter->to;
- switch (OpcodeID opcodeID = m_machine->getOpcodeID(instruction[i].u.opcode)) {
- case op_convert_this: {
- m_jit.link(iter->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_convert_this);
- emitPutResult(instruction[i + 1].u.operand);
- i += 2;
- break;
- }
- case op_add: {
- unsigned dst = instruction[i + 1].u.operand;
- unsigned src1 = instruction[i + 2].u.operand;
- unsigned src2 = instruction[i + 3].u.operand;
- if (JSValue* value = getConstantImmediateNumericArg(src1)) {
- X86Assembler::JmpSrc notImm = iter->from;
- m_jit.link((++iter)->from, m_jit.label());
- m_jit.subl_i32r(getDeTaggedConstantImmediate(value), X86::edx);
- m_jit.link(notImm, m_jit.label());
- emitGetPutArg(src1, 0, X86::ecx);
- emitPutArg(X86::edx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_add);
- emitPutResult(dst);
- } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
- X86Assembler::JmpSrc notImm = iter->from;
- m_jit.link((++iter)->from, m_jit.label());
- m_jit.subl_i32r(getDeTaggedConstantImmediate(value), X86::eax);
- m_jit.link(notImm, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitGetPutArg(src2, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_add);
- emitPutResult(dst);
- } else {
- OperandTypes types = OperandTypes::fromInt(instruction[i + 4].u.operand);
- if (types.first().mightBeNumber() && types.second().mightBeNumber())
- compileBinaryArithOpSlowCase(instruction + i, op_add, iter, dst, src1, src2, types, i);
- else
- ASSERT_NOT_REACHED();
- }
-
- i += 5;
- break;
- }
- case op_get_by_val: {
- // The slow case that handles accesses to arrays (below) may jump back up to here.
- X86Assembler::JmpDst beginGetByValSlow = m_jit.label();
-
- X86Assembler::JmpSrc notImm = iter->from;
- m_jit.link((++iter)->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
- emitFastArithIntToImmNoCheck(X86::edx);
- m_jit.link(notImm, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_get_by_val);
- emitPutResult(instruction[i + 1].u.operand);
- m_jit.link(m_jit.emitUnlinkedJmp(), m_labels[i + 4]);
-
- // This is slow case that handles accesses to arrays above the fast cut-off.
- // First, check if this is an access to the vector
- m_jit.link((++iter)->from, m_jit.label());
- m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(ArrayStorage, m_vectorLength), X86::ecx);
- m_jit.link(m_jit.emitUnlinkedJbe(), beginGetByValSlow);
-
- // okay, missed the fast region, but it is still in the vector. Get the value.
- m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_vector[0]), X86::ecx, X86::edx, sizeof(JSValue*), X86::ecx);
- // Check whether the value loaded is zero; if so we need to return undefined.
- m_jit.testl_rr(X86::ecx, X86::ecx);
- m_jit.link(m_jit.emitUnlinkedJe(), beginGetByValSlow);
- emitPutResult(instruction[i + 1].u.operand, X86::ecx);
-
- i += 4;
- break;
- }
- case op_sub: {
- compileBinaryArithOpSlowCase(instruction + i, op_sub, iter, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
- i += 5;
- break;
- }
- case op_negate: {
- m_jit.link(iter->from, m_jit.label());
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_negate);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_rshift: {
- m_jit.link(iter->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::ecx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_rshift);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_lshift: {
- X86Assembler::JmpSrc notImm1 = iter->from;
- X86Assembler::JmpSrc notImm2 = (++iter)->from;
- m_jit.link((++iter)->from, m_jit.label());
- emitGetArg(instruction[i + 2].u.operand, X86::eax);
- emitGetArg(instruction[i + 3].u.operand, X86::ecx);
- m_jit.link(notImm1, m_jit.label());
- m_jit.link(notImm2, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::ecx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_lshift);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_loop_if_less: {
- emitSlowScriptCheck(instruction + i, i);
-
- unsigned target = instruction[i + 3].u.operand;
- JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
- if (src2imm) {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::edx, 0);
- emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_loop_if_less);
- m_jit.testl_rr(X86::eax, X86::eax);
- m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]);
- } else {
- m_jit.link(iter->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_loop_if_less);
- m_jit.testl_rr(X86::eax, X86::eax);
- m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]);
- }
- i += 4;
- break;
- }
- case op_put_by_id: {
- m_jit.link(iter->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
-
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 8);
- X86Assembler::JmpSrc call = emitCTICall(instruction + i, i, Machine::cti_op_put_by_id);
-
- // Track the location of the call; this will be used to recover repatch information.
- ASSERT(m_codeBlock->propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i);
- m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
- ++propertyAccessInstructionIndex;
-
- i += 8;
- break;
- }
- case op_get_by_id: {
- // As for the hot path of get_by_id, above, we ensure that we can use an architecture specific offset
- // so that we only need track one pointer into the slow case code - we track a pointer to the location
- // of the call (which we can use to look up the repatch information), but should a array-length or
- // prototype access trampoline fail we want to bail out back to here. To do so we can subtract back
- // the distance from the call to the head of the slow case.
-
- m_jit.link(iter->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
-
-#ifndef NDEBUG
- X86Assembler::JmpDst coldPathBegin = m_jit.label();
-#endif
- emitPutArg(X86::eax, 0);
- Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
- emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
- X86Assembler::JmpSrc call = emitCTICall(instruction + i, i, Machine::cti_op_get_by_id);
- ASSERT(X86Assembler::getDifferenceBetweenLabels(coldPathBegin, call) == repatchOffsetGetByIdSlowCaseCall);
- emitPutResult(instruction[i + 1].u.operand);
-
- // Track the location of the call; this will be used to recover repatch information.
- ASSERT(m_codeBlock->propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i);
- m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
- ++propertyAccessInstructionIndex;
-
- i += 8;
- break;
- }
- case op_loop_if_lesseq: {
- emitSlowScriptCheck(instruction + i, i);
-
- unsigned target = instruction[i + 3].u.operand;
- JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
- if (src2imm) {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::edx, 0);
- emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_loop_if_lesseq);
- m_jit.testl_rr(X86::eax, X86::eax);
- m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]);
- } else {
- m_jit.link(iter->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_loop_if_lesseq);
- m_jit.testl_rr(X86::eax, X86::eax);
- m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]);
- }
- i += 4;
- break;
- }
- case op_pre_inc: {
- unsigned srcDst = instruction[i + 1].u.operand;
- X86Assembler::JmpSrc notImm = iter->from;
- m_jit.link((++iter)->from, m_jit.label());
- m_jit.subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
- m_jit.link(notImm, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_pre_inc);
- emitPutResult(srcDst);
- i += 2;
- break;
- }
- case op_put_by_val: {
- // Normal slow cases - either is not an immediate imm, or is an array.
- X86Assembler::JmpSrc notImm = iter->from;
- m_jit.link((++iter)->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
- emitFastArithIntToImmNoCheck(X86::edx);
- m_jit.link(notImm, m_jit.label());
- emitGetArg(instruction[i + 3].u.operand, X86::ecx);
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 4);
- emitPutArg(X86::ecx, 8);
- emitCTICall(instruction + i, i, Machine::cti_op_put_by_val);
- m_jit.link(m_jit.emitUnlinkedJmp(), m_labels[i + 4]);
-
- // slow cases for immediate int accesses to arrays
- m_jit.link((++iter)->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
- emitGetArg(instruction[i + 3].u.operand, X86::ecx);
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 4);
- emitPutArg(X86::ecx, 8);
- emitCTICall(instruction + i, i, Machine::cti_op_put_by_val_array);
-
- i += 4;
- break;
- }
- case op_loop_if_true: {
- emitSlowScriptCheck(instruction + i, i);
-
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_jtrue);
- m_jit.testl_rr(X86::eax, X86::eax);
- unsigned target = instruction[i + 2].u.operand;
- m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 2 + target]);
- i += 3;
- break;
- }
- case op_pre_dec: {
- unsigned srcDst = instruction[i + 1].u.operand;
- X86Assembler::JmpSrc notImm = iter->from;
- m_jit.link((++iter)->from, m_jit.label());
- m_jit.addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
- m_jit.link(notImm, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_pre_dec);
- emitPutResult(srcDst);
- i += 2;
- break;
- }
- case op_jnless: {
- unsigned target = instruction[i + 3].u.operand;
- JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
- if (src2imm) {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::edx, 0);
- emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_jless);
- m_jit.testl_rr(X86::eax, X86::eax);
- m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 3 + target]);
- } else {
- m_jit.link(iter->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_jless);
- m_jit.testl_rr(X86::eax, X86::eax);
- m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 3 + target]);
- }
- i += 4;
- break;
- }
- case op_not: {
- m_jit.link(iter->from, m_jit.label());
- m_jit.xorl_i8r(JSImmediate::FullTagTypeBool, X86::eax);
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_not);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_jfalse: {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_jtrue);
- m_jit.testl_rr(X86::eax, X86::eax);
- unsigned target = instruction[i + 2].u.operand;
- m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 2 + target]); // inverted!
- i += 3;
- break;
- }
- case op_post_inc: {
- unsigned srcDst = instruction[i + 2].u.operand;
- m_jit.link(iter->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_post_inc);
- emitPutResult(instruction[i + 1].u.operand);
- emitPutResult(srcDst, X86::edx);
- i += 3;
- break;
- }
- case op_bitnot: {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_bitnot);
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
- case op_bitand: {
- unsigned src1 = instruction[i + 2].u.operand;
- unsigned src2 = instruction[i + 3].u.operand;
- unsigned dst = instruction[i + 1].u.operand;
- if (getConstantImmediateNumericArg(src1)) {
- m_jit.link(iter->from, m_jit.label());
- emitGetPutArg(src1, 0, X86::ecx);
- emitPutArg(X86::eax, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_bitand);
- emitPutResult(dst);
- } else if (getConstantImmediateNumericArg(src2)) {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitGetPutArg(src2, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_bitand);
- emitPutResult(dst);
- } else {
- m_jit.link(iter->from, m_jit.label());
- emitGetPutArg(src1, 0, X86::ecx);
- emitPutArg(X86::edx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_bitand);
- emitPutResult(dst);
- }
- i += 5;
- break;
- }
- case op_jtrue: {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_jtrue);
- m_jit.testl_rr(X86::eax, X86::eax);
- unsigned target = instruction[i + 2].u.operand;
- m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 2 + target]);
- i += 3;
- break;
- }
- case op_post_dec: {
- unsigned srcDst = instruction[i + 2].u.operand;
- m_jit.link(iter->from, m_jit.label());
- m_jit.link((++iter)->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_post_dec);
- emitPutResult(instruction[i + 1].u.operand);
- emitPutResult(srcDst, X86::edx);
- i += 3;
- break;
- }
- case op_bitxor: {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_bitxor);
- emitPutResult(instruction[i + 1].u.operand);
- i += 5;
- break;
- }
- case op_bitor: {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_bitor);
- emitPutResult(instruction[i + 1].u.operand);
- i += 5;
- break;
- }
- case op_eq: {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_eq);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_neq: {
- m_jit.link(iter->from, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::edx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_neq);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- CTI_COMPILE_BINARY_OP_SLOW_CASE(op_stricteq);
- CTI_COMPILE_BINARY_OP_SLOW_CASE(op_nstricteq);
- case op_instanceof: {
- m_jit.link(iter->from, m_jit.label());
- emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
- emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
- emitGetPutArg(instruction[i + 4].u.operand, 8, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_instanceof);
- emitPutResult(instruction[i + 1].u.operand);
- i += 5;
- break;
- }
- case op_mod: {
- X86Assembler::JmpSrc notImm1 = iter->from;
- X86Assembler::JmpSrc notImm2 = (++iter)->from;
- m_jit.link((++iter)->from, m_jit.label());
- emitFastArithReTagImmediate(X86::eax);
- emitFastArithReTagImmediate(X86::ecx);
- m_jit.link(notImm1, m_jit.label());
- m_jit.link(notImm2, m_jit.label());
- emitPutArg(X86::eax, 0);
- emitPutArg(X86::ecx, 4);
- emitCTICall(instruction + i, i, Machine::cti_op_mod);
- emitPutResult(instruction[i + 1].u.operand);
- i += 4;
- break;
- }
- case op_mul: {
- int dst = instruction[i + 1].u.operand;
- int src1 = instruction[i + 2].u.operand;
- int src2 = instruction[i + 3].u.operand;
- JSValue* src1Value = getConstantImmediateNumericArg(src1);
- JSValue* src2Value = getConstantImmediateNumericArg(src2);
- int32_t value;
- if (src1Value && ((value = JSImmediate::intValue(src1Value)) > 0)) {
- m_jit.link(iter->from, m_jit.label());
- // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
- emitGetPutArg(src1, 0, X86::ecx);
- emitGetPutArg(src2, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_mul);
- emitPutResult(dst);
- } else if (src2Value && ((value = JSImmediate::intValue(src2Value)) > 0)) {
- m_jit.link(iter->from, m_jit.label());
- // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
- emitGetPutArg(src1, 0, X86::ecx);
- emitGetPutArg(src2, 4, X86::ecx);
- emitCTICall(instruction + i, i, Machine::cti_op_mul);
- emitPutResult(dst);
- } else
- compileBinaryArithOpSlowCase(instruction + i, op_mul, iter, dst, src1, src2, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
- i += 5;
- break;
- }
-
- case op_call:
- case op_call_eval:
- case op_construct: {
- int dst = instruction[i + 1].u.operand;
- int callee = instruction[i + 2].u.operand;
- int argCount = instruction[i + 5].u.operand;
-
- m_jit.link(iter->from, m_jit.label());
-
- // The arguments have been set up on the hot path for op_call_eval
- if (opcodeID != op_call_eval)
- compileOpCallSetupArgs(instruction + i, (opcodeID == op_construct), false);
-
- // Fast check for JS function.
- m_jit.testl_i32r(JSImmediate::TagMask, X86::ecx);
- X86Assembler::JmpSrc callLinkFailNotObject = m_jit.emitUnlinkedJne();
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsFunctionVptr), X86::ecx);
- X86Assembler::JmpSrc callLinkFailNotJSFunction = m_jit.emitUnlinkedJne();
-
- // This handles JSFunctions
- emitCTICall(instruction + i, i, (opcodeID == op_construct) ? Machine::cti_op_construct_JSConstruct : Machine::cti_op_call_JSFunction);
- // initialize the new call frame (pointed to by edx, after the last call), then set edi to point to it.
- compileOpCallInitializeCallFrame(callee, argCount);
- m_jit.movl_rr(X86::edx, X86::edi);
-
- // Try to link & repatch this call.
- CallLinkInfo* info = &(m_codeBlock->callLinkInfos[callLinkInfoIndex]);
- emitPutArgConstant(reinterpret_cast<unsigned>(info), 4);
- m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation =
- emitCTICall(instruction + i, i, Machine::cti_vm_lazyLinkCall);
- emitNakedCall(i, X86::eax);
- X86Assembler::JmpSrc storeResultForFirstRun = m_jit.emitUnlinkedJmp();
-
- // This is the address for the cold path *after* the first run (which tries to link the call).
- m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = m_jit.label();
-
- // The arguments have been set up on the hot path for op_call_eval
- if (opcodeID != op_call_eval)
- compileOpCallSetupArgs(instruction + i, (opcodeID == op_construct), false);
-
- // Check for JSFunctions.
- m_jit.testl_i32r(JSImmediate::TagMask, X86::ecx);
- X86Assembler::JmpSrc isNotObject = m_jit.emitUnlinkedJne();
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsFunctionVptr), X86::ecx);
- X86Assembler::JmpSrc isJSFunction = m_jit.emitUnlinkedJe();
-
- // This handles host functions
- X86Assembler::JmpDst notJSFunctionlabel = m_jit.label();
- m_jit.link(isNotObject, notJSFunctionlabel);
- m_jit.link(callLinkFailNotObject, notJSFunctionlabel);
- m_jit.link(callLinkFailNotJSFunction, notJSFunctionlabel);
- emitCTICall(instruction + i, i, ((opcodeID == op_construct) ? Machine::cti_op_construct_NotJSConstruct : Machine::cti_op_call_NotJSFunction));
- X86Assembler::JmpSrc wasNotJSFunction = m_jit.emitUnlinkedJmp();
-
- // Next, handle JSFunctions...
- m_jit.link(isJSFunction, m_jit.label());
- emitCTICall(instruction + i, i, (opcodeID == op_construct) ? Machine::cti_op_construct_JSConstruct : Machine::cti_op_call_JSFunction);
- // initialize the new call frame (pointed to by edx, after the last call).
- compileOpCallInitializeCallFrame(callee, argCount);
- m_jit.movl_rr(X86::edx, X86::edi);
-
- // load ctiCode from the new codeBlock.
- m_jit.movl_mr(OBJECT_OFFSET(CodeBlock, ctiCode), X86::eax, X86::eax);
-
- // Move the new callframe into edi.
- m_jit.movl_rr(X86::edx, X86::edi);
-
- // Check the ctiCode has been generated (if not compile it now), and make the call.
- m_jit.testl_rr(X86::eax, X86::eax);
- X86Assembler::JmpSrc hasCode = m_jit.emitUnlinkedJne();
- emitCTICall(instruction + i, i, Machine::cti_vm_compile);
- m_jit.link(hasCode, m_jit.label());
-
- emitNakedCall(i, X86::eax);
-
- // Put the return value in dst. In the interpreter, op_ret does this.
- X86Assembler::JmpDst storeResult = m_jit.label();
- m_jit.link(wasNotJSFunction, storeResult);
- m_jit.link(storeResultForFirstRun, storeResult);
- emitPutResult(dst);
-
-#if ENABLE(CODEBLOCK_SAMPLING)
- m_jit.movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_machine->sampler()->codeBlockSlot());
-#endif
- ++callLinkInfoIndex;
-
- i += 7;
- break;
- }
- case op_to_jsnumber: {
- m_jit.link(iter->from, m_jit.label());
- m_jit.link(iter->from, m_jit.label());
-
- emitPutArg(X86::eax, 0);
- emitCTICall(instruction + i, i, Machine::cti_op_to_jsnumber);
-
- emitPutResult(instruction[i + 1].u.operand);
- i += 3;
- break;
- }
-
- default:
- ASSERT_NOT_REACHED();
- break;
- }
-
- m_jit.link(m_jit.emitUnlinkedJmp(), m_labels[i]);
- }
-
- ASSERT(propertyAccessInstructionIndex == m_codeBlock->propertyAccessInstructions.size());
- ASSERT(callLinkInfoIndex == m_codeBlock->callLinkInfos.size());
-}
-
-void CTI::privateCompile()
-{
-#if ENABLE(CODEBLOCK_SAMPLING)
- m_jit.movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_machine->sampler()->codeBlockSlot());
-#endif
-#if ENABLE(OPCODE_SAMPLING)
- m_jit.movl_i32m(m_machine->sampler()->encodeSample(m_codeBlock->instructions.begin()), m_machine->sampler()->sampleSlot());
-#endif
-
- // Could use a popl_m, but would need to offset the following instruction if so.
- m_jit.popl_r(X86::ecx);
- emitPutToCallFrameHeader(X86::ecx, RegisterFile::ReturnPC);
-
- X86Assembler::JmpSrc slowRegisterFileCheck;
- X86Assembler::JmpDst afterRegisterFileCheck;
- if (m_codeBlock->codeType == FunctionCode) {
- // In the case of a fast linked call, we do not set this up in the caller.
- m_jit.movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), RegisterFile::CodeBlock * static_cast<int>(sizeof(Register)), X86::edi);
-
- emitGetCTIParam(CTI_ARGS_registerFile, X86::eax);
- m_jit.leal_mr(m_codeBlock->numCalleeRegisters * sizeof(Register), X86::edi, X86::edx);
- m_jit.cmpl_mr(OBJECT_OFFSET(RegisterFile, m_end), X86::eax, X86::edx);
- slowRegisterFileCheck = m_jit.emitUnlinkedJg();
- afterRegisterFileCheck = m_jit.label();
- }
-
- privateCompileMainPass();
- privateCompileLinkPass();
- privateCompileSlowCases();
-
- if (m_codeBlock->codeType == FunctionCode) {
- m_jit.link(slowRegisterFileCheck, m_jit.label());
- emitCTICall(m_codeBlock->instructions.begin(), 0, Machine::cti_register_file_check);
- X86Assembler::JmpSrc backToBody = m_jit.emitUnlinkedJmp();
- m_jit.link(backToBody, afterRegisterFileCheck);
- }
-
- ASSERT(m_jmpTable.isEmpty());
-
- void* code = m_jit.copy();
- ASSERT(code);
-
- // Translate vPC offsets into addresses in JIT generated code, for switch tables.
- for (unsigned i = 0; i < m_switches.size(); ++i) {
- SwitchRecord record = m_switches[i];
- unsigned opcodeIndex = record.m_opcodeIndex;
-
- if (record.m_type != SwitchRecord::String) {
- ASSERT(record.m_type == SwitchRecord::Immediate || record.m_type == SwitchRecord::Character);
- ASSERT(record.m_jumpTable.m_simpleJumpTable->branchOffsets.size() == record.m_jumpTable.m_simpleJumpTable->ctiOffsets.size());
-
- record.m_jumpTable.m_simpleJumpTable->ctiDefault = m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + record.m_defaultOffset]);
-
- for (unsigned j = 0; j < record.m_jumpTable.m_simpleJumpTable->branchOffsets.size(); ++j) {
- unsigned offset = record.m_jumpTable.m_simpleJumpTable->branchOffsets[j];
- record.m_jumpTable.m_simpleJumpTable->ctiOffsets[j] = offset ? m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + offset]) : record.m_jumpTable.m_simpleJumpTable->ctiDefault;
- }
- } else {
- ASSERT(record.m_type == SwitchRecord::String);
-
- record.m_jumpTable.m_stringJumpTable->ctiDefault = m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + record.m_defaultOffset]);
-
- StringJumpTable::StringOffsetTable::iterator end = record.m_jumpTable.m_stringJumpTable->offsetTable.end();
- for (StringJumpTable::StringOffsetTable::iterator it = record.m_jumpTable.m_stringJumpTable->offsetTable.begin(); it != end; ++it) {
- unsigned offset = it->second.branchOffset;
- it->second.ctiOffset = offset ? m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + offset]) : record.m_jumpTable.m_stringJumpTable->ctiDefault;
- }
- }
- }
-
- for (Vector<HandlerInfo>::iterator iter = m_codeBlock->exceptionHandlers.begin(); iter != m_codeBlock->exceptionHandlers.end(); ++iter)
- iter->nativeCode = m_jit.getRelocatedAddress(code, m_labels[iter->target]);
-
- for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
- if (iter->to)
- X86Assembler::link(code, iter->from, iter->to);
- m_codeBlock->ctiReturnAddressVPCMap.add(m_jit.getRelocatedAddress(code, iter->from), iter->opcodeIndex);
- }
-
- // Link absolute addresses for jsr
- for (Vector<JSRInfo>::iterator iter = m_jsrSites.begin(); iter != m_jsrSites.end(); ++iter)
- X86Assembler::linkAbsoluteAddress(code, iter->addrPosition, iter->target);
-
- for (unsigned i = 0; i < m_codeBlock->propertyAccessInstructions.size(); ++i) {
- StructureStubInfo& info = m_codeBlock->propertyAccessInstructions[i];
- info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_propertyAccessCompilationInfo[i].callReturnLocation);
- info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_propertyAccessCompilationInfo[i].hotPathBegin);
- }
- for (unsigned i = 0; i < m_codeBlock->callLinkInfos.size(); ++i) {
- CallLinkInfo& info = m_codeBlock->callLinkInfos[i];
- info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].callReturnLocation);
- info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].hotPathBegin);
- info.hotPathOther = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].hotPathOther);
- info.coldPathOther = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].coldPathOther);
- }
-
- m_codeBlock->ctiCode = code;
-}
-
-void CTI::privateCompileGetByIdSelf(StructureID* structureID, size_t cachedOffset, void* returnAddress)
-{
- // Check eax is an object of the right StructureID.
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
- m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
-
- // Checks out okay! - getDirectOffset
- m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
- m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::eax, X86::eax);
- m_jit.ret();
-
- void* code = m_jit.copy();
- ASSERT(code);
-
- X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
- X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
-
- m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
-
- ctiRepatchCallByReturnAddress(returnAddress, code);
-}
-
-void CTI::privateCompileGetByIdProto(StructureID* structureID, StructureID* prototypeStructureID, size_t cachedOffset, void* returnAddress)
-{
-#if USE(CTI_REPATCH_PIC)
- StructureStubInfo& info = m_codeBlock->getStubInfo(returnAddress);
-
- // We don't want to repatch more than once - in future go to cti_op_put_by_id_generic.
- ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
-
- // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a StructureID that is
- // referencing the prototype object - let's speculatively load it's table nice and early!)
- JSObject* protoObject = asObject(structureID->prototypeForLookup(m_callFrame));
- PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
- m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
-
- // check eax is an object of the right StructureID.
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
- m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
-
- // Check the prototype object's StructureID had not changed.
- StructureID** protoStructureIDAddress = &(protoObject->m_structureID);
- m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(prototypeStructureID), static_cast<void*>(protoStructureIDAddress));
- X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJne();
-
- // Checks out okay! - getDirectOffset
- m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::ecx);
-
- X86Assembler::JmpSrc success = m_jit.emitUnlinkedJmp();
-
- void* code = m_jit.copy();
- ASSERT(code);
-
- // Use the repatch information to link the failure cases back to the original slow case routine.
- void* slowCaseBegin = reinterpret_cast<char*>(info.callReturnLocation) - repatchOffsetGetByIdSlowCaseCall;
- X86Assembler::link(code, failureCases1, slowCaseBegin);
- X86Assembler::link(code, failureCases2, slowCaseBegin);
- X86Assembler::link(code, failureCases3, slowCaseBegin);
-
- // On success return back to the hot patch code, at a point it will perform the store to dest for us.
- intptr_t successDest = (intptr_t)(info.hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset;
- X86Assembler::link(code, success, reinterpret_cast<void*>(successDest));
-
- // Track the stub we have created so that it will be deleted later.
- m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
-
- // Finally repatch the jump to sow case back in the hot path to jump here instead.
- // FIXME: should revert this repatching, on failure.
- intptr_t jmpLocation = reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdBranchToSlowCase;
- X86Assembler::repatchBranchOffset(jmpLocation, code);
-#else
- // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a StructureID that is
- // referencing the prototype object - let's speculatively load it's table nice and early!)
- JSObject* protoObject = asObject(structureID->prototypeForLookup(m_callFrame));
- PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
- m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
-
- // check eax is an object of the right StructureID.
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
- m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
-
- // Check the prototype object's StructureID had not changed.
- StructureID** protoStructureIDAddress = &(protoObject->m_structureID);
- m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(prototypeStructureID), static_cast<void*>(protoStructureIDAddress));
- X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJne();
-
- // Checks out okay! - getDirectOffset
- m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::eax);
-
- m_jit.ret();
-
- void* code = m_jit.copy();
- ASSERT(code);
-
- X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
- X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
- X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
-
- m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
-
- ctiRepatchCallByReturnAddress(returnAddress, code);
-#endif
-}
-
-void CTI::privateCompileGetByIdChain(StructureID* structureID, StructureIDChain* chain, size_t count, size_t cachedOffset, void* returnAddress)
-{
- ASSERT(count);
-
- Vector<X86Assembler::JmpSrc> bucketsOfFail;
-
- // Check eax is an object of the right StructureID.
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- bucketsOfFail.append(m_jit.emitUnlinkedJne());
- m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- bucketsOfFail.append(m_jit.emitUnlinkedJne());
-
- StructureID* currStructureID = structureID;
- RefPtr<StructureID>* chainEntries = chain->head();
- JSObject* protoObject = 0;
- for (unsigned i = 0; i<count; ++i) {
- protoObject = asObject(currStructureID->prototypeForLookup(m_callFrame));
- currStructureID = chainEntries[i].get();
-
- // Check the prototype object's StructureID had not changed.
- StructureID** protoStructureIDAddress = &(protoObject->m_structureID);
- m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(currStructureID), static_cast<void*>(protoStructureIDAddress));
- bucketsOfFail.append(m_jit.emitUnlinkedJne());
- }
- ASSERT(protoObject);
-
- PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
- m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
- m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::eax);
- m_jit.ret();
-
- bucketsOfFail.append(m_jit.emitUnlinkedJmp());
-
- void* code = m_jit.copy();
- ASSERT(code);
-
- for (unsigned i = 0; i < bucketsOfFail.size(); ++i)
- X86Assembler::link(code, bucketsOfFail[i], reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
-
- m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
-
- ctiRepatchCallByReturnAddress(returnAddress, code);
-}
-
-void CTI::privateCompilePutByIdReplace(StructureID* structureID, size_t cachedOffset, void* returnAddress)
-{
- // check eax is an object of the right StructureID.
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
- m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
-
- // checks out okay! - putDirectOffset
- m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
- m_jit.movl_rm(X86::edx, cachedOffset * sizeof(JSValue*), X86::eax);
- m_jit.ret();
-
- void* code = m_jit.copy();
- ASSERT(code);
-
- X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail));
- X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail));
-
- m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
-
- ctiRepatchCallByReturnAddress(returnAddress, code);
-}
-
-extern "C" {
-
- static JSObject* resizePropertyStorage(JSObject* baseObject, size_t oldSize, size_t newSize)
- {
- baseObject->allocatePropertyStorageInline(oldSize, newSize);
- return baseObject;
- }
-
-}
-
-static inline bool transitionWillNeedStorageRealloc(StructureID* oldStructureID, StructureID* newStructureID)
-{
- return oldStructureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity();
-}
-
-void CTI::privateCompilePutByIdTransition(StructureID* oldStructureID, StructureID* newStructureID, size_t cachedOffset, StructureIDChain* sIDC, void* returnAddress)
-{
- Vector<X86Assembler::JmpSrc, 16> failureCases;
- // check eax is an object of the right StructureID.
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- failureCases.append(m_jit.emitUnlinkedJne());
- m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(oldStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
- failureCases.append(m_jit.emitUnlinkedJne());
- Vector<X86Assembler::JmpSrc> successCases;
-
- // ecx = baseObject
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
- // proto(ecx) = baseObject->structureID()->prototype()
- m_jit.cmpl_i32m(ObjectType, OBJECT_OFFSET(StructureID, m_typeInfo) + OBJECT_OFFSET(TypeInfo, m_type), X86::ecx);
- failureCases.append(m_jit.emitUnlinkedJne());
- m_jit.movl_mr(OBJECT_OFFSET(StructureID, m_prototype), X86::ecx, X86::ecx);
-
- // ecx = baseObject->m_structureID
- for (RefPtr<StructureID>* it = sIDC->head(); *it; ++it) {
- // null check the prototype
- m_jit.cmpl_i32r(asInteger(jsNull()), X86::ecx);
- successCases.append(m_jit.emitUnlinkedJe());
-
- // Check the structure id
- m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(it->get()), OBJECT_OFFSET(JSCell, m_structureID), X86::ecx);
- failureCases.append(m_jit.emitUnlinkedJne());
-
- m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::ecx, X86::ecx);
- m_jit.cmpl_i32m(ObjectType, OBJECT_OFFSET(StructureID, m_typeInfo) + OBJECT_OFFSET(TypeInfo, m_type), X86::ecx);
- failureCases.append(m_jit.emitUnlinkedJne());
- m_jit.movl_mr(OBJECT_OFFSET(StructureID, m_prototype), X86::ecx, X86::ecx);
- }
-
- failureCases.append(m_jit.emitUnlinkedJne());
- for (unsigned i = 0; i < successCases.size(); ++i)
- m_jit.link(successCases[i], m_jit.label());
-
- X86Assembler::JmpSrc callTarget;
-
- // emit a call only if storage realloc is needed
- if (transitionWillNeedStorageRealloc(oldStructureID, newStructureID)) {
- m_jit.pushl_r(X86::edx);
- m_jit.pushl_i32(newStructureID->propertyStorageCapacity());
- m_jit.pushl_i32(oldStructureID->propertyStorageCapacity());
- m_jit.pushl_r(X86::eax);
- callTarget = m_jit.emitCall();
- m_jit.addl_i32r(3 * sizeof(void*), X86::esp);
- m_jit.popl_r(X86::edx);
- }
-
- // Assumes m_refCount can be decremented easily, refcount decrement is safe as
- // codeblock should ensure oldStructureID->m_refCount > 0
- m_jit.subl_i8m(1, reinterpret_cast<void*>(oldStructureID));
- m_jit.addl_i8m(1, reinterpret_cast<void*>(newStructureID));
- m_jit.movl_i32m(reinterpret_cast<uint32_t>(newStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
-
- // write the value
- m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
- m_jit.movl_rm(X86::edx, cachedOffset * sizeof(JSValue*), X86::eax);
-
- m_jit.ret();
-
- X86Assembler::JmpSrc failureJump;
- if (failureCases.size()) {
- for (unsigned i = 0; i < failureCases.size(); ++i)
- m_jit.link(failureCases[i], m_jit.label());
- m_jit.emitRestoreArgumentReferenceForTrampoline();
- failureJump = m_jit.emitUnlinkedJmp();
- }
-
- void* code = m_jit.copy();
- ASSERT(code);
-
- if (failureCases.size())
- X86Assembler::link(code, failureJump, reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail));
-
- if (transitionWillNeedStorageRealloc(oldStructureID, newStructureID))
- X86Assembler::link(code, callTarget, reinterpret_cast<void*>(resizePropertyStorage));
-
- m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
-
- ctiRepatchCallByReturnAddress(returnAddress, code);
-}
-
-void CTI::unlinkCall(CallLinkInfo* callLinkInfo)
-{
- // When the JSFunction is deleted the pointer embedded in the instruction stream will no longer be valid
- // (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive
- // match). Reset the check so it no longer matches.
- reinterpret_cast<void**>(callLinkInfo->hotPathBegin)[-1] = asPointer(JSImmediate::impossibleValue());
-}
-
-void CTI::linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount)
-{
- // Currently we only link calls with the exact number of arguments.
- if (callerArgCount == calleeCodeBlock->numParameters) {
- ASSERT(!callLinkInfo->isLinked());
-
- calleeCodeBlock->addCaller(callLinkInfo);
-
- reinterpret_cast<void**>(callLinkInfo->hotPathBegin)[-1] = callee;
- ctiRepatchCallByReturnAddress(callLinkInfo->hotPathOther, ctiCode);
- }
-
- // repatch the instruction that jumps out to the cold path, so that we only try to link once.
- void* repatchCheck = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(callLinkInfo->hotPathBegin) + repatchOffsetOpCallCall);
- ctiRepatchCallByReturnAddress(repatchCheck, callLinkInfo->coldPathOther);
-}
-
-void* CTI::privateCompileArrayLengthTrampoline()
-{
- // Check eax is an array
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
- X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
-
- // Checks out okay! - get the length from the storage
- m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::eax);
- m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_length), X86::eax, X86::eax);
-
- m_jit.addl_rr(X86::eax, X86::eax);
- X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJo();
- m_jit.addl_i8r(1, X86::eax);
-
- m_jit.ret();
-
- void* code = m_jit.copy();
- ASSERT(code);
-
- X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
- X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
- X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
-
- return code;
-}
-
-void* CTI::privateCompileStringLengthTrampoline()
-{
- // Check eax is a string
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsStringVptr), X86::eax);
- X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
-
- // Checks out okay! - get the length from the Ustring.
- m_jit.movl_mr(OBJECT_OFFSET(JSString, m_value) + OBJECT_OFFSET(UString, m_rep), X86::eax, X86::eax);
- m_jit.movl_mr(OBJECT_OFFSET(UString::Rep, len), X86::eax, X86::eax);
-
- m_jit.addl_rr(X86::eax, X86::eax);
- X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJo();
- m_jit.addl_i8r(1, X86::eax);
-
- m_jit.ret();
-
- void* code = m_jit.copy();
- ASSERT(code);
-
- X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
- X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
- X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
-
- return code;
-}
-
-void CTI::patchGetByIdSelf(CodeBlock* codeBlock, StructureID* structureID, size_t cachedOffset, void* returnAddress)
-{
- StructureStubInfo& info = codeBlock->getStubInfo(returnAddress);
-
- // We don't want to repatch more than once - in future go to cti_op_get_by_id_generic.
- // Should probably go to Machine::cti_op_get_by_id_fail, but that doesn't do anything interesting right now.
- ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Machine::cti_op_get_by_id_generic));
-
- // Repatch the offset into the propoerty map to load from, then repatch the StructureID to look for.
- X86Assembler::repatchDisplacement(reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset, cachedOffset * sizeof(JSValue*));
- X86Assembler::repatchImmediate(reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdStructureID, reinterpret_cast<uint32_t>(structureID));
-}
-
-void CTI::patchPutByIdReplace(CodeBlock* codeBlock, StructureID* structureID, size_t cachedOffset, void* returnAddress)
-{
- StructureStubInfo& info = codeBlock->getStubInfo(returnAddress);
-
- // We don't want to repatch more than once - in future go to cti_op_put_by_id_generic.
- // Should probably go to Machine::cti_op_put_by_id_fail, but that doesn't do anything interesting right now.
- ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Machine::cti_op_put_by_id_generic));
-
- // Repatch the offset into the propoerty map to load from, then repatch the StructureID to look for.
- X86Assembler::repatchDisplacement(reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetPutByIdPropertyMapOffset, cachedOffset * sizeof(JSValue*));
- X86Assembler::repatchImmediate(reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetPutByIdStructureID, reinterpret_cast<uint32_t>(structureID));
-}
-
-void CTI::privateCompilePatchGetArrayLength(void* returnAddress)
-{
- StructureStubInfo& info = m_codeBlock->getStubInfo(returnAddress);
-
- // We don't want to repatch more than once - in future go to cti_op_put_by_id_generic.
- ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
-
- // Check eax is an array
- m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
- X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
- m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
- X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
-
- // Checks out okay! - get the length from the storage
- m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::ecx);
- m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_length), X86::ecx, X86::ecx);
-
- m_jit.addl_rr(X86::ecx, X86::ecx);
- X86Assembler::JmpSrc failureClobberedECX = m_jit.emitUnlinkedJo();
- m_jit.addl_i8r(1, X86::ecx);
-
- X86Assembler::JmpSrc success = m_jit.emitUnlinkedJmp();
-
- m_jit.link(failureClobberedECX, m_jit.label());
- m_jit.emitRestoreArgumentReference();
- X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJmp();
-
- void* code = m_jit.copy();
- ASSERT(code);
-
- // Use the repatch information to link the failure cases back to the original slow case routine.
- void* slowCaseBegin = reinterpret_cast<char*>(info.callReturnLocation) - repatchOffsetGetByIdSlowCaseCall;
- X86Assembler::link(code, failureCases1, slowCaseBegin);
- X86Assembler::link(code, failureCases2, slowCaseBegin);
- X86Assembler::link(code, failureCases3, slowCaseBegin);
-
- // On success return back to the hot patch code, at a point it will perform the store to dest for us.
- intptr_t successDest = (intptr_t)(info.hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset;
- X86Assembler::link(code, success, reinterpret_cast<void*>(successDest));
-
- // Track the stub we have created so that it will be deleted later.
- m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
-
- // Finally repatch the jump to sow case back in the hot path to jump here instead.
- // FIXME: should revert this repatching, on failure.
- intptr_t jmpLocation = reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdBranchToSlowCase;
- X86Assembler::repatchBranchOffset(jmpLocation, code);
-}
-
-void CTI::emitGetVariableObjectRegister(X86Assembler::RegisterID variableObject, int index, X86Assembler::RegisterID dst)
-{
- m_jit.movl_mr(JSVariableObject::offsetOf_d(), variableObject, dst);
- m_jit.movl_mr(JSVariableObject::offsetOf_Data_registers(), dst, dst);
- m_jit.movl_mr(index * sizeof(Register), dst, dst);
-}
-
-void CTI::emitPutVariableObjectRegister(X86Assembler::RegisterID src, X86Assembler::RegisterID variableObject, int index)
-{
- m_jit.movl_mr(JSVariableObject::offsetOf_d(), variableObject, variableObject);
- m_jit.movl_mr(JSVariableObject::offsetOf_Data_registers(), variableObject, variableObject);
- m_jit.movl_rm(src, index * sizeof(Register), variableObject);
-}
-
-#if ENABLE(WREC)
-
-void* CTI::compileRegExp(Machine* machine, const UString& pattern, unsigned* numSubpatterns_ptr, const char** error_ptr, bool ignoreCase, bool multiline)
-{
- // TODO: better error messages
- if (pattern.size() > MaxPatternSize) {
- *error_ptr = "regular expression too large";
- return 0;
- }
-
- X86Assembler jit(machine->jitCodeBuffer());
- WRECParser parser(pattern, ignoreCase, multiline, jit);
-
- jit.emitConvertToFastCall();
- // (0) Setup:
- // Preserve regs & initialize outputRegister.
- jit.pushl_r(WRECGenerator::outputRegister);
- jit.pushl_r(WRECGenerator::currentValueRegister);
- // push pos onto the stack, both to preserve and as a parameter available to parseDisjunction
- jit.pushl_r(WRECGenerator::currentPositionRegister);
- // load output pointer
- jit.movl_mr(16
-#if COMPILER(MSVC)
- + 3 * sizeof(void*)
-#endif
- , X86::esp, WRECGenerator::outputRegister);
-
- // restart point on match fail.
- WRECGenerator::JmpDst nextLabel = jit.label();
-
- // (1) Parse Disjunction:
-
- // Parsing the disjunction should fully consume the pattern.
- JmpSrcVector failures;
- parser.parseDisjunction(failures);
- if (parser.isEndOfPattern()) {
- parser.m_err = WRECParser::Error_malformedPattern;
- }
- if (parser.m_err) {
- // TODO: better error messages
- *error_ptr = "TODO: better error messages";
- return 0;
- }
-
- // (2) Success:
- // Set return value & pop registers from the stack.
-
- jit.testl_rr(WRECGenerator::outputRegister, WRECGenerator::outputRegister);
- WRECGenerator::JmpSrc noOutput = jit.emitUnlinkedJe();
-
- jit.movl_rm(WRECGenerator::currentPositionRegister, 4, WRECGenerator::outputRegister);
- jit.popl_r(X86::eax);
- jit.movl_rm(X86::eax, WRECGenerator::outputRegister);
- jit.popl_r(WRECGenerator::currentValueRegister);
- jit.popl_r(WRECGenerator::outputRegister);
- jit.ret();
-
- jit.link(noOutput, jit.label());
-
- jit.popl_r(X86::eax);
- jit.movl_rm(X86::eax, WRECGenerator::outputRegister);
- jit.popl_r(WRECGenerator::currentValueRegister);
- jit.popl_r(WRECGenerator::outputRegister);
- jit.ret();
-
- // (3) Failure:
- // All fails link to here. Progress the start point & if it is within scope, loop.
- // Otherwise, return fail value.
- WRECGenerator::JmpDst here = jit.label();
- for (unsigned i = 0; i < failures.size(); ++i)
- jit.link(failures[i], here);
- failures.clear();
-
- jit.movl_mr(X86::esp, WRECGenerator::currentPositionRegister);
- jit.addl_i8r(1, WRECGenerator::currentPositionRegister);
- jit.movl_rm(WRECGenerator::currentPositionRegister, X86::esp);
- jit.cmpl_rr(WRECGenerator::lengthRegister, WRECGenerator::currentPositionRegister);
- jit.link(jit.emitUnlinkedJle(), nextLabel);
-
- jit.addl_i8r(4, X86::esp);
-
- jit.movl_i32r(-1, X86::eax);
- jit.popl_r(WRECGenerator::currentValueRegister);
- jit.popl_r(WRECGenerator::outputRegister);
- jit.ret();
-
- *numSubpatterns_ptr = parser.m_numSubpatterns;
-
- void* code = jit.copy();
- ASSERT(code);
- return code;
-}
-
-#endif // ENABLE(WREC)
-
-} // namespace JSC
-
-#endif // ENABLE(CTI)
diff --git a/JavaScriptCore/VM/CTI.h b/JavaScriptCore/VM/CTI.h
deleted file mode 100644
index 04bb6ca..0000000
--- a/JavaScriptCore/VM/CTI.h
+++ /dev/null
@@ -1,475 +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 CTI_h
-#define CTI_h
-
-#if ENABLE(CTI)
-
-#define WTF_USE_CTI_REPATCH_PIC 1
-
-#include "Machine.h"
-#include "Opcode.h"
-#include "RegisterFile.h"
-#include <masm/X86Assembler.h>
-#include <profiler/Profiler.h>
-#include <wtf/AlwaysInline.h>
-#include <wtf/Vector.h>
-
-#define CTI_ARGS_code 0x0C
-#define CTI_ARGS_registerFile 0x0D
-#define CTI_ARGS_callFrame 0x0E
-#define CTI_ARGS_exception 0x0F
-#define CTI_ARGS_profilerReference 0x10
-#define CTI_ARGS_globalData 0x11
-
-#define ARG_callFrame static_cast<CallFrame*>(ARGS[CTI_ARGS_callFrame])
-#define ARG_registerFile static_cast<RegisterFile*>(ARGS[CTI_ARGS_registerFile])
-#define ARG_exception static_cast<JSValue**>(ARGS[CTI_ARGS_exception])
-#define ARG_profilerReference static_cast<Profiler**>(ARGS[CTI_ARGS_profilerReference])
-#define ARG_globalData static_cast<JSGlobalData*>(ARGS[CTI_ARGS_globalData])
-
-#define ARG_setCallFrame(newCallFrame) (ARGS[CTI_ARGS_callFrame] = (newCallFrame))
-
-#define ARG_src1 static_cast<JSValue*>(ARGS[1])
-#define ARG_src2 static_cast<JSValue*>(ARGS[2])
-#define ARG_src3 static_cast<JSValue*>(ARGS[3])
-#define ARG_src4 static_cast<JSValue*>(ARGS[4])
-#define ARG_src5 static_cast<JSValue*>(ARGS[5])
-#define ARG_id1 static_cast<Identifier*>(ARGS[1])
-#define ARG_id2 static_cast<Identifier*>(ARGS[2])
-#define ARG_id3 static_cast<Identifier*>(ARGS[3])
-#define ARG_id4 static_cast<Identifier*>(ARGS[4])
-#define ARG_int1 reinterpret_cast<intptr_t>(ARGS[1])
-#define ARG_int2 reinterpret_cast<intptr_t>(ARGS[2])
-#define ARG_int3 reinterpret_cast<intptr_t>(ARGS[3])
-#define ARG_int4 reinterpret_cast<intptr_t>(ARGS[4])
-#define ARG_int5 reinterpret_cast<intptr_t>(ARGS[5])
-#define ARG_int6 reinterpret_cast<intptr_t>(ARGS[6])
-#define ARG_func1 static_cast<FuncDeclNode*>(ARGS[1])
-#define ARG_funcexp1 static_cast<FuncExprNode*>(ARGS[1])
-#define ARG_registers1 static_cast<Register*>(ARGS[1])
-#define ARG_regexp1 static_cast<RegExp*>(ARGS[1])
-#define ARG_pni1 static_cast<JSPropertyNameIterator*>(ARGS[1])
-#define ARG_instr1 static_cast<Instruction*>(ARGS[1])
-#define ARG_instr2 static_cast<Instruction*>(ARGS[2])
-#define ARG_instr3 static_cast<Instruction*>(ARGS[3])
-#define ARG_instr4 static_cast<Instruction*>(ARGS[4])
-#define ARG_instr5 static_cast<Instruction*>(ARGS[5])
-#define ARG_instr6 static_cast<Instruction*>(ARGS[6])
-#define ARG_linkInfo2 static_cast<CallLinkInfo*>(ARGS[2])
-
-#define CTI_RETURN_ADDRESS_SLOT (ARGS[-1])
-
-#if COMPILER(MSVC)
-#define FASTCALL __fastcall
-#elif COMPILER(GCC)
-#define FASTCALL __attribute__ ((fastcall))
-#else
-#error Need to support fastcall calling convention in this compiler
-#endif
-
-namespace JSC {
-
- class CodeBlock;
- class JSPropertyNameIterator;
- class Machine;
- class Register;
- class RegisterFile;
- class ScopeChainNode;
- class SimpleJumpTable;
- class StringJumpTable;
- class StructureIDChain;
-
- struct CallLinkInfo;
- struct Instruction;
- struct OperandTypes;
-
- typedef JSValue* (SFX_CALL *CTIHelper_j)(CTI_ARGS);
- typedef JSObject* (SFX_CALL *CTIHelper_o)(CTI_ARGS);
- typedef JSPropertyNameIterator* (SFX_CALL *CTIHelper_p)(CTI_ARGS);
- typedef void (SFX_CALL *CTIHelper_v)(CTI_ARGS);
- typedef void* (SFX_CALL *CTIHelper_s)(CTI_ARGS);
- typedef int (SFX_CALL *CTIHelper_b)(CTI_ARGS);
- typedef VoidPtrPair (SFX_CALL *CTIHelper_2)(CTI_ARGS);
-
- struct CallRecord {
- X86Assembler::JmpSrc from;
- void* to;
- unsigned opcodeIndex;
-
- CallRecord()
- {
- }
-
- CallRecord(X86Assembler::JmpSrc f, CTIHelper_j t, unsigned i)
- : from(f)
- , to(reinterpret_cast<void*>(t))
- , opcodeIndex(i)
- {
- }
-
- CallRecord(X86Assembler::JmpSrc f, CTIHelper_o t, unsigned i)
- : from(f)
- , to(reinterpret_cast<void*>(t))
- , opcodeIndex(i)
- {
- }
-
- CallRecord(X86Assembler::JmpSrc f, CTIHelper_p t, unsigned i)
- : from(f)
- , to(reinterpret_cast<void*>(t))
- , opcodeIndex(i)
- {
- }
-
- CallRecord(X86Assembler::JmpSrc f, CTIHelper_v t, unsigned i)
- : from(f)
- , to(reinterpret_cast<void*>(t))
- , opcodeIndex(i)
- {
- }
-
- CallRecord(X86Assembler::JmpSrc f, CTIHelper_s t, unsigned i)
- : from(f)
- , to(reinterpret_cast<void*>(t))
- , opcodeIndex(i)
- {
- }
-
- CallRecord(X86Assembler::JmpSrc f, CTIHelper_b t, unsigned i)
- : from(f)
- , to(reinterpret_cast<void*>(t))
- , opcodeIndex(i)
- {
- }
-
- CallRecord(X86Assembler::JmpSrc f, CTIHelper_2 t, unsigned i)
- : from(f)
- , to(reinterpret_cast<void*>(t))
- , opcodeIndex(i)
- {
- }
-
- CallRecord(X86Assembler::JmpSrc f, unsigned i)
- : from(f)
- , to(0)
- , opcodeIndex(i)
- {
- }
- };
-
- struct JmpTable {
- X86Assembler::JmpSrc from;
- unsigned to;
-
- JmpTable(X86Assembler::JmpSrc f, unsigned t)
- : from(f)
- , to(t)
- {
- }
- };
-
- struct SlowCaseEntry {
- X86Assembler::JmpSrc from;
- unsigned to;
- unsigned hint;
-
- SlowCaseEntry(X86Assembler::JmpSrc f, unsigned t, unsigned h = 0)
- : from(f)
- , to(t)
- , hint(h)
- {
- }
- };
-
- struct SwitchRecord {
- enum Type {
- Immediate,
- Character,
- String
- };
-
- Type m_type;
-
- union {
- SimpleJumpTable* m_simpleJumpTable;
- StringJumpTable* m_stringJumpTable;
- } m_jumpTable;
-
- unsigned m_opcodeIndex;
- unsigned m_defaultOffset;
-
- SwitchRecord(SimpleJumpTable* jumpTable, unsigned opcodeIndex, unsigned defaultOffset, Type type)
- : m_type(type)
- , m_opcodeIndex(opcodeIndex)
- , m_defaultOffset(defaultOffset)
- {
- m_jumpTable.m_simpleJumpTable = jumpTable;
- }
-
- SwitchRecord(StringJumpTable* jumpTable, unsigned opcodeIndex, unsigned defaultOffset)
- : m_type(String)
- , m_opcodeIndex(opcodeIndex)
- , m_defaultOffset(defaultOffset)
- {
- m_jumpTable.m_stringJumpTable = jumpTable;
- }
- };
-
- struct StructureStubCompilationInfo {
- X86Assembler::JmpSrc callReturnLocation;
- X86Assembler::JmpDst hotPathBegin;
- X86Assembler::JmpSrc hotPathOther;
- X86Assembler::JmpDst coldPathOther;
- };
-
- extern "C" {
- JSValue* ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue** exception, Profiler**, JSGlobalData*);
- void ctiVMThrowTrampoline();
- };
-
- void ctiSetReturnAddress(void** where, void* what);
- void ctiRepatchCallByReturnAddress(void* where, void* what);
-
- class CTI {
- static const int repatchGetByIdDefaultStructureID = -1;
- // Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler
- // will compress the displacement, and we may not be able to fit a repatched offset.
- static const int repatchGetByIdDefaultOffset = 256;
-
-#if USE(FAST_CALL_CTI_ARGUMENT)
- static const int ctiArgumentInitSize = 2;
-#elif USE(CTI_ARGUMENT)
- static const int ctiArgumentInitSize = 4;
-#else
- static const int ctiArgumentInitSize = 0;
-#endif
- // These architecture specific value are used to enable repatching - see comment on op_put_by_id.
- static const int repatchOffsetPutByIdStructureID = 19;
- static const int repatchOffsetPutByIdPropertyMapOffset = 34;
- // These architecture specific value are used to enable repatching - see comment on op_get_by_id.
- static const int repatchOffsetGetByIdStructureID = 19;
- static const int repatchOffsetGetByIdBranchToSlowCase = 25;
- static const int repatchOffsetGetByIdPropertyMapOffset = 34;
-#if ENABLE(OPCODE_SAMPLING)
- static const int repatchOffsetGetByIdSlowCaseCall = 27 + 4 + ctiArgumentInitSize;
-#else
- static const int repatchOffsetGetByIdSlowCaseCall = 17 + 4 + ctiArgumentInitSize;
-#endif
- static const int repatchOffsetOpCallCall = 6;
-
- public:
- static void compile(Machine* machine, CallFrame* callFrame, CodeBlock* codeBlock)
- {
- CTI cti(machine, callFrame, codeBlock);
- cti.privateCompile();
- }
-
-#if ENABLE(WREC)
- static void* compileRegExp(Machine*, const UString& pattern, unsigned* numSubpatterns_ptr, const char** error_ptr, bool ignoreCase = false, bool multiline = false);
-#endif
-
- static void compileGetByIdSelf(Machine* machine, CallFrame* callFrame, CodeBlock* codeBlock, StructureID* structureID, size_t cachedOffset, void* returnAddress)
- {
- CTI cti(machine, callFrame, codeBlock);
- cti.privateCompileGetByIdSelf(structureID, cachedOffset, returnAddress);
- }
-
- static void compileGetByIdProto(Machine* machine, CallFrame* callFrame, CodeBlock* codeBlock, StructureID* structureID, StructureID* prototypeStructureID, size_t cachedOffset, void* returnAddress)
- {
- CTI cti(machine, callFrame, codeBlock);
- cti.privateCompileGetByIdProto(structureID, prototypeStructureID, cachedOffset, returnAddress);
- }
-
- static void compileGetByIdChain(Machine* machine, CallFrame* callFrame, CodeBlock* codeBlock, StructureID* structureID, StructureIDChain* chain, size_t count, size_t cachedOffset, void* returnAddress)
- {
- CTI cti(machine, callFrame, codeBlock);
- cti.privateCompileGetByIdChain(structureID, chain, count, cachedOffset, returnAddress);
- }
-
- static void compilePutByIdReplace(Machine* machine, CallFrame* callFrame, CodeBlock* codeBlock, StructureID* structureID, size_t cachedOffset, void* returnAddress)
- {
- CTI cti(machine, callFrame, codeBlock);
- cti.privateCompilePutByIdReplace(structureID, cachedOffset, returnAddress);
- }
-
- static void compilePutByIdTransition(Machine* machine, CallFrame* callFrame, CodeBlock* codeBlock, StructureID* oldStructureID, StructureID* newStructureID, size_t cachedOffset, StructureIDChain* sIDC, void* returnAddress)
- {
- CTI cti(machine, callFrame, codeBlock);
- cti.privateCompilePutByIdTransition(oldStructureID, newStructureID, cachedOffset, sIDC, returnAddress);
- }
-
- static void* compileArrayLengthTrampoline(Machine* machine, CallFrame* callFrame, CodeBlock* codeBlock)
- {
- CTI cti(machine, callFrame, codeBlock);
- return cti.privateCompileArrayLengthTrampoline();
- }
-
- static void* compileStringLengthTrampoline(Machine* machine, CallFrame* callFrame, CodeBlock* codeBlock)
- {
- CTI cti(machine, callFrame, codeBlock);
- return cti.privateCompileStringLengthTrampoline();
- }
-
- static void patchGetByIdSelf(CodeBlock* codeBlock, StructureID* structureID, size_t cachedOffset, void* returnAddress);
- static void patchPutByIdReplace(CodeBlock* codeBlock, StructureID* structureID, size_t cachedOffset, void* returnAddress);
-
- static void compilePatchGetArrayLength(Machine* machine, CallFrame* callFrame, CodeBlock* codeBlock, void* returnAddress)
- {
- CTI cti(machine, callFrame, codeBlock);
- return cti.privateCompilePatchGetArrayLength(returnAddress);
- }
-
- static void linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount);
- static void unlinkCall(CallLinkInfo*);
-
- inline static JSValue* execute(void* code, RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData, JSValue** exception)
- {
- return ctiTrampoline(code, registerFile, callFrame, exception, Profiler::enabledProfilerReference(), globalData);
- }
-
- private:
- CTI(Machine*, CallFrame*, CodeBlock*);
-
- static uintptr_t asInteger(JSValue*);
-
- bool isConstant(int src);
- JSValue* getConstant(CallFrame*, int src);
-
- void privateCompileMainPass();
- void privateCompileLinkPass();
- void privateCompileSlowCases();
- void privateCompile();
- void privateCompileGetByIdSelf(StructureID*, size_t cachedOffset, void* returnAddress);
- void privateCompileGetByIdProto(StructureID*, StructureID* prototypeStructureID, size_t cachedOffset, void* returnAddress);
- void privateCompileGetByIdChain(StructureID*, StructureIDChain*, size_t count, size_t cachedOffset, void* returnAddress);
- void privateCompilePutByIdReplace(StructureID*, size_t cachedOffset, void* returnAddress);
- void privateCompilePutByIdTransition(StructureID*, StructureID*, size_t cachedOffset, StructureIDChain*, void* returnAddress);
-
- void* privateCompileArrayLengthTrampoline();
- void* privateCompileStringLengthTrampoline();
- void privateCompilePatchGetArrayLength(void* returnAddress);
-
- void compileOpCall(OpcodeID, Instruction* instruction, unsigned i, unsigned callLinkInfoIndex);
- void compileOpCallInitializeCallFrame(unsigned callee, unsigned argCount);
- void compileOpCallSetupArgs(Instruction* instruction, bool isConstruct, bool isEval);
- enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq };
- void compileOpStrictEq(Instruction* instruction, unsigned i, CompileOpStrictEqType type);
- void putDoubleResultToJSNumberCellOrJSImmediate(X86::XMMRegisterID xmmSource, X86::RegisterID jsNumberCell, unsigned dst, X86Assembler::JmpSrc* wroteJSNumberCell, X86::XMMRegisterID tempXmm, X86::RegisterID tempReg1, X86::RegisterID tempReg2);
- void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi, unsigned i);
- void compileBinaryArithOpSlowCase(Instruction*, OpcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi, unsigned i);
-
- void emitGetArg(int src, X86Assembler::RegisterID dst);
- void emitGetPutArg(unsigned src, unsigned offset, X86Assembler::RegisterID scratch);
- void emitPutArg(X86Assembler::RegisterID src, unsigned offset);
- void emitPutArgConstant(unsigned value, unsigned offset);
- void emitPutResult(unsigned dst, X86Assembler::RegisterID from = X86::eax);
-
- void emitInitRegister(unsigned dst);
-
- void emitPutCTIParam(void* value, unsigned name);
- void emitPutCTIParam(X86Assembler::RegisterID from, unsigned name);
- void emitGetCTIParam(unsigned name, X86Assembler::RegisterID to);
-
- void emitPutToCallFrameHeader(X86Assembler::RegisterID from, RegisterFile::CallFrameHeaderEntry entry);
- void emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, X86Assembler::RegisterID to);
-
- JSValue* getConstantImmediateNumericArg(unsigned src);
- unsigned getDeTaggedConstantImmediate(JSValue* imm);
-
- void emitJumpSlowCaseIfIsJSCell(X86Assembler::RegisterID reg, unsigned opcodeIndex);
- void emitJumpSlowCaseIfNotJSCell(X86Assembler::RegisterID reg, unsigned opcodeIndex);
-
- void emitJumpSlowCaseIfNotImmNum(X86Assembler::RegisterID, unsigned opcodeIndex);
- void emitJumpSlowCaseIfNotImmNums(X86Assembler::RegisterID, X86Assembler::RegisterID, unsigned opcodeIndex);
-
- void emitFastArithDeTagImmediate(X86Assembler::RegisterID);
- X86Assembler::JmpSrc emitFastArithDeTagImmediateJumpIfZero(X86Assembler::RegisterID);
- void emitFastArithReTagImmediate(X86Assembler::RegisterID);
- void emitFastArithPotentiallyReTagImmediate(X86Assembler::RegisterID);
- void emitFastArithImmToInt(X86Assembler::RegisterID);
- void emitFastArithIntToImmOrSlowCase(X86Assembler::RegisterID, unsigned opcodeIndex);
- void emitFastArithIntToImmNoCheck(X86Assembler::RegisterID);
- X86Assembler::JmpSrc emitArithIntToImmWithJump(X86Assembler::RegisterID reg);
-
- void emitTagAsBoolImmediate(X86Assembler::RegisterID reg);
-
- void emitAllocateNumber(JSGlobalData*, unsigned);
-
- X86Assembler::JmpSrc emitNakedCall(unsigned opcodeIndex, X86::RegisterID);
- X86Assembler::JmpSrc emitNakedCall(unsigned opcodeIndex, void(*function)());
- X86Assembler::JmpSrc emitNakedFastCall(unsigned opcodeIndex, void*);
- X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_j);
- X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_o);
- X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_p);
- X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_v);
- X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_s);
- X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_b);
- X86Assembler::JmpSrc emitCTICall(Instruction*, unsigned opcodeIndex, CTIHelper_2);
-
- void emitGetVariableObjectRegister(X86Assembler::RegisterID variableObject, int index, X86Assembler::RegisterID dst);
- void emitPutVariableObjectRegister(X86Assembler::RegisterID src, X86Assembler::RegisterID variableObject, int index);
-
- void emitSlowScriptCheck(Instruction*, unsigned opcodeIndex);
-#ifndef NDEBUG
- void printOpcodeOperandTypes(unsigned src1, unsigned src2);
-#endif
-
- X86Assembler m_jit;
- Machine* m_machine;
- CallFrame* m_callFrame;
- CodeBlock* m_codeBlock;
-
- Vector<CallRecord> m_calls;
- Vector<X86Assembler::JmpDst> m_labels;
- Vector<StructureStubCompilationInfo> m_propertyAccessCompilationInfo;
- Vector<StructureStubCompilationInfo> m_callStructureStubCompilationInfo;
- Vector<JmpTable> m_jmpTable;
-
- struct JSRInfo {
- X86Assembler::JmpDst addrPosition;
- X86Assembler::JmpDst target;
-
- JSRInfo(const X86Assembler::JmpDst& storeLocation, const X86Assembler::JmpDst& targetLocation)
- : addrPosition(storeLocation)
- , target(targetLocation)
- {
- }
- };
-
- Vector<JSRInfo> m_jsrSites;
- Vector<SlowCaseEntry> m_slowCases;
- Vector<SwitchRecord> m_switches;
-
- // This limit comes from the limit set in PCRE
- static const int MaxPatternSize = (1 << 16);
-
- };
-}
-
-#endif // ENABLE(CTI)
-
-#endif // CTI_h
diff --git a/JavaScriptCore/VM/CodeBlock.cpp b/JavaScriptCore/VM/CodeBlock.cpp
deleted file mode 100644
index 38ef598..0000000
--- a/JavaScriptCore/VM/CodeBlock.cpp
+++ /dev/null
@@ -1,1184 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "CodeBlock.h"
-
-#include "CTI.h"
-#include "JSValue.h"
-#include "Machine.h"
-#include "Debugger.h"
-#include <stdio.h>
-#include <wtf/StringExtras.h>
-
-namespace JSC {
-
-#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
-
-static UString escapeQuotes(const UString& str)
-{
- UString result = str;
- int pos = 0;
- while ((pos = result.find('\"', pos)) >= 0) {
- result = result.substr(0, pos) + "\"\\\"\"" + result.substr(pos + 1);
- pos += 4;
- }
- return result;
-}
-
-static UString valueToSourceString(ExecState* exec, JSValue* val)
-{
- if (val->isString()) {
- UString result("\"");
- result += escapeQuotes(val->toString(exec)) + "\"";
- return result;
- }
-
- return val->toString(exec);
-}
-
-static CString registerName(int r)
-{
- if (r == missingThisObjectMarker())
- return "<null>";
-
- return (UString("r") + UString::from(r)).UTF8String();
-}
-
-static CString constantName(ExecState* exec, int k, JSValue* value)
-{
- return (valueToSourceString(exec, value) + "(@k" + UString::from(k) + ")").UTF8String();
-}
-
-static CString idName(int id0, const Identifier& ident)
-{
- return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String();
-}
-
-static UString regexpToSourceString(RegExp* regExp)
-{
- UString pattern = UString("/") + regExp->pattern() + "/";
- if (regExp->global())
- pattern += "g";
- if (regExp->ignoreCase())
- pattern += "i";
- if (regExp->multiline())
- pattern += "m";
-
- return pattern;
-}
-
-static CString regexpName(int re, RegExp* regexp)
-{
- return (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
- snprintf(buffer, sizeof(buffer), "%p", p);
- return buffer;
-}
-
-NEVER_INLINE static const char* debugHookName(int debugHookID)
-{
- switch (static_cast<DebugHookID>(debugHookID)) {
- case DidEnterCallFrame:
- return "didEnterCallFrame";
- case WillLeaveCallFrame:
- return "willLeaveCallFrame";
- case WillExecuteStatement:
- return "willExecuteStatement";
- case WillExecuteProgram:
- return "willExecuteProgram";
- case DidExecuteProgram:
- return "didExecuteProgram";
- case DidReachBreakpoint:
- return "didReachBreakpoint";
- }
-
- ASSERT_NOT_REACHED();
- return "";
-}
-
-static int jumpTarget(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int offset)
-{
- return it - begin + offset;
-}
-
-static void printUnaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op)
-{
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
-
- printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str());
-}
-
-static void printBinaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op)
-{
- 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
-}
-
-static void printConditionalJump(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int location, const char* op)
-{
- int r0 = (++it)->u.operand;
- int offset = (++it)->u.operand;
- printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, jumpTarget(begin, it, offset));
-}
-
-static void printGetByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& identifiers, const char* op)
-{
- 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(r0).c_str(), registerName(r1).c_str(), idName(id0, identifiers[id0]).c_str());
- it += 4;
-}
-
-static void printPutByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& identifiers, const char* op)
-{
- 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(r0).c_str(), idName(id0, identifiers[id0]).c_str(), registerName(r1).c_str());
- it += 4;
-}
-
-void CodeBlock::printStructureID(const char* name, const Instruction* vPC, int operand) const
-{
- unsigned instructionOffset = vPC - instructions.begin();
- printf(" [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structureID).UTF8String().c_str());
-}
-
-void CodeBlock::printStructureIDs(const Instruction* vPC) const
-{
- Machine* machine = globalData->machine;
- unsigned instructionOffset = vPC - instructions.begin();
-
- if (vPC[0].u.opcode == machine->getOpcode(op_get_by_id)) {
- printStructureID("get_by_id", vPC, 4);
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_get_by_id_self)) {
- printStructureID("get_by_id_self", vPC, 4);
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_get_by_id_proto)) {
- printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structureID).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structureID).UTF8String().c_str());
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_put_by_id_transition)) {
- printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_new", pointerToSourceString(vPC[4].u.structureID).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structureID).UTF8String().c_str(), pointerToSourceString(vPC[6].u.structureIDChain).UTF8String().c_str());
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_get_by_id_chain)) {
- printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structureID).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structureIDChain).UTF8String().c_str());
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_put_by_id)) {
- printStructureID("put_by_id", vPC, 4);
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_put_by_id_replace)) {
- printStructureID("put_by_id_replace", vPC, 4);
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_resolve_global)) {
- printStructureID("resolve_global", vPC, 4);
- return;
- }
-
- // These instructions doesn't ref StructureIDs.
- ASSERT(vPC[0].u.opcode == machine->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == machine->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == machine->getOpcode(op_call) || vPC[0].u.opcode == machine->getOpcode(op_call_eval) || vPC[0].u.opcode == machine->getOpcode(op_construct));
-}
-
-void CodeBlock::dump(ExecState* exec) const
-{
- Vector<Instruction>::const_iterator begin = instructions.begin();
- Vector<Instruction>::const_iterator end = instructions.end();
-
- size_t instructionCount = 0;
- for (Vector<Instruction>::const_iterator it = begin; it != end; ++it)
- if (exec->machine()->isOpcode(it->u.opcode))
- ++instructionCount;
-
- printf("%lu instructions; %lu bytes at %p; %d parameter(s); %d callee register(s)\n\n",
- static_cast<unsigned long>(instructionCount),
- static_cast<unsigned long>(instructions.size() * sizeof(Instruction)),
- this, numParameters, numCalleeRegisters);
-
- for (Vector<Instruction>::const_iterator it = begin; it != end; ++it)
- dump(exec, begin, it);
-
- if (identifiers.size()) {
- printf("\nIdentifiers:\n");
- size_t i = 0;
- do {
- printf(" id%u = %s\n", static_cast<unsigned>(i), identifiers[i].ascii());
- ++i;
- } while (i != identifiers.size());
- }
-
- if (constantRegisters.size()) {
- printf("\nConstants:\n");
- unsigned registerIndex = numVars;
- size_t i = 0;
- do {
- printf(" r%u = %s\n", registerIndex, valueToSourceString(exec, constantRegisters[i].jsValue(exec)).ascii());
- ++i;
- ++registerIndex;
- } while (i < constantRegisters.size());
- }
-
- if (unexpectedConstants.size()) {
- printf("\nUnexpected Constants:\n");
- size_t i = 0;
- do {
- printf(" k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, unexpectedConstants[i]).ascii());
- ++i;
- } while (i < unexpectedConstants.size());
- }
-
- if (regexps.size()) {
- printf("\nRegExps:\n");
- size_t i = 0;
- do {
- printf(" re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(regexps[i].get()).ascii());
- ++i;
- } while (i < regexps.size());
- }
-
- if (globalResolveInstructions.size() || propertyAccessInstructions.size())
- printf("\nStructureIDs:\n");
-
- if (globalResolveInstructions.size()) {
- size_t i = 0;
- do {
- printStructureIDs(&instructions[globalResolveInstructions[i]]);
- ++i;
- } while (i < globalResolveInstructions.size());
- }
- if (propertyAccessInstructions.size()) {
- size_t i = 0;
- do {
- printStructureIDs(&instructions[propertyAccessInstructions[i].opcodeIndex]);
- ++i;
- } while (i < propertyAccessInstructions.size());
- }
-
- if (exceptionHandlers.size()) {
- printf("\nException Handlers:\n");
- unsigned i = 0;
- do {
- printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] }\n", i + 1, exceptionHandlers[i].start, exceptionHandlers[i].end, exceptionHandlers[i].target);
- ++i;
- } while (i < exceptionHandlers.size());
- }
-
- if (immediateSwitchJumpTables.size()) {
- printf("Immediate Switch Jump Tables:\n");
- unsigned i = 0;
- do {
- printf(" %1d = {\n", i);
- int entry = 0;
- Vector<int32_t>::const_iterator end = immediateSwitchJumpTables[i].branchOffsets.end();
- for (Vector<int32_t>::const_iterator iter = immediateSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
- if (!*iter)
- continue;
- printf("\t\t%4d => %04d\n", entry + immediateSwitchJumpTables[i].min, *iter);
- }
- printf(" }\n");
- ++i;
- } while (i < immediateSwitchJumpTables.size());
- }
-
- if (characterSwitchJumpTables.size()) {
- printf("\nCharacter Switch Jump Tables:\n");
- unsigned i = 0;
- do {
- printf(" %1d = {\n", i);
- int entry = 0;
- Vector<int32_t>::const_iterator end = characterSwitchJumpTables[i].branchOffsets.end();
- for (Vector<int32_t>::const_iterator iter = characterSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
- if (!*iter)
- continue;
- ASSERT(!((i + characterSwitchJumpTables[i].min) & ~0xFFFF));
- UChar ch = static_cast<UChar>(entry + characterSwitchJumpTables[i].min);
- printf("\t\t\"%s\" => %04d\n", UString(&ch, 1).ascii(), *iter);
- }
- printf(" }\n");
- ++i;
- } while (i < characterSwitchJumpTables.size());
- }
-
- if (stringSwitchJumpTables.size()) {
- printf("\nString Switch Jump Tables:\n");
- unsigned i = 0;
- do {
- printf(" %1d = {\n", i);
- StringJumpTable::StringOffsetTable::const_iterator end = stringSwitchJumpTables[i].offsetTable.end();
- for (StringJumpTable::StringOffsetTable::const_iterator iter = stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter)
- printf("\t\t\"%s\" => %04d\n", UString(iter->first).ascii(), iter->second.branchOffset);
- printf(" }\n");
- ++i;
- } while (i < stringSwitchJumpTables.size());
- }
-
- printf("\n");
-}
-
-void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it) const
-{
- int location = it - begin;
- switch (exec->machine()->getOpcodeID(it->u.opcode)) {
- case op_enter: {
- printf("[%4d] enter\n", location);
- break;
- }
- case op_enter_with_activation: {
- int r0 = (++it)->u.operand;
- printf("[%4d] enter_with_activation %s\n", location, registerName(r0).c_str());
- break;
- }
- case op_create_arguments: {
- printf("[%4d] create_arguments\n", location);
- break;
- }
- case op_convert_this: {
- int r0 = (++it)->u.operand;
- printf("[%4d] convert_this %s\n", location, registerName(r0).c_str());
- break;
- }
- case op_unexpected_load: {
- int r0 = (++it)->u.operand;
- int k0 = (++it)->u.operand;
- printf("[%4d] unexpected_load\t %s, %s\n", location, registerName(r0).c_str(), constantName(exec, k0, unexpectedConstants[k0]).c_str());
- break;
- }
- case op_new_object: {
- int r0 = (++it)->u.operand;
- printf("[%4d] new_object\t %s\n", location, registerName(r0).c_str());
- 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(dst).c_str(), registerName(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(r0).c_str(), regexpName(re0, regexps[re0].get()).c_str());
- break;
- }
- case op_mov: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- printf("[%4d] mov\t\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
- break;
- }
- case op_not: {
- printUnaryOp(location, it, "not");
- break;
- }
- case op_eq: {
- printBinaryOp(location, it, "eq");
- break;
- }
- case op_eq_null: {
- printUnaryOp(location, it, "eq_null");
- break;
- }
- case op_neq: {
- printBinaryOp(location, it, "neq");
- break;
- }
- case op_neq_null: {
- printUnaryOp(location, it, "neq_null");
- break;
- }
- case op_stricteq: {
- printBinaryOp(location, it, "stricteq");
- break;
- }
- case op_nstricteq: {
- printBinaryOp(location, it, "nstricteq");
- break;
- }
- case op_less: {
- printBinaryOp(location, it, "less");
- break;
- }
- case op_lesseq: {
- printBinaryOp(location, it, "lesseq");
- break;
- }
- case op_pre_inc: {
- int r0 = (++it)->u.operand;
- printf("[%4d] pre_inc\t\t %s\n", location, registerName(r0).c_str());
- break;
- }
- case op_pre_dec: {
- int r0 = (++it)->u.operand;
- printf("[%4d] pre_dec\t\t %s\n", location, registerName(r0).c_str());
- break;
- }
- case op_post_inc: {
- printUnaryOp(location, it, "post_inc");
- break;
- }
- case op_post_dec: {
- printUnaryOp(location, it, "post_dec");
- break;
- }
- case op_to_jsnumber: {
- printUnaryOp(location, it, "to_jsnumber");
- break;
- }
- case op_negate: {
- printUnaryOp(location, it, "negate");
- ++it;
- break;
- }
- case op_add: {
- printBinaryOp(location, it, "add");
- ++it;
- break;
- }
- case op_mul: {
- printBinaryOp(location, it, "mul");
- ++it;
- break;
- }
- case op_div: {
- printBinaryOp(location, it, "div");
- break;
- }
- case op_mod: {
- printBinaryOp(location, it, "mod");
- break;
- }
- case op_sub: {
- printBinaryOp(location, it, "sub");
- ++it;
- break;
- }
- case op_lshift: {
- printBinaryOp(location, it, "lshift");
- break;
- }
- case op_rshift: {
- printBinaryOp(location, it, "rshift");
- break;
- }
- case op_urshift: {
- printBinaryOp(location, it, "urshift");
- break;
- }
- case op_bitand: {
- printBinaryOp(location, it, "bitand");
- ++it;
- break;
- }
- case op_bitxor: {
- printBinaryOp(location, it, "bitxor");
- ++it;
- break;
- }
- case op_bitor: {
- printBinaryOp(location, it, "bitor");
- ++it;
- break;
- }
- case op_bitnot: {
- printUnaryOp(location, it, "bitnot");
- break;
- }
- case op_instanceof: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int r2 = (++it)->u.operand;
- int r3 = (++it)->u.operand;
- printf("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str());
- break;
- }
- case op_typeof: {
- printUnaryOp(location, it, "typeof");
- break;
- }
- case op_is_undefined: {
- printUnaryOp(location, it, "is_undefined");
- break;
- }
- case op_is_boolean: {
- printUnaryOp(location, it, "is_boolean");
- break;
- }
- case op_is_number: {
- printUnaryOp(location, it, "is_number");
- break;
- }
- case op_is_string: {
- printUnaryOp(location, it, "is_string");
- break;
- }
- case op_is_object: {
- printUnaryOp(location, it, "is_object");
- break;
- }
- case op_is_function: {
- printUnaryOp(location, it, "is_function");
- break;
- }
- case op_in: {
- printBinaryOp(location, it, "in");
- break;
- }
- case op_resolve: {
- int r0 = (++it)->u.operand;
- int id0 = (++it)->u.operand;
- printf("[%4d] resolve\t\t %s, %s\n", location, registerName(r0).c_str(), idName(id0, identifiers[id0]).c_str());
- 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(r0).c_str(), idName(id0, identifiers[id0]).c_str(), skipLevels);
- break;
- }
- case op_resolve_global: {
- int r0 = (++it)->u.operand;
- JSValue* scope = static_cast<JSValue*>((++it)->u.jsCell);
- int id0 = (++it)->u.operand;
- printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), idName(id0, identifiers[id0]).c_str());
- it += 2;
- break;
- }
- case op_get_scoped_var: {
- int r0 = (++it)->u.operand;
- int index = (++it)->u.operand;
- int skipLevels = (++it)->u.operand;
- printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(r0).c_str(), 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(r0).c_str());
- break;
- }
- case op_get_global_var: {
- int r0 = (++it)->u.operand;
- JSValue* scope = static_cast<JSValue*>((++it)->u.jsCell);
- int index = (++it)->u.operand;
- printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), index);
- break;
- }
- case op_put_global_var: {
- JSValue* scope = static_cast<JSValue*>((++it)->u.jsCell);
- int index = (++it)->u.operand;
- int r0 = (++it)->u.operand;
- printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(r0).c_str());
- 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(r0).c_str(), idName(id0, identifiers[id0]).c_str());
- 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(r0).c_str(), registerName(r1).c_str(), idName(id0, identifiers[id0]).c_str());
- break;
- }
- case op_resolve_func: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int id0 = (++it)->u.operand;
- printf("[%4d] resolve_func\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, identifiers[id0]).c_str());
- break;
- }
- case op_get_by_id: {
- printGetByIdOp(location, it, identifiers, "get_by_id");
- break;
- }
- case op_get_by_id_self: {
- printGetByIdOp(location, it, identifiers, "get_by_id_self");
- break;
- }
- case op_get_by_id_proto: {
- printGetByIdOp(location, it, identifiers, "get_by_id_proto");
- break;
- }
- case op_get_by_id_chain: {
- printGetByIdOp(location, it, identifiers, "get_by_id_chain");
- break;
- }
- case op_get_by_id_generic: {
- printGetByIdOp(location, it, identifiers, "get_by_id_generic");
- break;
- }
- case op_get_array_length: {
- printGetByIdOp(location, it, identifiers, "get_array_length");
- break;
- }
- case op_get_string_length: {
- printGetByIdOp(location, it, identifiers, "get_string_length");
- break;
- }
- case op_put_by_id: {
- printPutByIdOp(location, it, identifiers, "put_by_id");
- break;
- }
- case op_put_by_id_replace: {
- printPutByIdOp(location, it, identifiers, "put_by_id_replace");
- break;
- }
- case op_put_by_id_transition: {
- printPutByIdOp(location, it, identifiers, "put_by_id_transition");
- break;
- }
- case op_put_by_id_generic: {
- printPutByIdOp(location, it, identifiers, "put_by_id_generic");
- break;
- }
- case op_put_getter: {
- 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(r0).c_str(), idName(id0, identifiers[id0]).c_str(), registerName(r1).c_str());
- 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(r0).c_str(), idName(id0, identifiers[id0]).c_str(), registerName(r1).c_str());
- break;
- }
- case op_del_by_id: {
- 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(r0).c_str(), registerName(r1).c_str(), idName(id0, identifiers[id0]).c_str());
- 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
- 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
- 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
- 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(r0).c_str(), n0, registerName(r1).c_str());
- break;
- }
- case op_jmp: {
- int offset = (++it)->u.operand;
- printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, jumpTarget(begin, it, offset));
- break;
- }
- case op_loop: {
- int offset = (++it)->u.operand;
- printf("[%4d] loop\t\t %d(->%d)\n", location, offset, jumpTarget(begin, it, offset));
- break;
- }
- case op_jtrue: {
- printConditionalJump(begin, it, location, "jtrue");
- break;
- }
- case op_loop_if_true: {
- printConditionalJump(begin, it, location, "loop_if_true");
- break;
- }
- case op_jfalse: {
- printConditionalJump(begin, it, location, "jfalse");
- break;
- }
- case op_jeq_null: {
- printConditionalJump(begin, it, location, "jeq_null");
- break;
- }
- case op_jneq_null: {
- printConditionalJump(begin, it, location, "jneq_null");
- 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(r0).c_str(), registerName(r1).c_str(), offset, jumpTarget(begin, it, 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(r0).c_str(), registerName(r1).c_str(), offset, jumpTarget(begin, it, 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(r0).c_str(), registerName(r1).c_str(), offset, jumpTarget(begin, it, 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, jumpTarget(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
- 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, jumpTarget(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
- 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, jumpTarget(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
- 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(r0).c_str(), 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(r0).c_str(), f0);
- break;
- }
- case op_call: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int r2 = (++it)->u.operand;
- int tempCount = (++it)->u.operand;
- int argCount = (++it)->u.operand;
- int registerOffset = (++it)->u.operand;
- printf("[%4d] call\t\t %s, %s, %s, %d, %d, %d\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), tempCount, argCount, registerOffset);
- break;
- }
- case op_call_eval: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int r2 = (++it)->u.operand;
- int tempCount = (++it)->u.operand;
- int argCount = (++it)->u.operand;
- int registerOffset = (++it)->u.operand;
- printf("[%4d] call_eval\t\t %s, %s, %s, %d, %d, %d\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), tempCount, argCount, registerOffset);
- break;
- }
- case op_tear_off_activation: {
- int r0 = (++it)->u.operand;
- printf("[%4d] tear_off_activation\t %s\n", location, registerName(r0).c_str());
- break;
- }
- case op_tear_off_arguments: {
- printf("[%4d] tear_off_arguments\n", location);
- break;
- }
- case op_ret: {
- int r0 = (++it)->u.operand;
- printf("[%4d] ret\t\t %s\n", location, registerName(r0).c_str());
- break;
- }
- case op_construct: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- int r2 = (++it)->u.operand;
- int tempCount = (++it)->u.operand;
- int argCount = (++it)->u.operand;
- int registerOffset = (++it)->u.operand;
- printf("[%4d] construct\t %s, %s, %s, %d, %d, %d\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), tempCount, argCount, registerOffset);
- 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(r0).c_str(), registerName(r1).c_str());
- break;
- }
- case op_get_pnames: {
- int r0 = (++it)->u.operand;
- int r1 = (++it)->u.operand;
- printf("[%4d] get_pnames\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
- break;
- }
- case op_next_pname: {
- int dest = (++it)->u.operand;
- int iter = (++it)->u.operand;
- int offset = (++it)->u.operand;
- printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, jumpTarget(begin, it, offset));
- break;
- }
- case op_push_scope: {
- int r0 = (++it)->u.operand;
- printf("[%4d] push_scope\t %s\n", location, registerName(r0).c_str());
- break;
- }
- case op_pop_scope: {
- printf("[%4d] pop_scope\n", location);
- break;
- }
- case op_push_new_scope: {
- 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(r0).c_str(), idName(id0, identifiers[id0]).c_str(), registerName(r1).c_str());
- break;
- }
- case op_jmp_scopes: {
- int scopeDelta = (++it)->u.operand;
- int offset = (++it)->u.operand;
- printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, jumpTarget(begin, it, offset));
- break;
- }
- case op_catch: {
- int r0 = (++it)->u.operand;
- printf("[%4d] catch\t\t %s\n", location, registerName(r0).c_str());
- break;
- }
- case op_throw: {
- int r0 = (++it)->u.operand;
- printf("[%4d] throw\t\t %s\n", location, registerName(r0).c_str());
- 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(r0).c_str(), errorType, constantName(exec, k0, unexpectedConstants[k0]).c_str());
- 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(retAddrDst).c_str(), offset, jumpTarget(begin, it, offset));
- break;
- }
- case op_sret: {
- int retAddrSrc = (++it)->u.operand;
- printf("[%4d] sret\t\t %s\n", location, registerName(retAddrSrc).c_str());
- break;
- }
- case op_debug: {
- int debugHookID = (++it)->u.operand;
- int firstLine = (++it)->u.operand;
- int lastLine = (++it)->u.operand;
- printf("[%4d] debug\t\t %s, %d, %d\n", location, debugHookName(debugHookID), firstLine, lastLine);
- break;
- }
- case op_profile_will_call: {
- int function = (++it)->u.operand;
- printf("[%4d] profile_will_call %s\n", location, registerName(function).c_str());
- break;
- }
- case op_profile_did_call: {
- int function = (++it)->u.operand;
- printf("[%4d] profile_did_call\t %s\n", location, registerName(function).c_str());
- break;
- }
- case op_end: {
- int r0 = (++it)->u.operand;
- printf("[%4d] end\t\t %s\n", location, registerName(r0).c_str());
- break;
- }
- }
-}
-
-#endif // !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
-
-CodeBlock::~CodeBlock()
-{
- for (size_t size = globalResolveInstructions.size(), i = 0; i < size; ++i) {
- derefStructureIDs(&instructions[globalResolveInstructions[i]]);
- }
-
- for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
- derefStructureIDs(&instructions[propertyAccessInstructions[i].opcodeIndex]);
- if (propertyAccessInstructions[i].stubRoutine)
- WTF::fastFreeExecutable(propertyAccessInstructions[i].stubRoutine);
- }
-
- for (size_t size = callLinkInfos.size(), i = 0; i < size; ++i) {
- CallLinkInfo* callLinkInfo = &callLinkInfos[i];
- if (callLinkInfo->isLinked())
- callLinkInfo->callee->removeCaller(callLinkInfo);
- }
-
-#if ENABLE(CTI)
- unlinkCallers();
-
- if (ctiCode)
- WTF::fastFreeExecutable(ctiCode);
-#endif
-}
-
-#if ENABLE(CTI)
-void CodeBlock::unlinkCallers()
-{
- size_t size = linkedCallerList.size();
- for (size_t i = 0; i < size; ++i) {
- CallLinkInfo* currentCaller = linkedCallerList[i];
- CTI::unlinkCall(currentCaller);
- currentCaller->setUnlinked();
- }
- linkedCallerList.clear();
-}
-#endif
-
-void CodeBlock::derefStructureIDs(Instruction* vPC) const
-{
- Machine* machine = globalData->machine;
-
- if (vPC[0].u.opcode == machine->getOpcode(op_get_by_id_self)) {
- vPC[4].u.structureID->deref();
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_get_by_id_proto)) {
- vPC[4].u.structureID->deref();
- vPC[5].u.structureID->deref();
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_get_by_id_chain)) {
- vPC[4].u.structureID->deref();
- vPC[5].u.structureIDChain->deref();
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_put_by_id_transition)) {
- vPC[4].u.structureID->deref();
- vPC[5].u.structureID->deref();
- vPC[6].u.structureIDChain->deref();
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_put_by_id_replace)) {
- vPC[4].u.structureID->deref();
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_resolve_global)) {
- if(vPC[4].u.structureID)
- vPC[4].u.structureID->deref();
- return;
- }
-
- // These instructions don't ref their StructureIDs.
- ASSERT(vPC[0].u.opcode == machine->getOpcode(op_get_by_id) || vPC[0].u.opcode == machine->getOpcode(op_put_by_id) || vPC[0].u.opcode == machine->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == machine->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == machine->getOpcode(op_get_array_length) || vPC[0].u.opcode == machine->getOpcode(op_get_string_length));
-}
-
-void CodeBlock::refStructureIDs(Instruction* vPC) const
-{
- Machine* machine = globalData->machine;
-
- if (vPC[0].u.opcode == machine->getOpcode(op_get_by_id_self)) {
- vPC[4].u.structureID->ref();
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_get_by_id_proto)) {
- vPC[4].u.structureID->ref();
- vPC[5].u.structureID->ref();
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_get_by_id_chain)) {
- vPC[4].u.structureID->ref();
- vPC[5].u.structureIDChain->ref();
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_put_by_id_transition)) {
- vPC[4].u.structureID->ref();
- vPC[5].u.structureID->ref();
- vPC[6].u.structureIDChain->ref();
- return;
- }
- if (vPC[0].u.opcode == machine->getOpcode(op_put_by_id_replace)) {
- vPC[4].u.structureID->ref();
- return;
- }
-
- // These instructions don't ref their StructureIDs.
- ASSERT(vPC[0].u.opcode == machine->getOpcode(op_get_by_id) || vPC[0].u.opcode == machine->getOpcode(op_put_by_id) || vPC[0].u.opcode == machine->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == machine->getOpcode(op_put_by_id_generic));
-}
-
-void CodeBlock::mark()
-{
- for (size_t i = 0; i < constantRegisters.size(); ++i)
- if (!constantRegisters[i].marked())
- constantRegisters[i].mark();
-
- for (size_t i = 0; i < unexpectedConstants.size(); ++i)
- if (!unexpectedConstants[i]->marked())
- unexpectedConstants[i]->mark();
-
- for (size_t i = 0; i < functions.size(); ++i)
- functions[i]->body()->mark();
-
- for (size_t i = 0; i < functionExpressions.size(); ++i)
- functionExpressions[i]->body()->mark();
-}
-
-bool CodeBlock::getHandlerForVPC(const Instruction* vPC, Instruction*& target, int& scopeDepth)
-{
- Vector<HandlerInfo>::iterator ptr = exceptionHandlers.begin();
- Vector<HandlerInfo>::iterator end = exceptionHandlers.end();
- unsigned addressOffset = vPC - instructions.begin();
- ASSERT(addressOffset < instructions.size());
-
- for (; ptr != end; ++ptr) {
- // Handlers are ordered innermost first, so the first handler we encounter
- // that contains the source address is the correct handler to use.
- if (ptr->start <= addressOffset && ptr->end >= addressOffset) {
- scopeDepth = ptr->scopeDepth;
- target = instructions.begin() + ptr->target;
- return true;
- }
- }
- return false;
-}
-
-void* CodeBlock::nativeExceptionCodeForHandlerVPC(const Instruction* handlerVPC)
-{
- Vector<HandlerInfo>::iterator ptr = exceptionHandlers.begin();
- Vector<HandlerInfo>::iterator end = exceptionHandlers.end();
-
- for (; ptr != end; ++ptr) {
- Instruction*target = instructions.begin() + ptr->target;
- if (handlerVPC == target)
- return ptr->nativeCode;
- }
-
- return 0;
-}
-
-int CodeBlock::lineNumberForVPC(const Instruction* vPC)
-{
- unsigned instructionOffset = vPC - instructions.begin();
- ASSERT(instructionOffset < instructions.size());
-
- if (!lineInfo.size())
- return ownerNode->source().firstLine(); // Empty function
-
- int low = 0;
- int high = lineInfo.size();
- while (low < high) {
- int mid = low + (high - low) / 2;
- if (lineInfo[mid].instructionOffset <= instructionOffset)
- low = mid + 1;
- else
- high = mid;
- }
-
- if (!low)
- return ownerNode->source().firstLine();
- return lineInfo[low - 1].lineNumber;
-}
-
-int CodeBlock::expressionRangeForVPC(const Instruction* vPC, int& divot, int& startOffset, int& endOffset)
-{
- unsigned instructionOffset = vPC - instructions.begin();
- ASSERT(instructionOffset < instructions.size());
-
- if (!expressionInfo.size()) {
- // We didn't think anything could throw. Apparently we were wrong.
- startOffset = 0;
- endOffset = 0;
- divot = 0;
- return lineNumberForVPC(vPC);
- }
-
- int low = 0;
- int high = expressionInfo.size();
- while (low < high) {
- int mid = low + (high - low) / 2;
- if (expressionInfo[mid].instructionOffset <= instructionOffset)
- low = mid + 1;
- else
- high = mid;
- }
-
- ASSERT(low);
- if (!low) {
- startOffset = 0;
- endOffset = 0;
- divot = 0;
- return lineNumberForVPC(vPC);
- }
-
- startOffset = expressionInfo[low - 1].startOffset;
- endOffset = expressionInfo[low - 1].endOffset;
- divot = expressionInfo[low - 1].divotPoint + sourceOffset;
- return lineNumberForVPC(vPC);
-}
-
-int32_t SimpleJumpTable::offsetForValue(int32_t value, int32_t defaultOffset)
-{
- if (value >= min && static_cast<uint32_t>(value - min) < branchOffsets.size()) {
- int32_t offset = branchOffsets[value - min];
- if (offset)
- return offset;
- }
- return defaultOffset;
-}
-
-} // namespace JSC
diff --git a/JavaScriptCore/VM/CodeBlock.h b/JavaScriptCore/VM/CodeBlock.h
deleted file mode 100644
index d745164..0000000
--- a/JavaScriptCore/VM/CodeBlock.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CodeBlock_h
-#define CodeBlock_h
-
-#include "Instruction.h"
-#include "JSGlobalObject.h"
-#include "nodes.h"
-#include "Parser.h"
-#include "SourceCode.h"
-#include "ustring.h"
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
-
-namespace JSC {
-
- class ExecState;
-
- enum CodeType { GlobalCode, EvalCode, FunctionCode };
-
- static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); }
-
- struct HandlerInfo {
- uint32_t start;
- uint32_t end;
- uint32_t target;
- uint32_t scopeDepth;
- void* nativeCode;
- };
-
- struct ExpressionRangeInfo {
- enum {
- MaxOffset = (1 << 7) - 1,
- MaxDivot = (1 << 25) - 1
- };
- uint32_t instructionOffset : 25;
- uint32_t divotPoint : 25;
- uint32_t startOffset : 7;
- uint32_t endOffset : 7;
- };
-
- struct LineInfo {
- uint32_t instructionOffset;
- int32_t lineNumber;
- };
-
- struct OffsetLocation {
- int32_t branchOffset;
-#if ENABLE(CTI)
- void* ctiOffset;
-#endif
- };
-
- struct StructureStubInfo {
- StructureStubInfo(unsigned opcodeIndex)
- : opcodeIndex(opcodeIndex)
- , stubRoutine(0)
- , callReturnLocation(0)
- , hotPathBegin(0)
- {
- }
-
- unsigned opcodeIndex;
- void* stubRoutine;
- void* callReturnLocation;
- void* hotPathBegin;
- };
-
- struct CallLinkInfo {
- CallLinkInfo()
- : callReturnLocation(0)
- , hotPathBegin(0)
- , hotPathOther(0)
- , coldPathOther(0)
- , callee(0)
- {
- }
-
- unsigned opcodeIndex;
- void* callReturnLocation;
- void* hotPathBegin;
- void* hotPathOther;
- void* coldPathOther;
- CodeBlock* callee;
- unsigned position;
-
- void setUnlinked() { callee = 0; }
- bool isLinked() { return callee; }
- };
-
- inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
- {
- return structureStubInfo->callReturnLocation;
- }
-
- // Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array,
- // compares result with key (KeyTypes should be comparable with '--', '<', '>').
- // Optimized for cases where the array contains the key, checked by assertions.
- template<typename ArrayType, typename KeyType, KeyType(*valueAtPosition)(ArrayType*)>
- inline ArrayType* binaryChop(ArrayType* array, size_t size, KeyType key)
- {
- // The array must contain at least one element (pre-condition, array does conatin key).
- // If the array only contains one element, no need to do the comparison.
- while (size > 1) {
- // Pick an element to check, half way through the array, and read the value.
- int pos = (size - 1) >> 1;
- KeyType val = valueAtPosition(&array[pos]);
-
- // If the key matches, success!
- if (val == key)
- return &array[pos];
- // The item we are looking for is smaller than the item being check; reduce the value of 'size',
- // chopping off the right hand half of the array.
- else if (key < val)
- size = pos;
- // Discard all values in the left hand half of the array, up to and including the item at pos.
- else {
- size -= (pos + 1);
- array += (pos + 1);
- }
-
- // 'size' should never reach zero.
- ASSERT(size);
- }
-
- // If we reach this point we've chopped down to one element, no need to check it matches
- ASSERT(size == 1);
- ASSERT(key == valueAtPosition(&array[0]));
- return &array[0];
- }
-
- struct StringJumpTable {
- typedef HashMap<RefPtr<UString::Rep>, OffsetLocation> StringOffsetTable;
- StringOffsetTable offsetTable;
-#if ENABLE(CTI)
- void* ctiDefault; // FIXME: it should not be necessary to store this.
-#endif
-
- inline int32_t offsetForValue(UString::Rep* value, int32_t defaultOffset)
- {
- StringOffsetTable::const_iterator end = offsetTable.end();
- StringOffsetTable::const_iterator loc = offsetTable.find(value);
- if (loc == end)
- return defaultOffset;
- return loc->second.branchOffset;
- }
-
-#if ENABLE(CTI)
- inline void* ctiForValue(UString::Rep* value)
- {
- StringOffsetTable::const_iterator end = offsetTable.end();
- StringOffsetTable::const_iterator loc = offsetTable.find(value);
- if (loc == end)
- return ctiDefault;
- return loc->second.ctiOffset;
- }
-#endif
- };
-
- struct SimpleJumpTable {
- // FIXME: The two Vectors can be combind into one Vector<OffsetLocation>
- Vector<int32_t> branchOffsets;
- int32_t min;
-#if ENABLE(CTI)
- Vector<void*> ctiOffsets;
- void* ctiDefault;
-#endif
-
- int32_t offsetForValue(int32_t value, int32_t defaultOffset);
- void add(int32_t key, int32_t offset)
- {
- if (!branchOffsets[key])
- branchOffsets[key] = offset;
- }
-
-#if ENABLE(CTI)
- inline void* ctiForValue(int32_t value)
- {
- if (value >= min && static_cast<uint32_t>(value - min) < ctiOffsets.size())
- return ctiOffsets[value - min];
- return ctiDefault;
- }
-#endif
- };
-
- class EvalCodeCache {
- public:
- PassRefPtr<EvalNode> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue*& exceptionValue)
- {
- RefPtr<EvalNode> evalNode;
-
- if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())
- evalNode = cacheMap.get(evalSource.rep());
-
- if (!evalNode) {
- int errLine;
- UString errMsg;
-
- SourceCode source = makeSource(evalSource);
- evalNode = exec->globalData().parser->parse<EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
- if (evalNode) {
- if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && cacheMap.size() < maxCacheEntries)
- cacheMap.set(evalSource.rep(), evalNode);
- } else {
- exceptionValue = Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), NULL);
- return 0;
- }
- }
-
- return evalNode.release();
- }
-
- private:
- static const int maxCacheableSourceLength = 256;
- static const int maxCacheEntries = 64;
-
- HashMap<RefPtr<UString::Rep>, RefPtr<EvalNode> > cacheMap;
- };
-
- struct CodeBlock {
- CodeBlock(ScopeNode* ownerNode, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset)
- : ownerNode(ownerNode)
- , globalData(0)
-#if ENABLE(CTI)
- , ctiCode(0)
-#endif
- , numCalleeRegisters(0)
- , numConstants(0)
- , numVars(0)
- , numParameters(0)
- , needsFullScopeChain(ownerNode->needsActivation())
- , usesEval(ownerNode->usesEval())
- , codeType(codeType)
- , source(sourceProvider)
- , sourceOffset(sourceOffset)
- {
- ASSERT(source);
- }
-
- ~CodeBlock();
-
-#if ENABLE(CTI)
- void unlinkCallers();
-#endif
-
- void addCaller(CallLinkInfo* caller)
- {
- caller->callee = this;
- caller->position = linkedCallerList.size();
- linkedCallerList.append(caller);
- }
-
- void removeCaller(CallLinkInfo* caller)
- {
- unsigned pos = caller->position;
- unsigned lastPos = linkedCallerList.size() - 1;
-
- if (pos != lastPos) {
- linkedCallerList[pos] = linkedCallerList[lastPos];
- linkedCallerList[pos]->position = pos;
- }
- linkedCallerList.shrink(lastPos);
- }
-
-#if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING
- void dump(ExecState*) const;
- void printStructureIDs(const Instruction*) const;
- void printStructureID(const char* name, const Instruction*, int operand) const;
-#endif
- int expressionRangeForVPC(const Instruction*, int& divot, int& startOffset, int& endOffset);
- int lineNumberForVPC(const Instruction* vPC);
- bool getHandlerForVPC(const Instruction* vPC, Instruction*& target, int& scopeDepth);
- void* nativeExceptionCodeForHandlerVPC(const Instruction* handlerVPC);
-
- void mark();
- void refStructureIDs(Instruction* vPC) const;
- void derefStructureIDs(Instruction* vPC) const;
-
- StructureStubInfo& getStubInfo(void* returnAddress)
- {
- return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(propertyAccessInstructions.begin(), propertyAccessInstructions.size(), returnAddress));
- }
-
- ScopeNode* ownerNode;
- JSGlobalData* globalData;
-#if ENABLE(CTI)
- void* ctiCode;
-#endif
-
- int numCalleeRegisters;
-
- // NOTE: numConstants holds the number of constant registers allocated
- // by the code generator, not the number of constant registers used.
- // (Duplicate constants are uniqued during code generation, and spare
- // constant registers may be allocated.)
- int numConstants;
- int numVars;
- int numParameters;
- int thisRegister;
- bool needsFullScopeChain;
- bool usesEval;
- bool usesArguments;
- CodeType codeType;
- RefPtr<SourceProvider> source;
- unsigned sourceOffset;
-
- Vector<Instruction> instructions;
- Vector<unsigned> globalResolveInstructions;
- Vector<StructureStubInfo> propertyAccessInstructions;
- Vector<CallLinkInfo> callLinkInfos;
- Vector<CallLinkInfo*> linkedCallerList;
-
- // Constant pool
- Vector<Identifier> identifiers;
- Vector<RefPtr<FuncDeclNode> > functions;
- Vector<RefPtr<FuncExprNode> > functionExpressions;
- Vector<Register> constantRegisters;
- Vector<JSValue*> unexpectedConstants;
- Vector<RefPtr<RegExp> > regexps;
- Vector<HandlerInfo> exceptionHandlers;
- Vector<ExpressionRangeInfo> expressionInfo;
- Vector<LineInfo> lineInfo;
-
- Vector<SimpleJumpTable> immediateSwitchJumpTables;
- Vector<SimpleJumpTable> characterSwitchJumpTables;
- Vector<StringJumpTable> stringSwitchJumpTables;
-
- HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > labels;
-
-#if ENABLE(CTI)
- HashMap<void*, unsigned> ctiReturnAddressVPCMap;
-#endif
-
- EvalCodeCache evalCodeCache;
-
- private:
-#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
- void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
-#endif
-
- };
-
- // Program code is not marked by any function, so we make the global object
- // responsible for marking it.
-
- struct ProgramCodeBlock : public CodeBlock {
- ProgramCodeBlock(ScopeNode* ownerNode, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider)
- : CodeBlock(ownerNode, codeType, sourceProvider, 0)
- , globalObject(globalObject)
- {
- globalObject->codeBlocks().add(this);
- }
-
- ~ProgramCodeBlock()
- {
- if (globalObject)
- globalObject->codeBlocks().remove(this);
- }
-
- JSGlobalObject* globalObject; // For program and eval nodes, the global object that marks the constant pool.
- };
-
- struct EvalCodeBlock : public ProgramCodeBlock {
- EvalCodeBlock(ScopeNode* ownerNode, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider)
- : ProgramCodeBlock(ownerNode, EvalCode, globalObject, sourceProvider)
- {
- }
- };
-
-} // namespace JSC
-
-#endif // CodeBlock_h
diff --git a/JavaScriptCore/VM/Machine.h b/JavaScriptCore/VM/Machine.h
deleted file mode 100644
index 6cb8aaa..0000000
--- a/JavaScriptCore/VM/Machine.h
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef Machine_h
-#define Machine_h
-
-#include "ArgList.h"
-#include "JSCell.h"
-#include "JSValue.h"
-#include "Opcode.h"
-#include "RegisterFile.h"
-#include <wtf/HashMap.h>
-
-#ifdef ANDROID_INSTRUMENT
-#include "TimeCounter.h"
-#endif
-
-namespace JSC {
-
- class CodeBlock;
- class EvalNode;
- class FunctionBodyNode;
- class Instruction;
- class InternalFunction;
- class JITCodeBuffer;
- class JSFunction;
- class JSGlobalObject;
- class ProgramNode;
- class Register;
- class ScopeChainNode;
- class SamplingTool;
-
-#if ENABLE(CTI)
-
-#if USE(CTI_ARGUMENT)
-#define CTI_ARGS void** args
-#define ARGS (args)
-#else
-#define CTI_ARGS void* args, ...
-#define ARGS (&args)
-#endif
-
-#if USE(FAST_CALL_CTI_ARGUMENT)
-
-#if COMPILER(MSVC)
-#define SFX_CALL __fastcall
-#elif COMPILER(GCC)
-#define SFX_CALL __attribute__ ((fastcall))
-#else
-#error Need to support fastcall calling convention in this compiler
-#endif
-
-#else
-
-#if COMPILER(MSVC)
-#define SFX_CALL __cdecl
-#else
-#define SFX_CALL
-#endif
-
-#endif
-
- typedef uint64_t VoidPtrPair;
-
- typedef union
- {
- struct { void* first; void* second; } s;
- VoidPtrPair i;
- } VoidPtrPairValue;
-#endif
-
- enum DebugHookID {
- WillExecuteProgram,
- DidExecuteProgram,
- DidEnterCallFrame,
- DidReachBreakpoint,
- WillLeaveCallFrame,
- WillExecuteStatement
- };
-
- enum { MaxReentryDepth = 128 };
-
- class Machine {
- friend class CTI;
- public:
- Machine();
- ~Machine();
-
- RegisterFile& registerFile() { return m_registerFile; }
-
- Opcode getOpcode(OpcodeID id)
- {
- #if HAVE(COMPUTED_GOTO)
- return m_opcodeTable[id];
- #else
- return id;
- #endif
- }
-
- OpcodeID getOpcodeID(Opcode opcode)
- {
- #if HAVE(COMPUTED_GOTO)
- ASSERT(isOpcode(opcode));
- return m_opcodeIDTable.get(opcode);
- #else
- return opcode;
- #endif
- }
-
- bool isOpcode(Opcode opcode);
-
- JSValue* execute(ProgramNode*, CallFrame*, ScopeChainNode*, JSObject* thisObj, JSValue** exception);
- JSValue* execute(FunctionBodyNode*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValue** exception);
- JSValue* execute(EvalNode* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue** exception);
-
- JSValue* retrieveArguments(CallFrame*, JSFunction*) const;
- JSValue* retrieveCaller(CallFrame*, InternalFunction*) const;
- void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue*& function) const;
-
- void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
- void setTimeoutTime(unsigned timeoutTime) { m_timeoutTime = timeoutTime; }
-
- void startTimeoutCheck()
- {
- if (!m_timeoutCheckCount)
- resetTimeoutCheck();
-#ifdef ANDROID_INSTRUMENT
- if (!m_timeoutCheckCount)
- android::TimeCounter::start(android::TimeCounter::JavaScriptTimeCounter);
-#endif
- ++m_timeoutCheckCount;
- }
-
- void stopTimeoutCheck()
- {
- ASSERT(m_timeoutCheckCount);
- --m_timeoutCheckCount;
-#ifdef ANDROID_INSTRUMENT
- if (!m_timeoutCheckCount)
- android::TimeCounter::record(android::TimeCounter::JavaScriptTimeCounter, __FUNCTION__);
-#endif
- }
-
- inline void initTimeout()
- {
- ASSERT(!m_timeoutCheckCount);
- resetTimeoutCheck();
- m_timeoutTime = 0;
- m_timeoutCheckCount = 0;
- }
-
- void setSampler(SamplingTool* sampler) { m_sampler = sampler; }
- SamplingTool* sampler() { return m_sampler; }
-
-#if ENABLE(CTI)
-
- static void SFX_CALL cti_timeout_check(CTI_ARGS);
- static void SFX_CALL cti_register_file_check(CTI_ARGS);
-
- static JSObject* SFX_CALL cti_op_convert_this(CTI_ARGS);
- static void SFX_CALL cti_op_end(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_add(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_pre_inc(CTI_ARGS);
- static int SFX_CALL cti_op_loop_if_less(CTI_ARGS);
- static int SFX_CALL cti_op_loop_if_lesseq(CTI_ARGS);
- static JSObject* SFX_CALL cti_op_new_object(CTI_ARGS);
- static void SFX_CALL cti_op_put_by_id(CTI_ARGS);
- static void SFX_CALL cti_op_put_by_id_second(CTI_ARGS);
- static void SFX_CALL cti_op_put_by_id_generic(CTI_ARGS);
- static void SFX_CALL cti_op_put_by_id_fail(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_get_by_id(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_get_by_id_second(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_get_by_id_generic(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_get_by_id_fail(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_del_by_id(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_instanceof(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_mul(CTI_ARGS);
- static JSObject* SFX_CALL cti_op_new_func(CTI_ARGS);
- static VoidPtrPair SFX_CALL cti_op_call_JSFunction(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_call_NotJSFunction(CTI_ARGS);
- static void SFX_CALL cti_op_create_arguments(CTI_ARGS);
- static void SFX_CALL cti_op_create_arguments_no_params(CTI_ARGS);
- static void SFX_CALL cti_op_tear_off_activation(CTI_ARGS);
- static void SFX_CALL cti_op_tear_off_arguments(CTI_ARGS);
- static void SFX_CALL cti_op_profile_will_call(CTI_ARGS);
- static void SFX_CALL cti_op_profile_did_call(CTI_ARGS);
- static void SFX_CALL cti_op_ret_scopeChain(CTI_ARGS);
- static JSObject* SFX_CALL cti_op_new_array(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_resolve(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_resolve_global(CTI_ARGS);
- static JSObject* SFX_CALL cti_op_construct_JSConstructFast(CTI_ARGS);
- static VoidPtrPair SFX_CALL cti_op_construct_JSConstruct(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_construct_NotJSConstruct(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_get_by_val(CTI_ARGS);
- static VoidPtrPair SFX_CALL cti_op_resolve_func(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_sub(CTI_ARGS);
- static void SFX_CALL cti_op_put_by_val(CTI_ARGS);
- static void SFX_CALL cti_op_put_by_val_array(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_lesseq(CTI_ARGS);
- static int SFX_CALL cti_op_loop_if_true(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_resolve_base(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_negate(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_resolve_skip(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_div(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_pre_dec(CTI_ARGS);
- static int SFX_CALL cti_op_jless(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_not(CTI_ARGS);
- static int SFX_CALL cti_op_jtrue(CTI_ARGS);
- static VoidPtrPair SFX_CALL cti_op_post_inc(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_eq(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_lshift(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_bitand(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_rshift(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_bitnot(CTI_ARGS);
- static VoidPtrPair SFX_CALL cti_op_resolve_with_base(CTI_ARGS);
- static JSObject* SFX_CALL cti_op_new_func_exp(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_mod(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_less(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_neq(CTI_ARGS);
- static VoidPtrPair SFX_CALL cti_op_post_dec(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_urshift(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_bitxor(CTI_ARGS);
- static JSObject* SFX_CALL cti_op_new_regexp(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_bitor(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_call_eval(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_throw(CTI_ARGS);
- static JSPropertyNameIterator* SFX_CALL cti_op_get_pnames(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_next_pname(CTI_ARGS);
- static void SFX_CALL cti_op_push_scope(CTI_ARGS);
- static void SFX_CALL cti_op_pop_scope(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_typeof(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_is_undefined(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_is_boolean(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_is_number(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_is_string(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_is_object(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_is_function(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_stricteq(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_nstricteq(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_to_jsnumber(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_in(CTI_ARGS);
- static JSObject* SFX_CALL cti_op_push_new_scope(CTI_ARGS);
- static void SFX_CALL cti_op_jmp_scopes(CTI_ARGS);
- static void SFX_CALL cti_op_put_by_index(CTI_ARGS);
- static void* SFX_CALL cti_op_switch_imm(CTI_ARGS);
- static void* SFX_CALL cti_op_switch_char(CTI_ARGS);
- static void* SFX_CALL cti_op_switch_string(CTI_ARGS);
- static JSValue* SFX_CALL cti_op_del_by_val(CTI_ARGS);
- static void SFX_CALL cti_op_put_getter(CTI_ARGS);
- static void SFX_CALL cti_op_put_setter(CTI_ARGS);
- static JSObject* SFX_CALL cti_op_new_error(CTI_ARGS);
- static void SFX_CALL cti_op_debug(CTI_ARGS);
-
- static JSValue* SFX_CALL cti_allocate_number(CTI_ARGS);
-
- static JSValue* SFX_CALL cti_vm_throw(CTI_ARGS);
- static void* SFX_CALL cti_vm_compile(CTI_ARGS);
- static void* SFX_CALL cti_vm_lazyLinkCall(CTI_ARGS);
- static JSObject* SFX_CALL cti_op_push_activation(CTI_ARGS);
-
-#endif // ENABLE(CTI)
-
- // Default number of ticks before a timeout check should be done.
- static const int initialTickCountThreshold = 1024;
-
- bool isJSArray(JSValue* v) { return !JSImmediate::isImmediate(v) && v->asCell()->vptr() == m_jsArrayVptr; }
- bool isJSString(JSValue* v) { return !JSImmediate::isImmediate(v) && v->asCell()->vptr() == m_jsStringVptr; }
-
- private:
- enum ExecutionFlag { Normal, InitializeAndReturn };
-
- NEVER_INLINE JSValue* callEval(CallFrame*, JSObject* thisObject, ScopeChainNode*, RegisterFile*, int argv, int argc, JSValue*& exceptionValue);
- JSValue* execute(EvalNode*, CallFrame*, JSObject* thisObject, int registerOffset, ScopeChainNode*, JSValue** exception);
-
- NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
-
- NEVER_INLINE bool resolve(CallFrame*, Instruction*, JSValue*& exceptionValue);
- NEVER_INLINE bool resolveSkip(CallFrame*, Instruction*, JSValue*& exceptionValue);
- NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValue*& exceptionValue);
- NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC);
- NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue*& exceptionValue);
- NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
-
- NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue*, const Instruction*&, CodeBlock*&);
- NEVER_INLINE Instruction* throwException(CallFrame*&, JSValue*&, const Instruction*, bool);
- NEVER_INLINE bool resolveBaseAndFunc(CallFrame*, Instruction*, JSValue*& exceptionValue);
-
- static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
-
- static CallFrame* findFunctionCallFrame(CallFrame*, InternalFunction*);
-
- JSValue* privateExecute(ExecutionFlag, RegisterFile*, CallFrame*, JSValue** exception);
-
- void dumpCallFrame(const RegisterFile*, CallFrame*);
- void dumpRegisters(const RegisterFile*, CallFrame*);
-
- JSValue* checkTimeout(JSGlobalObject*);
- void resetTimeoutCheck();
-
- void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue* baseValue, const Identifier& propertyName, const PropertySlot&);
- void uncacheGetByID(CodeBlock*, Instruction* vPC);
- void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue* baseValue, const PutPropertySlot&);
- void uncachePutByID(CodeBlock*, Instruction* vPC);
-
- bool isCallOpcode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
-
-#if ENABLE(CTI)
- static void throwStackOverflowPreviousFrame(CallFrame*, JSGlobalData*, void*& returnAddress);
-
- void tryCTICacheGetByID(CallFrame*, CodeBlock*, void* returnAddress, JSValue* baseValue, const Identifier& propertyName, const PropertySlot&);
- void tryCTICachePutByID(CallFrame*, CodeBlock*, void* returnAddress, JSValue* baseValue, const PutPropertySlot&);
-
- void* getCTIArrayLengthTrampoline(CallFrame*, CodeBlock*);
- void* getCTIStringLengthTrampoline(CallFrame*, CodeBlock*);
-
- JITCodeBuffer* jitCodeBuffer() const { return m_jitCodeBuffer.get(); }
-#endif
-
- SamplingTool* m_sampler;
-
-#if ENABLE(CTI)
- void* m_ctiArrayLengthTrampoline;
- void* m_ctiStringLengthTrampoline;
-
- OwnPtr<JITCodeBuffer> m_jitCodeBuffer;
-#endif
-
- int m_reentryDepth;
- unsigned m_timeoutTime;
- unsigned m_timeAtLastCheckTimeout;
- unsigned m_timeExecuting;
- unsigned m_timeoutCheckCount;
- unsigned m_ticksUntilNextTimeoutCheck;
-
- RegisterFile m_registerFile;
-
- void* m_jsArrayVptr;
- void* m_jsStringVptr;
- void* m_jsFunctionVptr;
-
-#if HAVE(COMPUTED_GOTO)
- Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
- HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
-#endif
- };
-
-} // namespace JSC
-
-#endif // Machine_h
diff --git a/JavaScriptCore/VM/Opcode.h b/JavaScriptCore/VM/Opcode.h
deleted file mode 100644
index fb65cec..0000000
--- a/JavaScriptCore/VM/Opcode.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef Opcodes_h
-#define Opcodes_h
-
-#include <algorithm>
-#include <string.h>
-
-#include <wtf/Assertions.h>
-
-namespace JSC {
-
- #define FOR_EACH_OPCODE_ID(macro) \
- macro(op_enter) \
- macro(op_enter_with_activation) \
- macro(op_create_arguments) \
- macro(op_convert_this) \
- \
- macro(op_unexpected_load) \
- macro(op_new_object) \
- macro(op_new_array) \
- macro(op_new_regexp) \
- macro(op_mov) \
- \
- macro(op_not) \
- macro(op_eq) \
- macro(op_eq_null) \
- macro(op_neq) \
- macro(op_neq_null) \
- macro(op_stricteq) \
- macro(op_nstricteq) \
- macro(op_less) \
- macro(op_lesseq) \
- \
- macro(op_pre_inc) \
- macro(op_pre_dec) \
- macro(op_post_inc) \
- macro(op_post_dec) \
- macro(op_to_jsnumber) \
- macro(op_negate) \
- macro(op_add) \
- macro(op_mul) \
- macro(op_div) \
- macro(op_mod) \
- macro(op_sub) \
- \
- macro(op_lshift) \
- macro(op_rshift) \
- macro(op_urshift) \
- macro(op_bitand) \
- macro(op_bitxor) \
- macro(op_bitor) \
- macro(op_bitnot) \
- \
- macro(op_instanceof) \
- macro(op_typeof) \
- macro(op_is_undefined) \
- macro(op_is_boolean) \
- macro(op_is_number) \
- macro(op_is_string) \
- macro(op_is_object) \
- macro(op_is_function) \
- macro(op_in) \
- \
- macro(op_resolve) \
- macro(op_resolve_skip) \
- macro(op_resolve_global) \
- macro(op_get_scoped_var) \
- macro(op_put_scoped_var) \
- macro(op_get_global_var) \
- macro(op_put_global_var) \
- macro(op_resolve_base) \
- macro(op_resolve_with_base) \
- macro(op_resolve_func) \
- macro(op_get_by_id) \
- macro(op_get_by_id_self) \
- macro(op_get_by_id_proto) \
- macro(op_get_by_id_chain) \
- macro(op_get_by_id_generic) \
- macro(op_get_array_length) \
- macro(op_get_string_length) \
- macro(op_put_by_id) \
- macro(op_put_by_id_transition) \
- macro(op_put_by_id_replace) \
- macro(op_put_by_id_generic) \
- macro(op_del_by_id) \
- macro(op_get_by_val) \
- macro(op_put_by_val) \
- macro(op_del_by_val) \
- macro(op_put_by_index) \
- macro(op_put_getter) \
- macro(op_put_setter) \
- \
- macro(op_jmp) \
- macro(op_jtrue) \
- macro(op_jfalse) \
- macro(op_jeq_null) \
- macro(op_jneq_null) \
- macro(op_jnless) \
- macro(op_jmp_scopes) \
- macro(op_loop) \
- macro(op_loop_if_true) \
- macro(op_loop_if_less) \
- macro(op_loop_if_lesseq) \
- macro(op_switch_imm) \
- macro(op_switch_char) \
- macro(op_switch_string) \
- \
- macro(op_new_func) \
- macro(op_new_func_exp) \
- macro(op_call) \
- macro(op_call_eval) \
- macro(op_tear_off_activation) \
- macro(op_tear_off_arguments) \
- macro(op_ret) \
- \
- macro(op_construct) \
- macro(op_construct_verify) \
- \
- macro(op_get_pnames) \
- macro(op_next_pname) \
- \
- macro(op_push_scope) \
- macro(op_pop_scope) \
- macro(op_push_new_scope) \
- \
- macro(op_catch) \
- macro(op_throw) \
- macro(op_new_error) \
- \
- macro(op_jsr) \
- macro(op_sret) \
- \
- macro(op_debug) \
- macro(op_profile_will_call) \
- macro(op_profile_did_call) \
- \
- macro(op_end) // end must be the last opcode in the list
-
- #define OPCODE_ID_ENUM(opcode) opcode,
- typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
- #undef OPCODE_ID_ENUM
-
- const int numOpcodeIDs = op_end + 1;
-
- #define VERIFY_OPCODE_ID(id) COMPILE_ASSERT(id <= op_end, ASSERT_THAT_JS_OPCODE_IDS_ARE_VALID);
- FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
- #undef VERIFY_OPCODE_ID
-
-#if HAVE(COMPUTED_GOTO)
- typedef void* Opcode;
-#else
- typedef OpcodeID Opcode;
-#endif
-
-#if ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS)
-
-#define PADDING_STRING " "
-#define PADDING_STRING_LENGTH static_cast<unsigned>(strlen(PADDING_STRING))
-
- extern const char* const opcodeNames[];
-
- inline const char* padOpcodeName(OpcodeID op, unsigned width)
- {
- unsigned pad = width - strlen(opcodeNames[op]);
- pad = std::min(pad, PADDING_STRING_LENGTH);
- return PADDING_STRING + PADDING_STRING_LENGTH - pad;
- }
-
-#undef PADDING_STRING_LENGTH
-#undef PADDING_STRING
-
-#endif
-
-#if ENABLE(OPCODE_STATS)
-
- struct OpcodeStats {
- OpcodeStats();
- ~OpcodeStats();
- static long long opcodeCounts[numOpcodeIDs];
- static long long opcodePairCounts[numOpcodeIDs][numOpcodeIDs];
- static int lastOpcode;
-
- static void recordInstruction(int opcode);
- static void resetLastInstruction();
- };
-
-#endif
-
-} // namespace JSC
-
-#endif // Opcodes_h
diff --git a/JavaScriptCore/assembler/AssemblerBuffer.h b/JavaScriptCore/assembler/AssemblerBuffer.h
new file mode 100644
index 0000000..e1f53d8
--- /dev/null
+++ b/JavaScriptCore/assembler/AssemblerBuffer.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 AssemblerBuffer_h
+#define AssemblerBuffer_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER)
+
+#include "stdint.h"
+#include <string.h>
+#include <jit/ExecutableAllocator.h>
+#include <wtf/Assertions.h>
+#include <wtf/FastMalloc.h>
+
+namespace JSC {
+
+ class AssemblerBuffer {
+ static const int inlineCapacity = 256;
+ public:
+ AssemblerBuffer()
+ : m_buffer(m_inlineBuffer)
+ , m_capacity(inlineCapacity)
+ , m_size(0)
+ {
+ }
+
+ ~AssemblerBuffer()
+ {
+ if (m_buffer != m_inlineBuffer)
+ fastFree(m_buffer);
+ }
+
+ void ensureSpace(int space)
+ {
+ if (m_size > m_capacity - space)
+ grow();
+ }
+
+ bool isAligned(int alignment) const
+ {
+ return !(m_size & (alignment - 1));
+ }
+
+ void putByteUnchecked(int value)
+ {
+ ASSERT(!(m_size > m_capacity - 4));
+ m_buffer[m_size] = value;
+ m_size++;
+ }
+
+ void putByte(int value)
+ {
+ if (m_size > m_capacity - 4)
+ grow();
+ putByteUnchecked(value);
+ }
+
+ void putShortUnchecked(int value)
+ {
+ ASSERT(!(m_size > m_capacity - 4));
+ *reinterpret_cast<short*>(&m_buffer[m_size]) = value;
+ m_size += 2;
+ }
+
+ void putShort(int value)
+ {
+ if (m_size > m_capacity - 4)
+ grow();
+ putShortUnchecked(value);
+ }
+
+ void putIntUnchecked(int value)
+ {
+ *reinterpret_cast<int*>(&m_buffer[m_size]) = value;
+ m_size += 4;
+ }
+
+ void putInt64Unchecked(int64_t value)
+ {
+ *reinterpret_cast<int64_t*>(&m_buffer[m_size]) = value;
+ m_size += 8;
+ }
+
+ void putInt(int value)
+ {
+ if (m_size > m_capacity - 4)
+ grow();
+ putIntUnchecked(value);
+ }
+
+ void* data() const
+ {
+ return m_buffer;
+ }
+
+ int size() const
+ {
+ return m_size;
+ }
+
+ void* executableCopy(ExecutablePool* allocator)
+ {
+ if (!m_size)
+ return 0;
+
+ void* result = allocator->alloc(m_size);
+
+ if (!result)
+ return 0;
+
+ return memcpy(result, m_buffer, m_size);
+ }
+
+ private:
+ void grow()
+ {
+ m_capacity += m_capacity / 2;
+
+ if (m_buffer == m_inlineBuffer) {
+ char* newBuffer = static_cast<char*>(fastMalloc(m_capacity));
+ m_buffer = static_cast<char*>(memcpy(newBuffer, m_buffer, m_size));
+ } else
+ m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity));
+ }
+
+ char m_inlineBuffer[inlineCapacity];
+ char* m_buffer;
+ int m_capacity;
+ int m_size;
+ };
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // AssemblerBuffer_h
diff --git a/JavaScriptCore/assembler/MacroAssembler.h b/JavaScriptCore/assembler/MacroAssembler.h
new file mode 100644
index 0000000..9d24653
--- /dev/null
+++ b/JavaScriptCore/assembler/MacroAssembler.h
@@ -0,0 +1,2019 @@
+/*
+ * 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 MacroAssembler_h
+#define MacroAssembler_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER)
+
+#include "X86Assembler.h"
+
+namespace JSC {
+
+class MacroAssembler {
+protected:
+ X86Assembler m_assembler;
+
+#if PLATFORM(X86_64)
+ static const X86::RegisterID scratchRegister = X86::r11;
+#endif
+
+public:
+ typedef X86::RegisterID RegisterID;
+
+ // Note: do not rely on values in this enum, these will change (to 0..3).
+ enum Scale {
+ TimesOne = 1,
+ TimesTwo = 2,
+ TimesFour = 4,
+ TimesEight = 8,
+#if PLATFORM(X86)
+ ScalePtr = TimesFour
+#endif
+#if PLATFORM(X86_64)
+ ScalePtr = TimesEight
+#endif
+ };
+
+ MacroAssembler()
+ {
+ }
+
+ size_t size() { return m_assembler.size(); }
+ void* copyCode(ExecutablePool* allocator)
+ {
+ return m_assembler.executableCopy(allocator);
+ }
+
+
+ // Address:
+ //
+ // Describes a simple base-offset address.
+ struct Address {
+ explicit Address(RegisterID base, int32_t offset = 0)
+ : base(base)
+ , offset(offset)
+ {
+ }
+
+ RegisterID base;
+ int32_t offset;
+ };
+
+ // ImplicitAddress:
+ //
+ // This class is used for explicit 'load' and 'store' operations
+ // (as opposed to situations in which a memory operand is provided
+ // to a generic operation, such as an integer arithmetic instruction).
+ //
+ // In the case of a load (or store) operation we want to permit
+ // addresses to be implicitly constructed, e.g. the two calls:
+ //
+ // load32(Address(addrReg), destReg);
+ // load32(addrReg, destReg);
+ //
+ // Are equivalent, and the explicit wrapping of the Address in the former
+ // is unnecessary.
+ struct ImplicitAddress {
+ ImplicitAddress(RegisterID base)
+ : base(base)
+ , offset(0)
+ {
+ }
+
+ ImplicitAddress(Address address)
+ : base(address.base)
+ , offset(address.offset)
+ {
+ }
+
+ RegisterID base;
+ int32_t offset;
+ };
+
+ // BaseIndex:
+ //
+ // Describes a complex addressing mode.
+ struct BaseIndex {
+ BaseIndex(RegisterID base, RegisterID index, Scale scale, int32_t offset = 0)
+ : base(base)
+ , index(index)
+ , scale(scale)
+ , offset(offset)
+ {
+ }
+
+ RegisterID base;
+ RegisterID index;
+ Scale scale;
+ int32_t offset;
+ };
+
+ // AbsoluteAddress:
+ //
+ // Describes an memory operand given by a pointer. For regular load & store
+ // operations an unwrapped void* will be used, rather than using this.
+ struct AbsoluteAddress {
+ explicit AbsoluteAddress(void* ptr)
+ : m_ptr(ptr)
+ {
+ }
+
+ void* m_ptr;
+ };
+
+
+ class Jump;
+ class PatchBuffer;
+
+ // DataLabelPtr:
+ //
+ // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
+ // patched after the code has been generated.
+ class DataLabelPtr {
+ friend class MacroAssembler;
+ friend class PatchBuffer;
+
+ public:
+ DataLabelPtr()
+ {
+ }
+
+ DataLabelPtr(MacroAssembler* masm)
+ : m_label(masm->m_assembler.label())
+ {
+ }
+
+ static void patch(void* address, void* value)
+ {
+ X86Assembler::patchPointer(reinterpret_cast<intptr_t>(address), reinterpret_cast<intptr_t>(value));
+ }
+
+ private:
+ X86Assembler::JmpDst m_label;
+ };
+
+ // DataLabel32:
+ //
+ // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
+ // patched after the code has been generated.
+ class DataLabel32 {
+ friend class MacroAssembler;
+ friend class PatchBuffer;
+
+ public:
+ DataLabel32()
+ {
+ }
+
+ DataLabel32(MacroAssembler* masm)
+ : m_label(masm->m_assembler.label())
+ {
+ }
+
+ static void patch(void* address, int32_t value)
+ {
+ X86Assembler::patchImmediate(reinterpret_cast<intptr_t>(address), value);
+ }
+
+ private:
+ X86Assembler::JmpDst m_label;
+ };
+
+ // Label:
+ //
+ // A Label records a point in the generated instruction stream, typically such that
+ // it may be used as a destination for a jump.
+ class Label {
+ friend class Jump;
+ friend class MacroAssembler;
+ friend class PatchBuffer;
+
+ public:
+ Label()
+ {
+ }
+
+ Label(MacroAssembler* masm)
+ : m_label(masm->m_assembler.label())
+ {
+ }
+
+ // FIXME: transitionary method, while we replace JmpSrces with Jumps.
+ operator X86Assembler::JmpDst()
+ {
+ return m_label;
+ }
+
+ private:
+ X86Assembler::JmpDst m_label;
+ };
+
+
+ // Jump:
+ //
+ // A jump object is a reference to a jump instruction that has been planted
+ // into the code buffer - it is typically used to link the jump, setting the
+ // relative offset such that when executed it will jump to the desired
+ // destination.
+ //
+ // Jump objects retain a pointer to the assembler for syntactic purposes -
+ // to allow the jump object to be able to link itself, e.g.:
+ //
+ // Jump forwardsBranch = jne32(Imm32(0), reg1);
+ // // ...
+ // forwardsBranch.link();
+ //
+ // Jumps may also be linked to a Label.
+ class Jump {
+ friend class PatchBuffer;
+ friend class MacroAssembler;
+
+ public:
+ Jump()
+ {
+ }
+
+ // FIXME: transitionary method, while we replace JmpSrces with Jumps.
+ Jump(X86Assembler::JmpSrc jmp)
+ : m_jmp(jmp)
+ {
+ }
+
+ void link(MacroAssembler* masm)
+ {
+ masm->m_assembler.link(m_jmp, masm->m_assembler.label());
+ }
+
+ void linkTo(Label label, MacroAssembler* masm)
+ {
+ masm->m_assembler.link(m_jmp, label.m_label);
+ }
+
+ // FIXME: transitionary method, while we replace JmpSrces with Jumps.
+ operator X86Assembler::JmpSrc()
+ {
+ return m_jmp;
+ }
+
+ static void patch(void* address, void* destination)
+ {
+ X86Assembler::patchBranchOffset(reinterpret_cast<intptr_t>(address), destination);
+ }
+
+ private:
+ X86Assembler::JmpSrc m_jmp;
+ };
+
+ // JumpList:
+ //
+ // A JumpList is a set of Jump objects.
+ // All jumps in the set will be linked to the same destination.
+ class JumpList {
+ friend class PatchBuffer;
+
+ public:
+ void link(MacroAssembler* masm)
+ {
+ size_t size = m_jumps.size();
+ for (size_t i = 0; i < size; ++i)
+ m_jumps[i].link(masm);
+ m_jumps.clear();
+ }
+
+ void linkTo(Label label, MacroAssembler* masm)
+ {
+ size_t size = m_jumps.size();
+ for (size_t i = 0; i < size; ++i)
+ m_jumps[i].linkTo(label, masm);
+ m_jumps.clear();
+ }
+
+ void append(Jump jump)
+ {
+ m_jumps.append(jump);
+ }
+
+ void append(JumpList& other)
+ {
+ m_jumps.append(other.m_jumps.begin(), other.m_jumps.size());
+ }
+
+ bool empty()
+ {
+ return !m_jumps.size();
+ }
+
+ private:
+ Vector<Jump, 16> m_jumps;
+ };
+
+
+ // PatchBuffer:
+ //
+ // This class assists in linking code generated by the macro assembler, once code generation
+ // has been completed, and the code has been copied to is final location in memory. At this
+ // time pointers to labels within the code may be resolved, and relative offsets to external
+ // addresses may be fixed.
+ //
+ // Specifically:
+ // * Jump objects may be linked to external targets,
+ // * The address of Jump objects may taken, such that it can later be relinked.
+ // * The return address of a Jump object representing a call may be acquired.
+ // * The address of a Label pointing into the code may be resolved.
+ // * The value referenced by a DataLabel may be fixed.
+ //
+ // FIXME: distinguish between Calls & Jumps (make a specific call to obtain the return
+ // address of calls, as opposed to a point that can be used to later relink a Jump -
+ // possibly wrap the later up in an object that can do just that).
+ class PatchBuffer {
+ public:
+ PatchBuffer(void* code)
+ : m_code(code)
+ {
+ }
+
+ void link(Jump jump, void* target)
+ {
+ X86Assembler::link(m_code, jump.m_jmp, target);
+ }
+
+ void link(JumpList list, void* target)
+ {
+ for (unsigned i = 0; i < list.m_jumps.size(); ++i)
+ X86Assembler::link(m_code, list.m_jumps[i], target);
+ }
+
+ void* addressOf(Jump jump)
+ {
+ return X86Assembler::getRelocatedAddress(m_code, jump.m_jmp);
+ }
+
+ void* addressOf(Label label)
+ {
+ return X86Assembler::getRelocatedAddress(m_code, label.m_label);
+ }
+
+ void* addressOf(DataLabelPtr label)
+ {
+ return X86Assembler::getRelocatedAddress(m_code, label.m_label);
+ }
+
+ void* addressOf(DataLabel32 label)
+ {
+ return X86Assembler::getRelocatedAddress(m_code, label.m_label);
+ }
+
+ void setPtr(DataLabelPtr label, void* value)
+ {
+ X86Assembler::patchAddress(m_code, label.m_label, value);
+ }
+
+ private:
+ void* m_code;
+ };
+
+
+ // ImmPtr:
+ //
+ // A pointer sized immediate operand to an instruction - this is wrapped
+ // in a class requiring explicit construction in order to differentiate
+ // from pointers used as absolute addresses to memory operations
+ struct ImmPtr {
+ explicit ImmPtr(void* value)
+ : m_value(value)
+ {
+ }
+
+ intptr_t asIntptr()
+ {
+ return reinterpret_cast<intptr_t>(m_value);
+ }
+
+ void* m_value;
+ };
+
+
+ // Imm32:
+ //
+ // A 32bit immediate operand to an instruction - this is wrapped in a
+ // class requiring explicit construction in order to prevent RegisterIDs
+ // (which are implemented as an enum) from accidentally being passed as
+ // immediate values.
+ struct Imm32 {
+ explicit Imm32(int32_t value)
+ : m_value(value)
+ {
+ }
+
+#if PLATFORM(X86)
+ explicit Imm32(ImmPtr ptr)
+ : m_value(ptr.asIntptr())
+ {
+ }
+#endif
+
+ int32_t m_value;
+ };
+
+ // Integer arithmetic operations:
+ //
+ // Operations are typically two operand - operation(source, srcDst)
+ // For many operations the source may be an Imm32, the srcDst operand
+ // may often be a memory location (explictly described using an Address
+ // object).
+
+ void addPtr(RegisterID src, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.addq_rr(src, dest);
+#else
+ add32(src, dest);
+#endif
+ }
+
+ void addPtr(Imm32 imm, RegisterID srcDest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.addq_ir(imm.m_value, srcDest);
+#else
+ add32(imm, srcDest);
+#endif
+ }
+
+ void addPtr(ImmPtr imm, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ move(imm, scratchRegister);
+ m_assembler.addq_rr(scratchRegister, dest);
+#else
+ add32(Imm32(imm), dest);
+#endif
+ }
+
+ void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ m_assembler.leal_mr(imm.m_value, src, dest);
+ }
+
+ void add32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.addl_rr(src, dest);
+ }
+
+ void add32(Imm32 imm, Address address)
+ {
+ m_assembler.addl_im(imm.m_value, address.offset, address.base);
+ }
+
+ void add32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.addl_ir(imm.m_value, dest);
+ }
+
+ void add32(Imm32 imm, AbsoluteAddress address)
+ {
+#if PLATFORM(X86_64)
+ move(ImmPtr(address.m_ptr), scratchRegister);
+ add32(imm, Address(scratchRegister));
+#else
+ m_assembler.addl_im(imm.m_value, address.m_ptr);
+#endif
+ }
+
+ void add32(Address src, RegisterID dest)
+ {
+ m_assembler.addl_mr(src.offset, src.base, dest);
+ }
+
+ void andPtr(RegisterID src, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.andq_rr(src, dest);
+#else
+ and32(src, dest);
+#endif
+ }
+
+ void andPtr(Imm32 imm, RegisterID srcDest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.andq_ir(imm.m_value, srcDest);
+#else
+ and32(imm, srcDest);
+#endif
+ }
+
+ void and32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.andl_rr(src, dest);
+ }
+
+ void and32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.andl_ir(imm.m_value, dest);
+ }
+
+ void lshift32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.shll_i8r(imm.m_value, dest);
+ }
+
+ void lshift32(RegisterID shift_amount, RegisterID dest)
+ {
+ // On x86 we can only shift by ecx; if asked to shift by another register we'll
+ // need rejig the shift amount into ecx first, and restore the registers afterwards.
+ if (shift_amount != X86::ecx) {
+ swap(shift_amount, X86::ecx);
+
+ // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
+ if (dest == shift_amount)
+ m_assembler.shll_CLr(X86::ecx);
+ // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
+ else if (dest == X86::ecx)
+ m_assembler.shll_CLr(shift_amount);
+ // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
+ else
+ m_assembler.shll_CLr(dest);
+
+ swap(shift_amount, X86::ecx);
+ } else
+ m_assembler.shll_CLr(dest);
+ }
+
+ // Take the value from dividend, divide it by divisor, and put the remainder in remainder.
+ // For now, this operation has specific register requirements, and the three register must
+ // be unique. It is unfortunate to expose this in the MacroAssembler interface, however
+ // given the complexity to fix, the fact that it is not uncommmon for processors to have
+ // specific register requirements on this operation (e.g. Mips result in 'hi'), or to not
+ // support a hardware divide at all, it may not be
+ void mod32(RegisterID divisor, RegisterID dividend, RegisterID remainder)
+ {
+#ifdef NDEBUG
+#pragma unused(dividend,remainder)
+#else
+ ASSERT((dividend == X86::eax) && (remainder == X86::edx));
+ ASSERT((dividend != divisor) && (remainder != divisor));
+#endif
+
+ m_assembler.cdq();
+ m_assembler.idivl_r(divisor);
+ }
+
+ void mul32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.imull_rr(src, dest);
+ }
+
+ void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ m_assembler.imull_i32r(src, imm.m_value, dest);
+ }
+
+ void not32(RegisterID srcDest)
+ {
+ m_assembler.notl_r(srcDest);
+ }
+
+ void orPtr(RegisterID src, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.orq_rr(src, dest);
+#else
+ or32(src, dest);
+#endif
+ }
+
+ void orPtr(ImmPtr imm, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ move(imm, scratchRegister);
+ m_assembler.orq_rr(scratchRegister, dest);
+#else
+ or32(Imm32(imm), dest);
+#endif
+ }
+
+ void orPtr(Imm32 imm, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.orq_ir(imm.m_value, dest);
+#else
+ or32(imm, dest);
+#endif
+ }
+
+ void or32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.orl_rr(src, dest);
+ }
+
+ void or32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.orl_ir(imm.m_value, dest);
+ }
+
+ void rshiftPtr(RegisterID shift_amount, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ // On x86 we can only shift by ecx; if asked to shift by another register we'll
+ // need rejig the shift amount into ecx first, and restore the registers afterwards.
+ if (shift_amount != X86::ecx) {
+ swap(shift_amount, X86::ecx);
+
+ // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
+ if (dest == shift_amount)
+ m_assembler.sarq_CLr(X86::ecx);
+ // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
+ else if (dest == X86::ecx)
+ m_assembler.sarq_CLr(shift_amount);
+ // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
+ else
+ m_assembler.sarq_CLr(dest);
+
+ swap(shift_amount, X86::ecx);
+ } else
+ m_assembler.sarq_CLr(dest);
+#else
+ rshift32(shift_amount, dest);
+#endif
+ }
+
+ void rshiftPtr(Imm32 imm, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.sarq_i8r(imm.m_value, dest);
+#else
+ rshift32(imm, dest);
+#endif
+ }
+
+ void rshift32(RegisterID shift_amount, RegisterID dest)
+ {
+ // On x86 we can only shift by ecx; if asked to shift by another register we'll
+ // need rejig the shift amount into ecx first, and restore the registers afterwards.
+ if (shift_amount != X86::ecx) {
+ swap(shift_amount, X86::ecx);
+
+ // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
+ if (dest == shift_amount)
+ m_assembler.sarl_CLr(X86::ecx);
+ // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
+ else if (dest == X86::ecx)
+ m_assembler.sarl_CLr(shift_amount);
+ // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
+ else
+ m_assembler.sarl_CLr(dest);
+
+ swap(shift_amount, X86::ecx);
+ } else
+ m_assembler.sarl_CLr(dest);
+ }
+
+ void rshift32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.sarl_i8r(imm.m_value, dest);
+ }
+
+ void subPtr(RegisterID src, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.subq_rr(src, dest);
+#else
+ sub32(src, dest);
+#endif
+ }
+
+ void subPtr(Imm32 imm, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.subq_ir(imm.m_value, dest);
+#else
+ sub32(imm, dest);
+#endif
+ }
+
+ void subPtr(ImmPtr imm, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ move(imm, scratchRegister);
+ m_assembler.subq_rr(scratchRegister, dest);
+#else
+ sub32(Imm32(imm), dest);
+#endif
+ }
+
+ void sub32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.subl_rr(src, dest);
+ }
+
+ void sub32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.subl_ir(imm.m_value, dest);
+ }
+
+ void sub32(Imm32 imm, Address address)
+ {
+ m_assembler.subl_im(imm.m_value, address.offset, address.base);
+ }
+
+ void sub32(Imm32 imm, AbsoluteAddress address)
+ {
+#if PLATFORM(X86_64)
+ move(ImmPtr(address.m_ptr), scratchRegister);
+ sub32(imm, Address(scratchRegister));
+#else
+ m_assembler.subl_im(imm.m_value, address.m_ptr);
+#endif
+ }
+
+ void sub32(Address src, RegisterID dest)
+ {
+ m_assembler.subl_mr(src.offset, src.base, dest);
+ }
+
+ void xorPtr(RegisterID src, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.xorq_rr(src, dest);
+#else
+ xor32(src, dest);
+#endif
+ }
+
+ void xorPtr(Imm32 imm, RegisterID srcDest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.xorq_ir(imm.m_value, srcDest);
+#else
+ xor32(imm, srcDest);
+#endif
+ }
+
+ void xor32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.xorl_rr(src, dest);
+ }
+
+ void xor32(Imm32 imm, RegisterID srcDest)
+ {
+ m_assembler.xorl_ir(imm.m_value, srcDest);
+ }
+
+
+ // Memory access operations:
+ //
+ // Loads are of the form load(address, destination) and stores of the form
+ // store(source, address). The source for a store may be an Imm32. Address
+ // operand objects to loads and store will be implicitly constructed if a
+ // register is passed.
+
+ void loadPtr(ImplicitAddress address, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movq_mr(address.offset, address.base, dest);
+#else
+ load32(address, dest);
+#endif
+ }
+
+ DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movq_mr_disp32(address.offset, address.base, dest);
+ return DataLabel32(this);
+#else
+ m_assembler.movl_mr_disp32(address.offset, address.base, dest);
+ return DataLabel32(this);
+#endif
+ }
+
+ void loadPtr(BaseIndex address, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest);
+#else
+ load32(address, dest);
+#endif
+ }
+
+ void loadPtr(void* address, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ if (dest == X86::eax)
+ m_assembler.movq_mEAX(address);
+ else {
+ move(X86::eax, dest);
+ m_assembler.movq_mEAX(address);
+ swap(X86::eax, dest);
+ }
+#else
+ load32(address, dest);
+#endif
+ }
+
+ void load32(ImplicitAddress address, RegisterID dest)
+ {
+ m_assembler.movl_mr(address.offset, address.base, dest);
+ }
+
+ void load32(BaseIndex address, RegisterID dest)
+ {
+ m_assembler.movl_mr(address.offset, address.base, address.index, address.scale, dest);
+ }
+
+ void load32(void* address, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ if (dest == X86::eax)
+ m_assembler.movl_mEAX(address);
+ else {
+ move(X86::eax, dest);
+ m_assembler.movl_mEAX(address);
+ swap(X86::eax, dest);
+ }
+#else
+ m_assembler.movl_mr(address, dest);
+#endif
+ }
+
+ void load16(BaseIndex address, RegisterID dest)
+ {
+ m_assembler.movzwl_mr(address.offset, address.base, address.index, address.scale, dest);
+ }
+
+ void storePtr(RegisterID src, ImplicitAddress address)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movq_rm(src, address.offset, address.base);
+#else
+ store32(src, address);
+#endif
+ }
+
+ DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movq_rm_disp32(src, address.offset, address.base);
+ return DataLabel32(this);
+#else
+ m_assembler.movl_rm_disp32(src, address.offset, address.base);
+ return DataLabel32(this);
+#endif
+ }
+
+ void storePtr(RegisterID src, BaseIndex address)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movq_rm(src, address.offset, address.base, address.index, address.scale);
+#else
+ store32(src, address);
+#endif
+ }
+
+ void storePtr(ImmPtr imm, ImplicitAddress address)
+ {
+#if PLATFORM(X86_64)
+ move(imm, scratchRegister);
+ storePtr(scratchRegister, address);
+#else
+ m_assembler.movl_i32m(imm.asIntptr(), address.offset, address.base);
+#endif
+ }
+
+#if !PLATFORM(X86_64)
+ void storePtr(ImmPtr imm, void* address)
+ {
+ store32(Imm32(imm), address);
+ }
+#endif
+
+ DataLabelPtr storePtrWithPatch(Address address)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movq_i64r(0, scratchRegister);
+ DataLabelPtr label(this);
+ storePtr(scratchRegister, address);
+ return label;
+#else
+ m_assembler.movl_i32m(0, address.offset, address.base);
+ return DataLabelPtr(this);
+#endif
+ }
+
+ void store32(RegisterID src, ImplicitAddress address)
+ {
+ m_assembler.movl_rm(src, address.offset, address.base);
+ }
+
+ void store32(RegisterID src, BaseIndex address)
+ {
+ m_assembler.movl_rm(src, address.offset, address.base, address.index, address.scale);
+ }
+
+ void store32(Imm32 imm, ImplicitAddress address)
+ {
+ m_assembler.movl_i32m(imm.m_value, address.offset, address.base);
+ }
+
+ void store32(Imm32 imm, void* address)
+ {
+#if PLATFORM(X86_64)
+ move(X86::eax, scratchRegister);
+ move(imm, X86::eax);
+ m_assembler.movl_EAXm(address);
+ move(scratchRegister, X86::eax);
+#else
+ m_assembler.movl_i32m(imm.m_value, address);
+#endif
+ }
+
+
+ // Stack manipulation operations:
+ //
+ // The ABI is assumed to provide a stack abstraction to memory,
+ // containing machine word sized units of data. Push and pop
+ // operations add and remove a single register sized unit of data
+ // to or from the stack. Peek and poke operations read or write
+ // values on the stack, without moving the current stack position.
+
+ void pop(RegisterID dest)
+ {
+ m_assembler.pop_r(dest);
+ }
+
+ void push(RegisterID src)
+ {
+ m_assembler.push_r(src);
+ }
+
+ void push(Address address)
+ {
+ m_assembler.push_m(address.offset, address.base);
+ }
+
+ void push(Imm32 imm)
+ {
+ m_assembler.push_i32(imm.m_value);
+ }
+
+ void pop()
+ {
+ addPtr(Imm32(sizeof(void*)), X86::esp);
+ }
+
+ void peek(RegisterID dest, int index = 0)
+ {
+ loadPtr(Address(X86::esp, (index * sizeof(void *))), dest);
+ }
+
+ void poke(RegisterID src, int index = 0)
+ {
+ storePtr(src, Address(X86::esp, (index * sizeof(void *))));
+ }
+
+ void poke(Imm32 value, int index = 0)
+ {
+ store32(value, Address(X86::esp, (index * sizeof(void *))));
+ }
+
+ void poke(ImmPtr imm, int index = 0)
+ {
+ storePtr(imm, Address(X86::esp, (index * sizeof(void *))));
+ }
+
+ // Register move operations:
+ //
+ // Move values in registers.
+
+ void move(Imm32 imm, RegisterID dest)
+ {
+ // Note: on 64-bit the Imm32 value is zero extended into the register, it
+ // may be useful to have a separate version that sign extends the value?
+ if (!imm.m_value)
+ m_assembler.xorl_rr(dest, dest);
+ else
+ m_assembler.movl_i32r(imm.m_value, dest);
+ }
+
+ void move(RegisterID src, RegisterID dest)
+ {
+ // Note: on 64-bit this is is a full register move; perhaps it would be
+ // useful to have separate move32 & movePtr, with move32 zero extending?
+#if PLATFORM(X86_64)
+ m_assembler.movq_rr(src, dest);
+#else
+ m_assembler.movl_rr(src, dest);
+#endif
+ }
+
+ void move(ImmPtr imm, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ if (CAN_SIGN_EXTEND_U32_64(imm.asIntptr()))
+ m_assembler.movl_i32r(static_cast<int32_t>(imm.asIntptr()), dest);
+ else
+ m_assembler.movq_i64r(imm.asIntptr(), dest);
+#else
+ m_assembler.movl_i32r(imm.asIntptr(), dest);
+#endif
+ }
+
+ void swap(RegisterID reg1, RegisterID reg2)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.xchgq_rr(reg1, reg2);
+#else
+ m_assembler.xchgl_rr(reg1, reg2);
+#endif
+ }
+
+ void signExtend32ToPtr(RegisterID src, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movsxd_rr(src, dest);
+#else
+ if (src != dest)
+ move(src, dest);
+#endif
+ }
+
+ void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movl_rr(src, dest);
+#else
+ if (src != dest)
+ move(src, dest);
+#endif
+ }
+
+
+ // Forwards / external control flow operations:
+ //
+ // This set of jump and conditional branch operations return a Jump
+ // object which may linked at a later point, allow forwards jump,
+ // or jumps that will require external linkage (after the code has been
+ // relocated).
+ //
+ // For branches, signed <, >, <= and >= are denoted as l, g, le, and ge
+ // respecitvely, for unsigned comparisons the names b, a, be, and ae are
+ // used (representing the names 'below' and 'above').
+ //
+ // Operands to the comparision are provided in the expected order, e.g.
+ // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when
+ // treated as a signed 32bit value, is less than or equal to 5.
+ //
+ // jz and jnz test whether the first operand is equal to zero, and take
+ // an optional second operand of a mask under which to perform the test.
+
+private:
+ void compareImm32ForBranch(RegisterID left, int32_t right)
+ {
+ m_assembler.cmpl_ir(right, left);
+ }
+
+ void compareImm32ForBranchEquality(RegisterID reg, int32_t imm)
+ {
+ if (!imm)
+ m_assembler.testl_rr(reg, reg);
+ else
+ m_assembler.cmpl_ir(imm, reg);
+ }
+
+ void compareImm32ForBranchEquality(Address address, int32_t imm)
+ {
+ m_assembler.cmpl_im(imm, address.offset, address.base);
+ }
+
+ void testImm32(RegisterID reg, Imm32 mask)
+ {
+ // if we are only interested in the low seven bits, this can be tested with a testb
+ if (mask.m_value == -1)
+ m_assembler.testl_rr(reg, reg);
+ else if ((mask.m_value & ~0x7f) == 0)
+ m_assembler.testb_i8r(mask.m_value, reg);
+ else
+ m_assembler.testl_i32r(mask.m_value, reg);
+ }
+
+ void testImm32(Address address, Imm32 mask)
+ {
+ if (mask.m_value == -1)
+ m_assembler.cmpl_im(0, address.offset, address.base);
+ else
+ m_assembler.testl_i32m(mask.m_value, address.offset, address.base);
+ }
+
+ void testImm32(BaseIndex address, Imm32 mask)
+ {
+ if (mask.m_value == -1)
+ m_assembler.cmpl_im(0, address.offset, address.base, address.index, address.scale);
+ else
+ m_assembler.testl_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
+ }
+
+#if PLATFORM(X86_64)
+ void compareImm64ForBranch(RegisterID left, int32_t right)
+ {
+ m_assembler.cmpq_ir(right, left);
+ }
+
+ void compareImm64ForBranchEquality(RegisterID reg, int32_t imm)
+ {
+ if (!imm)
+ m_assembler.testq_rr(reg, reg);
+ else
+ m_assembler.cmpq_ir(imm, reg);
+ }
+
+ void testImm64(RegisterID reg, Imm32 mask)
+ {
+ // if we are only interested in the low seven bits, this can be tested with a testb
+ if (mask.m_value == -1)
+ m_assembler.testq_rr(reg, reg);
+ else if ((mask.m_value & ~0x7f) == 0)
+ m_assembler.testb_i8r(mask.m_value, reg);
+ else
+ m_assembler.testq_i32r(mask.m_value, reg);
+ }
+
+ void testImm64(Address address, Imm32 mask)
+ {
+ if (mask.m_value == -1)
+ m_assembler.cmpq_im(0, address.offset, address.base);
+ else
+ m_assembler.testq_i32m(mask.m_value, address.offset, address.base);
+ }
+
+ void testImm64(BaseIndex address, Imm32 mask)
+ {
+ if (mask.m_value == -1)
+ m_assembler.cmpq_im(0, address.offset, address.base, address.index, address.scale);
+ else
+ m_assembler.testq_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
+ }
+#endif
+
+public:
+ Jump ja32(RegisterID left, Imm32 right)
+ {
+ compareImm32ForBranch(left, right.m_value);
+ return Jump(m_assembler.ja());
+ }
+
+ Jump jaePtr(RegisterID left, RegisterID right)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.cmpq_rr(right, left);
+ return Jump(m_assembler.jae());
+#else
+ return jae32(left, right);
+#endif
+ }
+
+ Jump jaePtr(RegisterID reg, ImmPtr ptr)
+ {
+#if PLATFORM(X86_64)
+ intptr_t imm = ptr.asIntptr();
+ if (CAN_SIGN_EXTEND_32_64(imm)) {
+ compareImm64ForBranch(reg, imm);
+ return Jump(m_assembler.jae());
+ } else {
+ move(ptr, scratchRegister);
+ return jaePtr(reg, scratchRegister);
+ }
+#else
+ return jae32(reg, Imm32(ptr));
+#endif
+ }
+
+ Jump jae32(RegisterID left, RegisterID right)
+ {
+ m_assembler.cmpl_rr(right, left);
+ return Jump(m_assembler.jae());
+ }
+
+ Jump jae32(RegisterID left, Imm32 right)
+ {
+ compareImm32ForBranch(left, right.m_value);
+ return Jump(m_assembler.jae());
+ }
+
+ Jump jae32(RegisterID left, Address right)
+ {
+ m_assembler.cmpl_mr(right.offset, right.base, left);
+ return Jump(m_assembler.jae());
+ }
+
+ Jump jae32(Address left, RegisterID right)
+ {
+ m_assembler.cmpl_rm(right, left.offset, left.base);
+ return Jump(m_assembler.jae());
+ }
+
+ Jump jbPtr(RegisterID left, RegisterID right)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.cmpq_rr(right, left);
+ return Jump(m_assembler.jb());
+#else
+ return jb32(left, right);
+#endif
+ }
+
+ Jump jbPtr(RegisterID reg, ImmPtr ptr)
+ {
+#if PLATFORM(X86_64)
+ intptr_t imm = ptr.asIntptr();
+ if (CAN_SIGN_EXTEND_32_64(imm)) {
+ compareImm64ForBranch(reg, imm);
+ return Jump(m_assembler.jb());
+ } else {
+ move(ptr, scratchRegister);
+ return jbPtr(reg, scratchRegister);
+ }
+#else
+ return jb32(reg, Imm32(ptr));
+#endif
+ }
+
+ Jump jb32(RegisterID left, RegisterID right)
+ {
+ m_assembler.cmpl_rr(right, left);
+ return Jump(m_assembler.jb());
+ }
+
+ Jump jb32(RegisterID left, Imm32 right)
+ {
+ compareImm32ForBranch(left, right.m_value);
+ return Jump(m_assembler.jb());
+ }
+
+ Jump jb32(RegisterID left, Address right)
+ {
+ m_assembler.cmpl_mr(right.offset, right.base, left);
+ return Jump(m_assembler.jb());
+ }
+
+ Jump jePtr(RegisterID op1, RegisterID op2)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.cmpq_rr(op1, op2);
+ return Jump(m_assembler.je());
+#else
+ return je32(op1, op2);
+#endif
+ }
+
+ Jump jePtr(RegisterID reg, Address address)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.cmpq_rm(reg, address.offset, address.base);
+#else
+ m_assembler.cmpl_rm(reg, address.offset, address.base);
+#endif
+ return Jump(m_assembler.je());
+ }
+
+ Jump jePtr(RegisterID reg, ImmPtr ptr)
+ {
+#if PLATFORM(X86_64)
+ intptr_t imm = ptr.asIntptr();
+ if (CAN_SIGN_EXTEND_32_64(imm)) {
+ compareImm64ForBranchEquality(reg, imm);
+ return Jump(m_assembler.je());
+ } else {
+ move(ptr, scratchRegister);
+ return jePtr(scratchRegister, reg);
+ }
+#else
+ return je32(reg, Imm32(ptr));
+#endif
+ }
+
+ Jump jePtr(Address address, ImmPtr imm)
+ {
+#if PLATFORM(X86_64)
+ move(imm, scratchRegister);
+ return jePtr(scratchRegister, address);
+#else
+ return je32(address, Imm32(imm));
+#endif
+ }
+
+ Jump je32(RegisterID op1, RegisterID op2)
+ {
+ m_assembler.cmpl_rr(op1, op2);
+ return Jump(m_assembler.je());
+ }
+
+ Jump je32(Address op1, RegisterID op2)
+ {
+ m_assembler.cmpl_mr(op1.offset, op1.base, op2);
+ return Jump(m_assembler.je());
+ }
+
+ Jump je32(RegisterID reg, Imm32 imm)
+ {
+ compareImm32ForBranchEquality(reg, imm.m_value);
+ return Jump(m_assembler.je());
+ }
+
+ Jump je32(Address address, Imm32 imm)
+ {
+ compareImm32ForBranchEquality(address, imm.m_value);
+ return Jump(m_assembler.je());
+ }
+
+ Jump je16(RegisterID op1, BaseIndex op2)
+ {
+ m_assembler.cmpw_rm(op1, op2.offset, op2.base, op2.index, op2.scale);
+ return Jump(m_assembler.je());
+ }
+
+ Jump jg32(RegisterID left, RegisterID right)
+ {
+ m_assembler.cmpl_rr(right, left);
+ return Jump(m_assembler.jg());
+ }
+
+ Jump jg32(RegisterID reg, Address address)
+ {
+ m_assembler.cmpl_mr(address.offset, address.base, reg);
+ return Jump(m_assembler.jg());
+ }
+
+ Jump jgePtr(RegisterID left, RegisterID right)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.cmpq_rr(right, left);
+ return Jump(m_assembler.jge());
+#else
+ return jge32(left, right);
+#endif
+ }
+
+ Jump jgePtr(RegisterID reg, ImmPtr ptr)
+ {
+#if PLATFORM(X86_64)
+ intptr_t imm = ptr.asIntptr();
+ if (CAN_SIGN_EXTEND_32_64(imm)) {
+ compareImm64ForBranch(reg, imm);
+ return Jump(m_assembler.jge());
+ } else {
+ move(ptr, scratchRegister);
+ return jgePtr(reg, scratchRegister);
+ }
+#else
+ return jge32(reg, Imm32(ptr));
+#endif
+ }
+
+ Jump jge32(RegisterID left, RegisterID right)
+ {
+ m_assembler.cmpl_rr(right, left);
+ return Jump(m_assembler.jge());
+ }
+
+ Jump jge32(RegisterID left, Imm32 right)
+ {
+ compareImm32ForBranch(left, right.m_value);
+ return Jump(m_assembler.jge());
+ }
+
+ Jump jlPtr(RegisterID left, RegisterID right)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.cmpq_rr(right, left);
+ return Jump(m_assembler.jl());
+#else
+ return jl32(left, right);
+#endif
+ }
+
+ Jump jlPtr(RegisterID reg, ImmPtr ptr)
+ {
+#if PLATFORM(X86_64)
+ intptr_t imm = ptr.asIntptr();
+ if (CAN_SIGN_EXTEND_32_64(imm)) {
+ compareImm64ForBranch(reg, imm);
+ return Jump(m_assembler.jl());
+ } else {
+ move(ptr, scratchRegister);
+ return jlPtr(reg, scratchRegister);
+ }
+#else
+ return jl32(reg, Imm32(ptr));
+#endif
+ }
+
+ Jump jl32(RegisterID left, RegisterID right)
+ {
+ m_assembler.cmpl_rr(right, left);
+ return Jump(m_assembler.jl());
+ }
+
+ Jump jl32(RegisterID left, Imm32 right)
+ {
+ compareImm32ForBranch(left, right.m_value);
+ return Jump(m_assembler.jl());
+ }
+
+ Jump jlePtr(RegisterID left, RegisterID right)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.cmpq_rr(right, left);
+ return Jump(m_assembler.jle());
+#else
+ return jle32(left, right);
+#endif
+ }
+
+ Jump jlePtr(RegisterID reg, ImmPtr ptr)
+ {
+#if PLATFORM(X86_64)
+ intptr_t imm = ptr.asIntptr();
+ if (CAN_SIGN_EXTEND_32_64(imm)) {
+ compareImm64ForBranch(reg, imm);
+ return Jump(m_assembler.jle());
+ } else {
+ move(ptr, scratchRegister);
+ return jlePtr(reg, scratchRegister);
+ }
+#else
+ return jle32(reg, Imm32(ptr));
+#endif
+ }
+
+ Jump jle32(RegisterID left, RegisterID right)
+ {
+ m_assembler.cmpl_rr(right, left);
+ return Jump(m_assembler.jle());
+ }
+
+ Jump jle32(RegisterID left, Imm32 right)
+ {
+ compareImm32ForBranch(left, right.m_value);
+ return Jump(m_assembler.jle());
+ }
+
+ Jump jnePtr(RegisterID op1, RegisterID op2)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.cmpq_rr(op1, op2);
+ return Jump(m_assembler.jne());
+#else
+ return jne32(op1, op2);
+#endif
+ }
+
+ Jump jnePtr(RegisterID reg, Address address)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.cmpq_rm(reg, address.offset, address.base);
+#else
+ m_assembler.cmpl_rm(reg, address.offset, address.base);
+#endif
+ return Jump(m_assembler.jne());
+ }
+
+ Jump jnePtr(RegisterID reg, AbsoluteAddress address)
+ {
+#if PLATFORM(X86_64)
+ move(ImmPtr(address.m_ptr), scratchRegister);
+ return jnePtr(reg, Address(scratchRegister));
+#else
+ m_assembler.cmpl_rm(reg, address.m_ptr);
+ return Jump(m_assembler.jne());
+#endif
+ }
+
+ Jump jnePtr(RegisterID reg, ImmPtr ptr)
+ {
+#if PLATFORM(X86_64)
+ intptr_t imm = ptr.asIntptr();
+ if (CAN_SIGN_EXTEND_32_64(imm)) {
+ compareImm64ForBranchEquality(reg, imm);
+ return Jump(m_assembler.jne());
+ } else {
+ move(ptr, scratchRegister);
+ return jnePtr(scratchRegister, reg);
+ }
+#else
+ return jne32(reg, Imm32(ptr));
+#endif
+ }
+
+ Jump jnePtr(Address address, ImmPtr imm)
+ {
+#if PLATFORM(X86_64)
+ move(imm, scratchRegister);
+ return jnePtr(scratchRegister, address);
+#else
+ return jne32(address, Imm32(imm));
+#endif
+ }
+
+#if !PLATFORM(X86_64)
+ Jump jnePtr(AbsoluteAddress address, ImmPtr imm)
+ {
+ m_assembler.cmpl_im(imm.asIntptr(), address.m_ptr);
+ return Jump(m_assembler.jne());
+ }
+#endif
+
+ Jump jnePtrWithPatch(RegisterID reg, DataLabelPtr& dataLabel, ImmPtr initialValue = ImmPtr(0))
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movq_i64r(initialValue.asIntptr(), scratchRegister);
+ dataLabel = DataLabelPtr(this);
+ return jnePtr(scratchRegister, reg);
+#else
+ m_assembler.cmpl_ir_force32(initialValue.asIntptr(), reg);
+ dataLabel = DataLabelPtr(this);
+ return Jump(m_assembler.jne());
+#endif
+ }
+
+ Jump jnePtrWithPatch(Address address, DataLabelPtr& dataLabel, ImmPtr initialValue = ImmPtr(0))
+ {
+#if PLATFORM(X86_64)
+ m_assembler.movq_i64r(initialValue.asIntptr(), scratchRegister);
+ dataLabel = DataLabelPtr(this);
+ return jnePtr(scratchRegister, address);
+#else
+ m_assembler.cmpl_im_force32(initialValue.asIntptr(), address.offset, address.base);
+ dataLabel = DataLabelPtr(this);
+ return Jump(m_assembler.jne());
+#endif
+ }
+
+ Jump jne32(RegisterID op1, RegisterID op2)
+ {
+ m_assembler.cmpl_rr(op1, op2);
+ return Jump(m_assembler.jne());
+ }
+
+ Jump jne32(RegisterID reg, Imm32 imm)
+ {
+ compareImm32ForBranchEquality(reg, imm.m_value);
+ return Jump(m_assembler.jne());
+ }
+
+ Jump jne32(Address address, Imm32 imm)
+ {
+ compareImm32ForBranchEquality(address, imm.m_value);
+ return Jump(m_assembler.jne());
+ }
+
+ Jump jne32(Address address, RegisterID reg)
+ {
+ m_assembler.cmpl_rm(reg, address.offset, address.base);
+ return Jump(m_assembler.jne());
+ }
+
+ Jump jnzPtr(RegisterID reg, RegisterID mask)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.testq_rr(reg, mask);
+ return Jump(m_assembler.jne());
+#else
+ return jnz32(reg, mask);
+#endif
+ }
+
+ Jump jnzPtr(RegisterID reg, Imm32 mask = Imm32(-1))
+ {
+#if PLATFORM(X86_64)
+ testImm64(reg, mask);
+ return Jump(m_assembler.jne());
+#else
+ return jnz32(reg, mask);
+#endif
+ }
+
+ Jump jnzPtr(RegisterID reg, ImmPtr mask)
+ {
+#if PLATFORM(X86_64)
+ move(mask, scratchRegister);
+ m_assembler.testq_rr(scratchRegister, reg);
+ return Jump(m_assembler.jne());
+#else
+ return jnz32(reg, Imm32(mask));
+#endif
+ }
+
+ Jump jnzPtr(Address address, Imm32 mask = Imm32(-1))
+ {
+#if PLATFORM(X86_64)
+ testImm64(address, mask);
+ return Jump(m_assembler.jne());
+#else
+ return jnz32(address, mask);
+#endif
+ }
+
+ Jump jnz32(RegisterID reg, RegisterID mask)
+ {
+ m_assembler.testl_rr(reg, mask);
+ return Jump(m_assembler.jne());
+ }
+
+ Jump jnz32(RegisterID reg, Imm32 mask = Imm32(-1))
+ {
+ testImm32(reg, mask);
+ return Jump(m_assembler.jne());
+ }
+
+ Jump jnz32(Address address, Imm32 mask = Imm32(-1))
+ {
+ testImm32(address, mask);
+ return Jump(m_assembler.jne());
+ }
+
+ Jump jzPtr(RegisterID reg, RegisterID mask)
+ {
+#if PLATFORM(X86_64)
+ m_assembler.testq_rr(reg, mask);
+ return Jump(m_assembler.je());
+#else
+ return jz32(reg, mask);
+#endif
+ }
+
+ Jump jzPtr(RegisterID reg, Imm32 mask = Imm32(-1))
+ {
+#if PLATFORM(X86_64)
+ testImm64(reg, mask);
+ return Jump(m_assembler.je());
+#else
+ return jz32(reg, mask);
+#endif
+ }
+
+ Jump jzPtr(RegisterID reg, ImmPtr mask)
+ {
+#if PLATFORM(X86_64)
+ move(mask, scratchRegister);
+ m_assembler.testq_rr(scratchRegister, reg);
+ return Jump(m_assembler.je());
+#else
+ return jz32(reg, Imm32(mask));
+#endif
+ }
+
+ Jump jzPtr(Address address, Imm32 mask = Imm32(-1))
+ {
+#if PLATFORM(X86_64)
+ testImm64(address, mask);
+ return Jump(m_assembler.je());
+#else
+ return jz32(address, mask);
+#endif
+ }
+
+ Jump jzPtr(BaseIndex address, Imm32 mask = Imm32(-1))
+ {
+#if PLATFORM(X86_64)
+ testImm64(address, mask);
+ return Jump(m_assembler.je());
+#else
+ return jz32(address, mask);
+#endif
+ }
+
+ Jump jz32(RegisterID reg, RegisterID mask)
+ {
+ m_assembler.testl_rr(reg, mask);
+ return Jump(m_assembler.je());
+ }
+
+ Jump jz32(RegisterID reg, Imm32 mask = Imm32(-1))
+ {
+ testImm32(reg, mask);
+ return Jump(m_assembler.je());
+ }
+
+ Jump jz32(Address address, Imm32 mask = Imm32(-1))
+ {
+ testImm32(address, mask);
+ return Jump(m_assembler.je());
+ }
+
+ Jump jz32(BaseIndex address, Imm32 mask = Imm32(-1))
+ {
+ testImm32(address, mask);
+ return Jump(m_assembler.je());
+ }
+
+ Jump jump()
+ {
+ return Jump(m_assembler.jmp());
+ }
+
+
+ // Backwards, local control flow operations:
+ //
+ // These operations provide a shorter notation for local
+ // backwards branches, which may be both more convenient
+ // for the user, and for the programmer, and for the
+ // assembler (allowing shorter values to be used in
+ // relative offsets).
+ //
+ // The code sequence:
+ //
+ // Label topOfLoop(this);
+ // // ...
+ // jne32(reg1, reg2, topOfLoop);
+ //
+ // Is equivalent to the longer, potentially less efficient form:
+ //
+ // Label topOfLoop(this);
+ // // ...
+ // jne32(reg1, reg2).linkTo(topOfLoop);
+
+ void jae32(RegisterID left, Address right, Label target)
+ {
+ jae32(left, right).linkTo(target, this);
+ }
+
+ void je32(RegisterID op1, Imm32 imm, Label target)
+ {
+ je32(op1, imm).linkTo(target, this);
+ }
+
+ void je16(RegisterID op1, BaseIndex op2, Label target)
+ {
+ je16(op1, op2).linkTo(target, this);
+ }
+
+ void jl32(RegisterID left, Imm32 right, Label target)
+ {
+ jl32(left, right).linkTo(target, this);
+ }
+
+ void jle32(RegisterID left, RegisterID right, Label target)
+ {
+ jle32(left, right).linkTo(target, this);
+ }
+
+ void jnePtr(RegisterID op1, ImmPtr imm, Label target)
+ {
+ jnePtr(op1, imm).linkTo(target, this);
+ }
+
+ void jne32(RegisterID op1, RegisterID op2, Label target)
+ {
+ jne32(op1, op2).linkTo(target, this);
+ }
+
+ void jne32(RegisterID op1, Imm32 imm, Label target)
+ {
+ jne32(op1, imm).linkTo(target, this);
+ }
+
+ void jzPtr(RegisterID reg, Label target)
+ {
+ jzPtr(reg).linkTo(target, this);
+ }
+
+ void jump(Label target)
+ {
+ m_assembler.link(m_assembler.jmp(), target.m_label);
+ }
+
+ void jump(RegisterID target)
+ {
+ m_assembler.jmp_r(target);
+ }
+
+ // Address is a memory location containing the address to jump to
+ void jump(Address address)
+ {
+ m_assembler.jmp_m(address.offset, address.base);
+ }
+
+
+ // Arithmetic control flow operations:
+ //
+ // This set of conditional branch operations branch based
+ // on the result of an arithmetic operation. The operation
+ // is performed as normal, storing the result.
+ //
+ // * jz operations branch if the result is zero.
+ // * jo operations branch if the (signed) arithmetic
+ // operation caused an overflow to occur.
+
+ Jump jnzSubPtr(Imm32 imm, RegisterID dest)
+ {
+ subPtr(imm, dest);
+ return Jump(m_assembler.jne());
+ }
+
+ Jump jnzSub32(Imm32 imm, RegisterID dest)
+ {
+ sub32(imm, dest);
+ return Jump(m_assembler.jne());
+ }
+
+ Jump joAddPtr(RegisterID src, RegisterID dest)
+ {
+ addPtr(src, dest);
+ return Jump(m_assembler.jo());
+ }
+
+ Jump joAdd32(RegisterID src, RegisterID dest)
+ {
+ add32(src, dest);
+ return Jump(m_assembler.jo());
+ }
+
+ Jump joAdd32(Imm32 imm, RegisterID dest)
+ {
+ add32(imm, dest);
+ return Jump(m_assembler.jo());
+ }
+
+ Jump joMul32(RegisterID src, RegisterID dest)
+ {
+ mul32(src, dest);
+ return Jump(m_assembler.jo());
+ }
+
+ Jump joMul32(Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ mul32(imm, src, dest);
+ return Jump(m_assembler.jo());
+ }
+
+ Jump joSub32(RegisterID src, RegisterID dest)
+ {
+ sub32(src, dest);
+ return Jump(m_assembler.jo());
+ }
+
+ Jump joSub32(Imm32 imm, RegisterID dest)
+ {
+ sub32(imm, dest);
+ return Jump(m_assembler.jo());
+ }
+
+ Jump jzSubPtr(Imm32 imm, RegisterID dest)
+ {
+ subPtr(imm, dest);
+ return Jump(m_assembler.je());
+ }
+
+ Jump jzSub32(Imm32 imm, RegisterID dest)
+ {
+ sub32(imm, dest);
+ return Jump(m_assembler.je());
+ }
+
+
+ // Miscellaneous operations:
+
+ void breakpoint()
+ {
+ m_assembler.int3();
+ }
+
+ Jump call()
+ {
+ return Jump(m_assembler.call());
+ }
+
+ // FIXME: why does this return a Jump object? - it can't be linked.
+ // This may be to get a reference to the return address of the call.
+ //
+ // This should probably be handled by a separate label type to a regular
+ // jump. Todo: add a CallLabel type, for the regular call - can be linked
+ // like a jump (possibly a subclass of jump?, or possibly casts to a Jump).
+ // Also add a CallReturnLabel type for this to return (just a more JmpDsty
+ // form of label, can get the void* after the code has been linked, but can't
+ // try to link it like a Jump object), and let the CallLabel be cast into a
+ // CallReturnLabel.
+ Jump call(RegisterID target)
+ {
+ return Jump(m_assembler.call(target));
+ }
+
+ Label label()
+ {
+ return Label(this);
+ }
+
+ Label align()
+ {
+ m_assembler.align(16);
+ return Label(this);
+ }
+
+ ptrdiff_t differenceBetween(Label from, Jump to)
+ {
+ return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
+ }
+
+ ptrdiff_t differenceBetween(Label from, Label to)
+ {
+ return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_label);
+ }
+
+ ptrdiff_t differenceBetween(Label from, DataLabelPtr to)
+ {
+ return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_label);
+ }
+
+ ptrdiff_t differenceBetween(Label from, DataLabel32 to)
+ {
+ return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_label);
+ }
+
+ ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)
+ {
+ return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
+ }
+
+ void ret()
+ {
+ m_assembler.ret();
+ }
+
+ void sete32(RegisterID src, RegisterID srcDest)
+ {
+ m_assembler.cmpl_rr(srcDest, src);
+ m_assembler.sete_r(srcDest);
+ m_assembler.movzbl_rr(srcDest, srcDest);
+ }
+
+ void sete32(Imm32 imm, RegisterID srcDest)
+ {
+ compareImm32ForBranchEquality(srcDest, imm.m_value);
+ m_assembler.sete_r(srcDest);
+ m_assembler.movzbl_rr(srcDest, srcDest);
+ }
+
+ void setne32(RegisterID src, RegisterID srcDest)
+ {
+ m_assembler.cmpl_rr(srcDest, src);
+ m_assembler.setne_r(srcDest);
+ m_assembler.movzbl_rr(srcDest, srcDest);
+ }
+
+ void setne32(Imm32 imm, RegisterID srcDest)
+ {
+ compareImm32ForBranchEquality(srcDest, imm.m_value);
+ m_assembler.setne_r(srcDest);
+ m_assembler.movzbl_rr(srcDest, srcDest);
+ }
+
+ // FIXME:
+ // The mask should be optional... paerhaps the argument order should be
+ // dest-src, operations always have a dest? ... possibly not true, considering
+ // asm ops like test, or pseudo ops like pop().
+ void setnz32(Address address, Imm32 mask, RegisterID dest)
+ {
+ testImm32(address, mask);
+ m_assembler.setnz_r(dest);
+ m_assembler.movzbl_rr(dest, dest);
+ }
+
+ void setz32(Address address, Imm32 mask, RegisterID dest)
+ {
+ testImm32(address, mask);
+ m_assembler.setz_r(dest);
+ m_assembler.movzbl_rr(dest, dest);
+ }
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // MacroAssembler_h
diff --git a/JavaScriptCore/assembler/X86Assembler.h b/JavaScriptCore/assembler/X86Assembler.h
new file mode 100644
index 0000000..de23e45
--- /dev/null
+++ b/JavaScriptCore/assembler/X86Assembler.h
@@ -0,0 +1,1704 @@
+/*
+ * 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 X86Assembler_h
+#define X86Assembler_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER) && (PLATFORM(X86) || PLATFORM(X86_64))
+
+#include "AssemblerBuffer.h"
+#include <stdint.h>
+#include <wtf/Assertions.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
+#if PLATFORM(X86_64)
+inline bool CAN_SIGN_EXTEND_32_64(intptr_t value) { return value == (intptr_t)(int32_t)value; }
+inline bool CAN_SIGN_EXTEND_U32_64(intptr_t value) { return value == (intptr_t)(uint32_t)value; }
+#endif
+
+namespace X86 {
+ typedef enum {
+ eax,
+ ecx,
+ edx,
+ ebx,
+ esp,
+ ebp,
+ esi,
+ edi,
+
+#if PLATFORM(X86_64)
+ r8,
+ r9,
+ r10,
+ r11,
+ r12,
+ r13,
+ r14,
+ r15,
+#endif
+ } RegisterID;
+
+ typedef enum {
+ xmm0,
+ xmm1,
+ xmm2,
+ xmm3,
+ xmm4,
+ xmm5,
+ xmm6,
+ xmm7,
+ } XMMRegisterID;
+}
+
+class X86Assembler {
+public:
+ typedef X86::RegisterID RegisterID;
+ typedef X86::XMMRegisterID XMMRegisterID;
+
+ typedef enum {
+ OP_ADD_EvGv = 0x01,
+ OP_ADD_GvEv = 0x03,
+ OP_OR_EvGv = 0x09,
+ OP_OR_GvEv = 0x0B,
+ OP_2BYTE_ESCAPE = 0x0F,
+ OP_AND_EvGv = 0x21,
+ OP_SUB_EvGv = 0x29,
+ OP_SUB_GvEv = 0x2B,
+ PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
+ OP_XOR_EvGv = 0x31,
+ OP_CMP_EvGv = 0x39,
+ OP_CMP_GvEv = 0x3B,
+#if PLATFORM(X86_64)
+ PRE_REX = 0x40,
+#endif
+ OP_PUSH_EAX = 0x50,
+ OP_POP_EAX = 0x58,
+#if PLATFORM(X86_64)
+ OP_MOVSXD_GvEv = 0x63,
+#endif
+ PRE_OPERAND_SIZE = 0x66,
+ PRE_SSE_66 = 0x66,
+ OP_PUSH_Iz = 0x68,
+ OP_IMUL_GvEvIz = 0x69,
+ OP_GROUP1_EvIz = 0x81,
+ OP_GROUP1_EvIb = 0x83,
+ OP_TEST_EvGv = 0x85,
+ OP_XCHG_EvGv = 0x87,
+ OP_MOV_EvGv = 0x89,
+ OP_MOV_GvEv = 0x8B,
+ OP_LEA = 0x8D,
+ OP_GROUP1A_Ev = 0x8F,
+ OP_CDQ = 0x99,
+ OP_MOV_EAXOv = 0xA1,
+ OP_MOV_OvEAX = 0xA3,
+ OP_MOV_EAXIv = 0xB8,
+ OP_GROUP2_EvIb = 0xC1,
+ OP_RET = 0xC3,
+ OP_GROUP11_EvIz = 0xC7,
+ OP_INT3 = 0xCC,
+ OP_GROUP2_Ev1 = 0xD1,
+ OP_GROUP2_EvCL = 0xD3,
+ OP_CALL_rel32 = 0xE8,
+ OP_JMP_rel32 = 0xE9,
+ PRE_SSE_F2 = 0xF2,
+ OP_HLT = 0xF4,
+ OP_GROUP3_EbIb = 0xF6,
+ OP_GROUP3_Ev = 0xF7,
+ OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
+ OP_GROUP5_Ev = 0xFF,
+ } OneByteOpcodeID;
+
+ typedef enum {
+ OP2_MOVSD_VsdWsd = 0x10,
+ OP2_MOVSD_WsdVsd = 0x11,
+ OP2_CVTSI2SD_VsdEd = 0x2A,
+ OP2_CVTTSD2SI_GdWsd = 0x2C,
+ OP2_UCOMISD_VsdWsd = 0x2E,
+ OP2_ADDSD_VsdWsd = 0x58,
+ OP2_MULSD_VsdWsd = 0x59,
+ OP2_SUBSD_VsdWsd = 0x5C,
+ OP2_MOVD_VdEd = 0x6E,
+ OP2_MOVD_EdVd = 0x7E,
+ OP2_JO_rel32 = 0x80,
+ OP2_JB_rel32 = 0x82,
+ OP2_JAE_rel32 = 0x83,
+ OP2_JE_rel32 = 0x84,
+ OP2_JNE_rel32 = 0x85,
+ OP2_JBE_rel32 = 0x86,
+ OP2_JA_rel32 = 0x87,
+ OP2_JS_rel32 = 0x88,
+ OP2_JP_rel32 = 0x8A,
+ OP2_JL_rel32 = 0x8C,
+ OP2_JGE_rel32 = 0x8D,
+ OP2_JLE_rel32 = 0x8E,
+ OP2_JG_rel32 = 0x8F,
+ OP_SETE = 0x94,
+ OP_SETNE = 0x95,
+ OP2_IMUL_GvEv = 0xAF,
+ OP2_MOVZX_GvEb = 0xB6,
+ OP2_MOVZX_GvEw = 0xB7,
+ OP2_PEXTRW_GdUdIb = 0xC5,
+ } TwoByteOpcodeID;
+
+ typedef enum {
+ GROUP1_OP_ADD = 0,
+ GROUP1_OP_OR = 1,
+ GROUP1_OP_AND = 4,
+ GROUP1_OP_SUB = 5,
+ GROUP1_OP_XOR = 6,
+ GROUP1_OP_CMP = 7,
+
+ GROUP1A_OP_POP = 0,
+
+ GROUP2_OP_SHL = 4,
+ GROUP2_OP_SAR = 7,
+
+ GROUP3_OP_TEST = 0,
+ GROUP3_OP_NOT = 2,
+ GROUP3_OP_IDIV = 7,
+
+ GROUP5_OP_CALLN = 2,
+ GROUP5_OP_JMPN = 4,
+ GROUP5_OP_PUSH = 6,
+
+ GROUP11_MOV = 0,
+ } GroupOpcodeID;
+
+ // Opaque label types
+
+private:
+ class X86InstructionFormatter;
+public:
+
+ class JmpSrc {
+ friend class X86Assembler;
+ friend class X86InstructionFormatter;
+ public:
+ JmpSrc()
+ : m_offset(-1)
+ {
+ }
+
+ private:
+ JmpSrc(int offset)
+ : m_offset(offset)
+ {
+ }
+
+ int m_offset;
+ };
+
+ class JmpDst {
+ friend class X86Assembler;
+ friend class X86InstructionFormatter;
+ public:
+ JmpDst()
+ : m_offset(-1)
+ {
+ }
+
+ private:
+ JmpDst(int offset)
+ : m_offset(offset)
+ {
+ }
+
+ int m_offset;
+ };
+
+ X86Assembler()
+ {
+ }
+
+ size_t size() const { return m_formatter.size(); }
+
+ // Stack operations:
+
+ void push_r(RegisterID reg)
+ {
+ m_formatter.oneByteOp(OP_PUSH_EAX, reg);
+ }
+
+ void pop_r(RegisterID reg)
+ {
+ m_formatter.oneByteOp(OP_POP_EAX, reg);
+ }
+
+ void push_i32(int imm)
+ {
+ m_formatter.oneByteOp(OP_PUSH_Iz);
+ m_formatter.immediate32(imm);
+ }
+
+ void push_m(int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
+ }
+
+ void pop_m(int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
+ }
+
+ // Arithmetic operations:
+
+ void addl_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
+ }
+
+ void addl_mr(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
+ }
+
+ void addl_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+ void addl_im(int imm, int offset, RegisterID base)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+#if PLATFORM(X86_64)
+ void addq_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
+ }
+
+ void addq_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+#else
+ void addl_im(int imm, void* addr)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
+ m_formatter.immediate32(imm);
+ }
+ }
+#endif
+
+ void andl_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
+ }
+
+ void andl_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+#if PLATFORM(X86_64)
+ void andq_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
+ }
+
+ void andq_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+#endif
+
+ void notl_r(RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
+ }
+
+ void orl_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
+ }
+
+ void orl_mr(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
+ }
+
+ void orl_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+#if PLATFORM(X86_64)
+ void orq_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
+ }
+
+ void orq_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+#endif
+
+ void subl_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
+ }
+
+ void subl_mr(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
+ }
+
+ void subl_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+ void subl_im(int imm, int offset, RegisterID base)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+#if PLATFORM(X86_64)
+ void subq_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
+ }
+
+ void subq_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+#else
+ void subl_im(int imm, void* addr)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
+ m_formatter.immediate32(imm);
+ }
+ }
+#endif
+
+ void xorl_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
+ }
+
+ void xorl_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+#if PLATFORM(X86_64)
+ void xorq_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
+ }
+
+ void xorq_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+#endif
+
+ void sarl_i8r(int imm, RegisterID dst)
+ {
+ if (imm == 1)
+ m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
+ else {
+ m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
+ m_formatter.immediate8(imm);
+ }
+ }
+
+ void sarl_CLr(RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
+ }
+
+ void shll_i8r(int imm, RegisterID dst)
+ {
+ if (imm == 1)
+ m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
+ else {
+ m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
+ m_formatter.immediate8(imm);
+ }
+ }
+
+ void shll_CLr(RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
+ }
+
+#if PLATFORM(X86_64)
+ void sarq_CLr(RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
+ }
+
+ void sarq_i8r(int imm, RegisterID dst)
+ {
+ if (imm == 1)
+ m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
+ else {
+ m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
+ m_formatter.immediate8(imm);
+ }
+ }
+#endif
+
+ void imull_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
+ }
+
+ void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
+ m_formatter.immediate32(value);
+ }
+
+ void idivl_r(RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
+ }
+
+ // Comparisons:
+
+ void cmpl_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
+ }
+
+ void cmpl_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
+ }
+
+ void cmpl_mr(int offset, RegisterID base, RegisterID src)
+ {
+ m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
+ }
+
+ void cmpl_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+ void cmpl_ir_force32(int imm, RegisterID dst)
+ {
+ 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)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+ void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+ void cmpl_im_force32(int imm, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
+ m_formatter.immediate32(imm);
+ }
+
+#if PLATFORM(X86_64)
+ void cmpq_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
+ }
+
+ void cmpq_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
+ }
+
+ void cmpq_ir(int imm, RegisterID dst)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+ void cmpq_im(int imm, int offset, RegisterID base)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
+ m_formatter.immediate32(imm);
+ }
+ }
+
+ void cmpq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
+ m_formatter.immediate32(imm);
+ }
+ }
+#else
+ void cmpl_rm(RegisterID reg, void* addr)
+ {
+ m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
+ }
+
+ void cmpl_im(int imm, void* addr)
+ {
+ if (CAN_SIGN_EXTEND_8_32(imm)) {
+ m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
+ m_formatter.immediate8(imm);
+ } else {
+ m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
+ m_formatter.immediate32(imm);
+ }
+ }
+#endif
+
+ void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
+ {
+ m_formatter.prefix(PRE_OPERAND_SIZE);
+ m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
+ }
+
+ void testl_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
+ }
+
+ void testl_i32r(int imm, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
+ m_formatter.immediate32(imm);
+ }
+
+ void testl_i32m(int imm, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
+ m_formatter.immediate32(imm);
+ }
+
+ void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
+ {
+ m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
+ m_formatter.immediate32(imm);
+ }
+
+#if PLATFORM(X86_64)
+ void testq_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
+ }
+
+ void testq_i32r(int imm, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
+ m_formatter.immediate32(imm);
+ }
+
+ void testq_i32m(int imm, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
+ m_formatter.immediate32(imm);
+ }
+
+ void testq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
+ {
+ m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
+ m_formatter.immediate32(imm);
+ }
+#endif
+
+ void testb_i8r(int imm, RegisterID dst)
+ {
+ m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
+ m_formatter.immediate8(imm);
+ }
+
+ void sete_r(RegisterID dst)
+ {
+ m_formatter.twoByteOp8(OP_SETE, (GroupOpcodeID)0, dst);
+ }
+
+ void setz_r(RegisterID dst)
+ {
+ sete_r(dst);
+ }
+
+ void setne_r(RegisterID dst)
+ {
+ m_formatter.twoByteOp8(OP_SETNE, (GroupOpcodeID)0, dst);
+ }
+
+ void setnz_r(RegisterID dst)
+ {
+ setne_r(dst);
+ }
+
+ // Various move ops:
+
+ void cdq()
+ {
+ m_formatter.oneByteOp(OP_CDQ);
+ }
+
+ void xchgl_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
+ }
+
+#if PLATFORM(X86_64)
+ void xchgq_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
+ }
+#endif
+
+ void movl_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
+ }
+
+ void movl_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
+ }
+
+ void movl_rm_disp32(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp_disp32(OP_MOV_EvGv, src, base, offset);
+ }
+
+ void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
+ {
+ m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
+ }
+
+ void movl_mEAX(void* addr)
+ {
+ m_formatter.oneByteOp(OP_MOV_EAXOv);
+#if PLATFORM(X86_64)
+ m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
+#else
+ m_formatter.immediate32(reinterpret_cast<int>(addr));
+#endif
+ }
+
+ void movl_mr(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
+ }
+
+ void movl_mr_disp32(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset);
+ }
+
+ void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
+ }
+
+ void movl_i32r(int imm, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
+ m_formatter.immediate32(imm);
+ }
+
+ void movl_i32m(int imm, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
+ m_formatter.immediate32(imm);
+ }
+
+ void movl_EAXm(void* addr)
+ {
+ m_formatter.oneByteOp(OP_MOV_OvEAX);
+#if PLATFORM(X86_64)
+ m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
+#else
+ m_formatter.immediate32(reinterpret_cast<int>(addr));
+#endif
+ }
+
+#if PLATFORM(X86_64)
+ void movq_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
+ }
+
+ void movq_rm(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
+ }
+
+ void movq_rm_disp32(RegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp64_disp32(OP_MOV_EvGv, src, base, offset);
+ }
+
+ void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
+ {
+ m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
+ }
+
+ void movq_mEAX(void* addr)
+ {
+ m_formatter.oneByteOp64(OP_MOV_EAXOv);
+ m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
+ }
+
+ void movq_mr(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
+ }
+
+ void movq_mr_disp32(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.oneByteOp64_disp32(OP_MOV_GvEv, dst, base, offset);
+ }
+
+ void movq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
+ }
+
+ void movq_i64r(int64_t imm, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
+ m_formatter.immediate64(imm);
+ }
+
+ void movsxd_rr(RegisterID src, RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
+ }
+
+
+#else
+ void movl_mr(void* addr, RegisterID dst)
+ {
+ if (dst == X86::eax)
+ movl_mEAX(addr);
+ else
+ m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
+ }
+
+ void movl_i32m(int imm, void* addr)
+ {
+ m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
+ m_formatter.immediate32(imm);
+ }
+#endif
+
+ void movzwl_mr(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
+ }
+
+ void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
+ {
+ m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
+ }
+
+ void movzbl_rr(RegisterID src, RegisterID dst)
+ {
+ // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
+ // is in the range ESP-EDI, and the src would not have required a REX). Unneeded
+ // REX prefixes are defined to be silently ignored by the processor.
+ m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
+ }
+
+ void leal_mr(int offset, RegisterID base, RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_LEA, dst, base, offset);
+ }
+
+ // Flow control:
+
+ JmpSrc call()
+ {
+ m_formatter.oneByteOp(OP_CALL_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc call(RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
+ return JmpSrc(m_formatter.size());
+ }
+
+ JmpSrc jmp()
+ {
+ m_formatter.oneByteOp(OP_JMP_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ void jmp_r(RegisterID dst)
+ {
+ m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
+ }
+
+ void jmp_m(int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
+ }
+
+ JmpSrc jne()
+ {
+ m_formatter.twoByteOp(OP2_JNE_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jnz()
+ {
+ return jne();
+ }
+
+ JmpSrc je()
+ {
+ m_formatter.twoByteOp(OP2_JE_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jl()
+ {
+ m_formatter.twoByteOp(OP2_JL_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jb()
+ {
+ m_formatter.twoByteOp(OP2_JB_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jle()
+ {
+ m_formatter.twoByteOp(OP2_JLE_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jbe()
+ {
+ m_formatter.twoByteOp(OP2_JBE_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jge()
+ {
+ m_formatter.twoByteOp(OP2_JGE_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jg()
+ {
+ m_formatter.twoByteOp(OP2_JG_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc ja()
+ {
+ m_formatter.twoByteOp(OP2_JA_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jae()
+ {
+ m_formatter.twoByteOp(OP2_JAE_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jo()
+ {
+ m_formatter.twoByteOp(OP2_JO_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jp()
+ {
+ m_formatter.twoByteOp(OP2_JP_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc js()
+ {
+ m_formatter.twoByteOp(OP2_JS_rel32);
+ return m_formatter.immediateRel32();
+ }
+
+ // SSE operations:
+
+ void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+ }
+
+ void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
+ }
+
+ void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
+ }
+
+ void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
+ }
+
+ void movd_rr(XMMRegisterID src, RegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_66);
+ m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
+ }
+
+#if PLATFORM(X86_64)
+ void movq_rr(XMMRegisterID src, RegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_66);
+ m_formatter.twoByteOp64(OP2_MOVD_EdVd, (RegisterID)src, dst);
+ }
+
+ void movq_rr(RegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_66);
+ m_formatter.twoByteOp64(OP2_MOVD_VdEd, (RegisterID)dst, src);
+ }
+#endif
+
+ void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
+ }
+
+ void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
+ }
+
+ void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+ }
+
+ void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
+ }
+
+ void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_66);
+ m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
+ m_formatter.immediate8(whichWord);
+ }
+
+ void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+ }
+
+ void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_F2);
+ m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
+ }
+
+ void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
+ {
+ m_formatter.prefix(PRE_SSE_66);
+ m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+ }
+
+ // Misc instructions:
+
+ void int3()
+ {
+ m_formatter.oneByteOp(OP_INT3);
+ }
+
+ void ret()
+ {
+ m_formatter.oneByteOp(OP_RET);
+ }
+
+ void predictNotTaken()
+ {
+ m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
+ }
+
+ // Assembler admin methods:
+
+ JmpDst label()
+ {
+ return JmpDst(m_formatter.size());
+ }
+
+ JmpDst align(int alignment)
+ {
+ while (!m_formatter.isAligned(alignment))
+ m_formatter.oneByteOp(OP_HLT);
+
+ return label();
+ }
+
+ // Linking & patching:
+
+ void link(JmpSrc from, JmpDst to)
+ {
+ ASSERT(to.m_offset != -1);
+ ASSERT(from.m_offset != -1);
+
+ reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
+ }
+
+ static void patchAddress(void* code, JmpDst position, void* value)
+ {
+ ASSERT(position.m_offset != -1);
+
+ reinterpret_cast<void**>(reinterpret_cast<ptrdiff_t>(code) + position.m_offset)[-1] = value;
+ }
+
+ static void link(void* code, JmpSrc from, void* to)
+ {
+ ASSERT(from.m_offset != -1);
+
+ reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
+ }
+
+ static void* getRelocatedAddress(void* code, JmpSrc jump)
+ {
+ return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
+ }
+
+ static void* getRelocatedAddress(void* code, JmpDst destination)
+ {
+ ASSERT(destination.m_offset != -1);
+
+ return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + destination.m_offset);
+ }
+
+ static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
+ {
+ return dst.m_offset - src.m_offset;
+ }
+
+ static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
+ {
+ return dst.m_offset - src.m_offset;
+ }
+
+ static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)
+ {
+ return dst.m_offset - src.m_offset;
+ }
+
+ static void patchImmediate(intptr_t where, int32_t value)
+ {
+ reinterpret_cast<int32_t*>(where)[-1] = value;
+ }
+
+ static void patchPointer(intptr_t where, intptr_t value)
+ {
+ reinterpret_cast<intptr_t*>(where)[-1] = value;
+ }
+
+ static void patchBranchOffset(intptr_t where, void* destination)
+ {
+ intptr_t offset = reinterpret_cast<intptr_t>(destination) - where;
+ ASSERT(offset == static_cast<int32_t>(offset));
+ reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset);
+ }
+
+ void* executableCopy(ExecutablePool* allocator)
+ {
+ void* copy = m_formatter.executableCopy(allocator);
+ ASSERT(copy);
+ return copy;
+ }
+
+private:
+
+ class X86InstructionFormatter {
+
+ static const int maxInstructionSize = 16;
+
+ public:
+
+ // Legacy prefix bytes:
+ //
+ // These are emmitted prior to the instruction.
+
+ void prefix(OneByteOpcodeID pre)
+ {
+ m_buffer.putByte(pre);
+ }
+
+ // Word-sized operands / no operand instruction formatters.
+ //
+ // In addition to the opcode, the following operand permutations are supported:
+ // * None - instruction takes no operands.
+ // * One register - the low three bits of the RegisterID are added into the opcode.
+ // * Two registers - encode a register form ModRm (for all ModRm formats, the reg field is passed first, and a GroupOpcodeID may be passed in its place).
+ // * Three argument ModRM - a register, and a register and an offset describing a memory operand.
+ // * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
+ //
+ // For 32-bit x86 targets, the address operand may also be provided as a void*.
+ // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
+ //
+ // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
+
+ void oneByteOp(OneByteOpcodeID opcode)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ m_buffer.putByteUnchecked(opcode);
+ }
+
+ void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIfNeeded(0, 0, reg);
+ m_buffer.putByteUnchecked(opcode + (reg & 7));
+ }
+
+ void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIfNeeded(reg, 0, rm);
+ m_buffer.putByteUnchecked(opcode);
+ registerModRM(reg, rm);
+ }
+
+ void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIfNeeded(reg, 0, base);
+ m_buffer.putByteUnchecked(opcode);
+ memoryModRM(reg, base, offset);
+ }
+
+ void oneByteOp_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIfNeeded(reg, 0, base);
+ m_buffer.putByteUnchecked(opcode);
+ memoryModRM_disp32(reg, base, offset);
+ }
+
+ void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIfNeeded(reg, index, base);
+ m_buffer.putByteUnchecked(opcode);
+ memoryModRM(reg, base, index, scale, offset);
+ }
+
+#if !PLATFORM(X86_64)
+ void oneByteOp(OneByteOpcodeID opcode, int reg, void* address)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ m_buffer.putByteUnchecked(opcode);
+ memoryModRM(reg, address);
+ }
+#endif
+
+ void twoByteOp(TwoByteOpcodeID opcode)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
+ m_buffer.putByteUnchecked(opcode);
+ }
+
+ void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIfNeeded(reg, 0, rm);
+ m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
+ m_buffer.putByteUnchecked(opcode);
+ registerModRM(reg, rm);
+ }
+
+ void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIfNeeded(reg, 0, base);
+ m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
+ m_buffer.putByteUnchecked(opcode);
+ memoryModRM(reg, base, offset);
+ }
+
+ void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIfNeeded(reg, index, base);
+ m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
+ m_buffer.putByteUnchecked(opcode);
+ memoryModRM(reg, base, index, scale, offset);
+ }
+
+#if PLATFORM(X86_64)
+ // Quad-word-sized operands:
+ //
+ // Used to format 64-bit operantions, planting a REX.w prefix.
+ // When planting d64 or f64 instructions, not requiring a REX.w prefix,
+ // the normal (non-'64'-postfixed) formatters should be used.
+
+ void oneByteOp64(OneByteOpcodeID opcode)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexW(0, 0, 0);
+ m_buffer.putByteUnchecked(opcode);
+ }
+
+ void oneByteOp64(OneByteOpcodeID opcode, RegisterID reg)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexW(0, 0, reg);
+ m_buffer.putByteUnchecked(opcode + (reg & 7));
+ }
+
+ void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID rm)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexW(reg, 0, rm);
+ m_buffer.putByteUnchecked(opcode);
+ registerModRM(reg, rm);
+ }
+
+ void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexW(reg, 0, base);
+ m_buffer.putByteUnchecked(opcode);
+ memoryModRM(reg, base, offset);
+ }
+
+ void oneByteOp64_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexW(reg, 0, base);
+ m_buffer.putByteUnchecked(opcode);
+ memoryModRM_disp32(reg, base, offset);
+ }
+
+ void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexW(reg, index, base);
+ m_buffer.putByteUnchecked(opcode);
+ memoryModRM(reg, base, index, scale, offset);
+ }
+
+ void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexW(reg, 0, rm);
+ m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
+ m_buffer.putByteUnchecked(opcode);
+ registerModRM(reg, rm);
+ }
+#endif
+
+ // Byte-operands:
+ //
+ // These methods format byte operations. Byte operations differ from the normal
+ // formatters in the circumstances under which they will decide to emit REX prefixes.
+ // These should be used where any register operand signifies a byte register.
+ //
+ // The disctinction is due to the handling of register numbers in the range 4..7 on
+ // x86-64. These register numbers may either represent the second byte of the first
+ // four registers (ah..bh) or the first byte of the second four registers (spl..dil).
+ //
+ // Since ah..bh cannot be used in all permutations of operands (specifically cannot
+ // be accessed where a REX prefix is present), these are likely best treated as
+ // deprecated. In order to ensure the correct registers spl..dil are selected a
+ // REX prefix will be emitted for any byte register operand in the range 4..15.
+ //
+ // These formatters may be used in instructions where a mix of operand sizes, in which
+ // case an unnecessary REX will be emitted, for example:
+ // movzbl %al, %edi
+ // In this case a REX will be planted since edi is 7 (and were this a byte operand
+ // a REX would be required to specify dil instead of bh). Unneeded REX prefixes will
+ // be silently ignored by the processor.
+ //
+ // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex()
+ // is provided to check byte register operands.
+
+ void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
+ m_buffer.putByteUnchecked(opcode);
+ registerModRM(groupOp, rm);
+ }
+
+ void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
+ m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
+ m_buffer.putByteUnchecked(opcode);
+ registerModRM(reg, rm);
+ }
+
+ void twoByteOp8(TwoByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
+ {
+ m_buffer.ensureSpace(maxInstructionSize);
+ emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
+ m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
+ m_buffer.putByteUnchecked(opcode);
+ registerModRM(groupOp, rm);
+ }
+
+ // Immediates:
+ //
+ // An immedaite should be appended where appropriate after an op has been emitted.
+ // The writes are unchecked since the opcode formatters above will have ensured space.
+
+ void immediate8(int imm)
+ {
+ m_buffer.putByteUnchecked(imm);
+ }
+
+ void immediate32(int imm)
+ {
+ m_buffer.putIntUnchecked(imm);
+ }
+
+ void immediate64(int64_t imm)
+ {
+ m_buffer.putInt64Unchecked(imm);
+ }
+
+ JmpSrc immediateRel32()
+ {
+ m_buffer.putIntUnchecked(0);
+ return JmpSrc(m_buffer.size());
+ }
+
+ // Administrative methods:
+
+ size_t size() const { return m_buffer.size(); }
+ bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
+ void* data() const { return m_buffer.data(); }
+ void* executableCopy(ExecutablePool* allocator) { return m_buffer.executableCopy(allocator); }
+
+ private:
+
+ // Internals; ModRm and REX formatters.
+
+ static const RegisterID noBase = X86::ebp;
+ static const RegisterID hasSib = X86::esp;
+ static const RegisterID noIndex = X86::esp;
+#if PLATFORM(X86_64)
+ static const RegisterID noBase2 = X86::r13;
+ static const RegisterID hasSib2 = X86::r12;
+
+ // Registers r8 & above require a REX prefixe.
+ inline bool regRequiresRex(int reg)
+ {
+ return (reg >= X86::r8);
+ }
+
+ // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
+ inline bool byteRegRequiresRex(int reg)
+ {
+ return (reg >= X86::esp);
+ }
+
+ // Format a REX prefix byte.
+ inline void emitRex(bool w, int r, int x, int b)
+ {
+ m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
+ }
+
+ // Used to plant a REX byte with REX.w set (for 64-bit operations).
+ inline void emitRexW(int r, int x, int b)
+ {
+ emitRex(true, r, x, b);
+ }
+
+ // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
+ // regRequiresRex() to check other registers (i.e. address base & index).
+ inline void emitRexIf(bool condition, int r, int x, int b)
+ {
+ if (condition) emitRex(false, r, x, b);
+ }
+
+ // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
+ inline void emitRexIfNeeded(int r, int x, int b)
+ {
+ emitRexIf(regRequiresRex(r) || regRequiresRex(x) || regRequiresRex(b), r, x, b);
+ }
+#else
+ // No REX prefix bytes on 32-bit x86.
+ inline bool regRequiresRex(int) { return false; }
+ inline bool byteRegRequiresRex(int) { return false; }
+ inline void emitRexIf(bool, int, int, int) {}
+ inline void emitRexIfNeeded(int, int, int) {}
+#endif
+
+ enum ModRmMode {
+ ModRmMemoryNoDisp,
+ ModRmMemoryDisp8,
+ ModRmMemoryDisp32,
+ ModRmRegister,
+ };
+
+ void putModRm(ModRmMode mode, int reg, RegisterID rm)
+ {
+ m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7));
+ }
+
+ void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale)
+ {
+ ASSERT(mode != ModRmRegister);
+
+ // Encode sacle of (1,2,4,8) -> (0,1,2,3)
+ int shift = 0;
+ while (scale >>= 1)
+ shift++;
+
+ putModRm(mode, reg, hasSib);
+ m_buffer.putByteUnchecked((shift << 6) | ((index & 7) << 3) | (base & 7));
+ }
+
+ void registerModRM(int reg, RegisterID rm)
+ {
+ putModRm(ModRmRegister, reg, rm);
+ }
+
+ void memoryModRM(int reg, RegisterID base, int offset)
+ {
+ // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
+#if PLATFORM(X86_64)
+ if ((base == hasSib) || (base == hasSib2)) {
+#else
+ if (base == hasSib) {
+#endif
+ if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
+ putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
+ else if (CAN_SIGN_EXTEND_8_32(offset)) {
+ putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
+ m_buffer.putByteUnchecked(offset);
+ } else {
+ putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
+ m_buffer.putIntUnchecked(offset);
+ }
+ } else {
+#if PLATFORM(X86_64)
+ if (!offset && (base != noBase) && (base != noBase2))
+#else
+ if (!offset && (base != noBase))
+#endif
+ putModRm(ModRmMemoryNoDisp, reg, base);
+ else if (CAN_SIGN_EXTEND_8_32(offset)) {
+ putModRm(ModRmMemoryDisp8, reg, base);
+ m_buffer.putByteUnchecked(offset);
+ } else {
+ putModRm(ModRmMemoryDisp32, reg, base);
+ m_buffer.putIntUnchecked(offset);
+ }
+ }
+ }
+
+ void memoryModRM_disp32(int reg, RegisterID base, int offset)
+ {
+ // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
+#if PLATFORM(X86_64)
+ if ((base == hasSib) || (base == hasSib2)) {
+#else
+ if (base == hasSib) {
+#endif
+ putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
+ m_buffer.putIntUnchecked(offset);
+ } else {
+ putModRm(ModRmMemoryDisp32, reg, base);
+ m_buffer.putIntUnchecked(offset);
+ }
+ }
+
+ void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset)
+ {
+ ASSERT(index != noIndex);
+
+#if PLATFORM(X86_64)
+ if (!offset && (base != noBase) && (base != noBase2))
+#else
+ if (!offset && (base != noBase))
+#endif
+ putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale);
+ else if (CAN_SIGN_EXTEND_8_32(offset)) {
+ putModRmSib(ModRmMemoryDisp8, reg, base, index, scale);
+ m_buffer.putByteUnchecked(offset);
+ } else {
+ putModRmSib(ModRmMemoryDisp32, reg, base, index, scale);
+ m_buffer.putIntUnchecked(offset);
+ }
+ }
+
+#if !PLATFORM(X86_64)
+ void memoryModRM(int reg, void* address)
+ {
+ // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
+ putModRm(ModRmMemoryNoDisp, reg, noBase);
+ m_buffer.putIntUnchecked(reinterpret_cast<int32_t>(address));
+ }
+#endif
+
+ AssemblerBuffer m_buffer;
+ } m_formatter;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER) && PLATFORM(X86)
+
+#endif // X86Assembler_h
diff --git a/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp
new file mode 100644
index 0000000..be060d0
--- /dev/null
+++ b/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -0,0 +1,1686 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CodeBlock.h"
+
+#include "JIT.h"
+#include "JSValue.h"
+#include "Interpreter.h"
+#include "Debugger.h"
+#include "BytecodeGenerator.h"
+#include <stdio.h>
+#include <wtf/StringExtras.h>
+
+#define DUMP_CODE_BLOCK_STATISTICS 0
+
+namespace JSC {
+
+#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
+
+static UString escapeQuotes(const UString& str)
+{
+ UString result = str;
+ int pos = 0;
+ while ((pos = result.find('\"', pos)) >= 0) {
+ result = result.substr(0, pos) + "\"\\\"\"" + result.substr(pos + 1);
+ pos += 4;
+ }
+ return result;
+}
+
+static UString valueToSourceString(ExecState* exec, JSValuePtr val)
+{
+ if (val.isString()) {
+ UString result("\"");
+ result += escapeQuotes(val.toString(exec)) + "\"";
+ return result;
+ }
+
+ return val.toString(exec);
+}
+
+static CString registerName(int r)
+{
+ if (r == missingThisObjectMarker())
+ return "<null>";
+
+ return (UString("r") + UString::from(r)).UTF8String();
+}
+
+static CString constantName(ExecState* exec, int k, JSValuePtr value)
+{
+ return (valueToSourceString(exec, value) + "(@k" + UString::from(k) + ")").UTF8String();
+}
+
+static CString idName(int id0, const Identifier& ident)
+{
+ return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String();
+}
+
+static UString regexpToSourceString(RegExp* regExp)
+{
+ UString pattern = UString("/") + regExp->pattern() + "/";
+ if (regExp->global())
+ pattern += "g";
+ if (regExp->ignoreCase())
+ pattern += "i";
+ if (regExp->multiline())
+ pattern += "m";
+
+ return pattern;
+}
+
+static CString regexpName(int re, RegExp* regexp)
+{
+ return (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
+ snprintf(buffer, sizeof(buffer), "%p", p);
+ return buffer;
+}
+
+NEVER_INLINE static const char* debugHookName(int debugHookID)
+{
+ switch (static_cast<DebugHookID>(debugHookID)) {
+ case DidEnterCallFrame:
+ return "didEnterCallFrame";
+ case WillLeaveCallFrame:
+ return "willLeaveCallFrame";
+ case WillExecuteStatement:
+ return "willExecuteStatement";
+ case WillExecuteProgram:
+ return "willExecuteProgram";
+ case DidExecuteProgram:
+ return "didExecuteProgram";
+ case DidReachBreakpoint:
+ return "didReachBreakpoint";
+ }
+
+ ASSERT_NOT_REACHED();
+ return "";
+}
+
+static int locationForOffset(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int offset)
+{
+ return it - begin + offset;
+}
+
+static void printUnaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op)
+{
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+
+ printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str());
+}
+
+static void printBinaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op)
+{
+ 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
+}
+
+static void printConditionalJump(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int location, const char* op)
+{
+ int r0 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, locationForOffset(begin, it, offset));
+}
+
+static void printGetByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op)
+{
+ 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(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
+ it += 4;
+}
+
+static void printPutByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op)
+{
+ 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(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());
+ it += 4;
+}
+
+#if ENABLE(JIT)
+static bool isGlobalResolve(OpcodeID opcodeID)
+{
+ return opcodeID == op_resolve_global;
+}
+
+static bool isPropertyAccess(OpcodeID opcodeID)
+{
+ switch (opcodeID) {
+ case op_get_by_id_self:
+ case op_get_by_id_proto:
+ case op_get_by_id_chain:
+ case op_get_by_id_self_list:
+ case op_get_by_id_proto_list:
+ case op_put_by_id_transition:
+ case op_put_by_id_replace:
+ case op_get_by_id:
+ case op_put_by_id:
+ case op_get_by_id_generic:
+ case op_put_by_id_generic:
+ case op_get_array_length:
+ case op_get_string_length:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static unsigned instructionOffsetForNth(ExecState* exec, const Vector<Instruction>& instructions, int nth, bool (*predicate)(OpcodeID))
+{
+ size_t i = 0;
+ while (i < instructions.size()) {
+ OpcodeID currentOpcode = exec->interpreter()->getOpcodeID(instructions[i].u.opcode);
+ if (predicate(currentOpcode)) {
+ if (!--nth)
+ return i;
+ }
+ i += opcodeLengths[currentOpcode];
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigned instructionOffset)
+{
+ printf(" [%4d] %s: %s\n", instructionOffset, "resolve_global", pointerToSourceString(resolveInfo.structure).UTF8String().c_str());
+}
+
+static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset)
+{
+ switch (stubInfo.opcodeID) {
+ case op_get_by_id_self:
+ printf(" [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).UTF8String().c_str());
+ return;
+ case op_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());
+ return;
+ case op_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());
+ return;
+ case op_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);
+ return;
+ case op_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);
+ return;
+ case op_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());
+ return;
+ case op_put_by_id_replace:
+ printf(" [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).UTF8String().c_str());
+ return;
+ case op_get_by_id:
+ printf(" [%4d] %s\n", instructionOffset, "get_by_id");
+ return;
+ case op_put_by_id:
+ printf(" [%4d] %s\n", instructionOffset, "put_by_id");
+ return;
+ case op_get_by_id_generic:
+ printf(" [%4d] %s\n", instructionOffset, "op_get_by_id_generic");
+ return;
+ case op_put_by_id_generic:
+ printf(" [%4d] %s\n", instructionOffset, "op_put_by_id_generic");
+ return;
+ case op_get_array_length:
+ printf(" [%4d] %s\n", instructionOffset, "op_get_array_length");
+ return;
+ case op_get_string_length:
+ printf(" [%4d] %s\n", instructionOffset, "op_get_string_length");
+ return;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+#endif
+
+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());
+}
+
+void CodeBlock::printStructures(const Instruction* vPC) const
+{
+ Interpreter* interpreter = m_globalData->interpreter;
+ unsigned instructionOffset = vPC - m_instructions.begin();
+
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id)) {
+ printStructure("get_by_id", vPC, 4);
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
+ printStructure("get_by_id_self", vPC, 4);
+ 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());
+ 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());
+ 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());
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id)) {
+ printStructure("put_by_id", vPC, 4);
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
+ printStructure("put_by_id_replace", vPC, 4);
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global)) {
+ printStructure("resolve_global", vPC, 4);
+ return;
+ }
+
+ // These m_instructions doesn't ref Structures.
+ ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_call) || vPC[0].u.opcode == interpreter->getOpcode(op_call_eval) || vPC[0].u.opcode == interpreter->getOpcode(op_construct));
+}
+
+void CodeBlock::dump(ExecState* exec) const
+{
+ if (m_instructions.isEmpty()) {
+ printf("No instructions available.\n");
+ return;
+ }
+
+ size_t instructionCount = 0;
+
+ for (size_t i = 0; i < m_instructions.size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(m_instructions[i].u.opcode)])
+ ++instructionCount;
+
+ printf("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s)\n\n",
+ static_cast<unsigned long>(instructionCount),
+ static_cast<unsigned long>(m_instructions.size() * sizeof(Instruction)),
+ this, m_numParameters, m_numCalleeRegisters);
+
+ Vector<Instruction>::const_iterator begin = m_instructions.begin();
+ Vector<Instruction>::const_iterator end = m_instructions.end();
+ for (Vector<Instruction>::const_iterator it = begin; it != end; ++it)
+ dump(exec, begin, it);
+
+ if (!m_identifiers.isEmpty()) {
+ printf("\nIdentifiers:\n");
+ size_t i = 0;
+ do {
+ printf(" id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].ascii());
+ ++i;
+ } while (i != m_identifiers.size());
+ }
+
+ if (!m_constantRegisters.isEmpty()) {
+ printf("\nConstants:\n");
+ unsigned registerIndex = m_numVars;
+ size_t i = 0;
+ do {
+ printf(" r%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue(exec)).ascii());
+ ++i;
+ ++registerIndex;
+ } while (i < m_constantRegisters.size());
+ }
+
+ if (m_rareData && !m_rareData->m_unexpectedConstants.isEmpty()) {
+ printf("\nUnexpected Constants:\n");
+ size_t i = 0;
+ do {
+ printf(" k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, m_rareData->m_unexpectedConstants[i]).ascii());
+ ++i;
+ } while (i < m_rareData->m_unexpectedConstants.size());
+ }
+
+ if (m_rareData && !m_rareData->m_regexps.isEmpty()) {
+ printf("\nm_regexps:\n");
+ size_t i = 0;
+ 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");
+
+ if (!m_globalResolveInfos.isEmpty()) {
+ size_t i = 0;
+ do {
+ printGlobalResolveInfo(m_globalResolveInfos[i], instructionOffsetForNth(exec, m_instructions, i + 1, isGlobalResolve));
+ ++i;
+ } while (i < m_globalResolveInfos.size());
+ }
+ if (!m_structureStubInfos.isEmpty()) {
+ size_t i = 0;
+ do {
+ printStructureStubInfo(m_structureStubInfos[i], instructionOffsetForNth(exec, m_instructions, i + 1, isPropertyAccess));
+ ++i;
+ } while (i < m_structureStubInfos.size());
+ }
+#else
+ if (!m_globalResolveInstructions.isEmpty() || !m_propertyAccessInstructions.isEmpty())
+ printf("\nStructures:\n");
+
+ if (!m_globalResolveInstructions.isEmpty()) {
+ size_t i = 0;
+ do {
+ printStructures(&m_instructions[m_globalResolveInstructions[i]]);
+ ++i;
+ } while (i < m_globalResolveInstructions.size());
+ }
+ if (!m_propertyAccessInstructions.isEmpty()) {
+ size_t i = 0;
+ do {
+ printStructures(&m_instructions[m_propertyAccessInstructions[i]]);
+ ++i;
+ } while (i < m_propertyAccessInstructions.size());
+ }
+#endif
+
+ if (m_rareData && !m_rareData->m_exceptionHandlers.isEmpty()) {
+ printf("\nException Handlers:\n");
+ unsigned i = 0;
+ do {
+ printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target);
+ ++i;
+ } while (i < m_rareData->m_exceptionHandlers.size());
+ }
+
+ if (m_rareData && !m_rareData->m_immediateSwitchJumpTables.isEmpty()) {
+ printf("Immediate Switch Jump Tables:\n");
+ unsigned i = 0;
+ do {
+ printf(" %1d = {\n", i);
+ int entry = 0;
+ Vector<int32_t>::const_iterator end = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.end();
+ for (Vector<int32_t>::const_iterator iter = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
+ if (!*iter)
+ continue;
+ printf("\t\t%4d => %04d\n", entry + m_rareData->m_immediateSwitchJumpTables[i].min, *iter);
+ }
+ printf(" }\n");
+ ++i;
+ } while (i < m_rareData->m_immediateSwitchJumpTables.size());
+ }
+
+ if (m_rareData && !m_rareData->m_characterSwitchJumpTables.isEmpty()) {
+ printf("\nCharacter Switch Jump Tables:\n");
+ unsigned i = 0;
+ do {
+ printf(" %1d = {\n", i);
+ int entry = 0;
+ Vector<int32_t>::const_iterator end = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.end();
+ for (Vector<int32_t>::const_iterator iter = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
+ if (!*iter)
+ continue;
+ ASSERT(!((i + m_rareData->m_characterSwitchJumpTables[i].min) & ~0xFFFF));
+ UChar ch = static_cast<UChar>(entry + m_rareData->m_characterSwitchJumpTables[i].min);
+ printf("\t\t\"%s\" => %04d\n", UString(&ch, 1).ascii(), *iter);
+ }
+ printf(" }\n");
+ ++i;
+ } while (i < m_rareData->m_characterSwitchJumpTables.size());
+ }
+
+ if (m_rareData && !m_rareData->m_stringSwitchJumpTables.isEmpty()) {
+ printf("\nString Switch Jump Tables:\n");
+ unsigned i = 0;
+ do {
+ printf(" %1d = {\n", i);
+ StringJumpTable::StringOffsetTable::const_iterator end = m_rareData->m_stringSwitchJumpTables[i].offsetTable.end();
+ for (StringJumpTable::StringOffsetTable::const_iterator iter = m_rareData->m_stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter)
+ printf("\t\t\"%s\" => %04d\n", UString(iter->first).ascii(), iter->second.branchOffset);
+ printf(" }\n");
+ ++i;
+ } while (i < m_rareData->m_stringSwitchJumpTables.size());
+ }
+
+ printf("\n");
+}
+
+void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it) const
+{
+ int location = it - begin;
+ switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
+ case op_enter: {
+ printf("[%4d] enter\n", location);
+ break;
+ }
+ case op_enter_with_activation: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] enter_with_activation %s\n", location, registerName(r0).c_str());
+ break;
+ }
+ case op_create_arguments: {
+ printf("[%4d] create_arguments\n", location);
+ break;
+ }
+ case op_convert_this: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] convert_this %s\n", location, registerName(r0).c_str());
+ break;
+ }
+ case op_unexpected_load: {
+ int r0 = (++it)->u.operand;
+ int k0 = (++it)->u.operand;
+ printf("[%4d] unexpected_load\t %s, %s\n", location, registerName(r0).c_str(), constantName(exec, k0, unexpectedConstant(k0)).c_str());
+ break;
+ }
+ case op_new_object: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] new_object\t %s\n", location, registerName(r0).c_str());
+ 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(dst).c_str(), registerName(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(r0).c_str(), regexpName(re0, regexp(re0)).c_str());
+ break;
+ }
+ case op_mov: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ printf("[%4d] mov\t\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
+ break;
+ }
+ case op_not: {
+ printUnaryOp(location, it, "not");
+ break;
+ }
+ case op_eq: {
+ printBinaryOp(location, it, "eq");
+ break;
+ }
+ case op_eq_null: {
+ printUnaryOp(location, it, "eq_null");
+ break;
+ }
+ case op_neq: {
+ printBinaryOp(location, it, "neq");
+ break;
+ }
+ case op_neq_null: {
+ printUnaryOp(location, it, "neq_null");
+ break;
+ }
+ case op_stricteq: {
+ printBinaryOp(location, it, "stricteq");
+ break;
+ }
+ case op_nstricteq: {
+ printBinaryOp(location, it, "nstricteq");
+ break;
+ }
+ case op_less: {
+ printBinaryOp(location, it, "less");
+ break;
+ }
+ case op_lesseq: {
+ printBinaryOp(location, it, "lesseq");
+ break;
+ }
+ case op_pre_inc: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] pre_inc\t\t %s\n", location, registerName(r0).c_str());
+ break;
+ }
+ case op_pre_dec: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] pre_dec\t\t %s\n", location, registerName(r0).c_str());
+ break;
+ }
+ case op_post_inc: {
+ printUnaryOp(location, it, "post_inc");
+ break;
+ }
+ case op_post_dec: {
+ printUnaryOp(location, it, "post_dec");
+ break;
+ }
+ case op_to_jsnumber: {
+ printUnaryOp(location, it, "to_jsnumber");
+ break;
+ }
+ case op_negate: {
+ printUnaryOp(location, it, "negate");
+ break;
+ }
+ case op_add: {
+ printBinaryOp(location, it, "add");
+ ++it;
+ break;
+ }
+ case op_mul: {
+ printBinaryOp(location, it, "mul");
+ ++it;
+ break;
+ }
+ case op_div: {
+ printBinaryOp(location, it, "div");
+ break;
+ }
+ case op_mod: {
+ printBinaryOp(location, it, "mod");
+ break;
+ }
+ case op_sub: {
+ printBinaryOp(location, it, "sub");
+ ++it;
+ break;
+ }
+ case op_lshift: {
+ printBinaryOp(location, it, "lshift");
+ break;
+ }
+ case op_rshift: {
+ printBinaryOp(location, it, "rshift");
+ break;
+ }
+ case op_urshift: {
+ printBinaryOp(location, it, "urshift");
+ break;
+ }
+ case op_bitand: {
+ printBinaryOp(location, it, "bitand");
+ ++it;
+ break;
+ }
+ case op_bitxor: {
+ printBinaryOp(location, it, "bitxor");
+ ++it;
+ break;
+ }
+ case op_bitor: {
+ printBinaryOp(location, it, "bitor");
+ ++it;
+ break;
+ }
+ case op_bitnot: {
+ printUnaryOp(location, it, "bitnot");
+ break;
+ }
+ case op_instanceof: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int r2 = (++it)->u.operand;
+ int r3 = (++it)->u.operand;
+ printf("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str());
+ break;
+ }
+ case op_typeof: {
+ printUnaryOp(location, it, "typeof");
+ break;
+ }
+ case op_is_undefined: {
+ printUnaryOp(location, it, "is_undefined");
+ break;
+ }
+ case op_is_boolean: {
+ printUnaryOp(location, it, "is_boolean");
+ break;
+ }
+ case op_is_number: {
+ printUnaryOp(location, it, "is_number");
+ break;
+ }
+ case op_is_string: {
+ printUnaryOp(location, it, "is_string");
+ break;
+ }
+ case op_is_object: {
+ printUnaryOp(location, it, "is_object");
+ break;
+ }
+ case op_is_function: {
+ printUnaryOp(location, it, "is_function");
+ break;
+ }
+ case op_in: {
+ printBinaryOp(location, it, "in");
+ break;
+ }
+ case op_resolve: {
+ int r0 = (++it)->u.operand;
+ int id0 = (++it)->u.operand;
+ printf("[%4d] resolve\t\t %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str());
+ 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(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), skipLevels);
+ break;
+ }
+ case op_resolve_global: {
+ int r0 = (++it)->u.operand;
+ JSValuePtr scope = JSValuePtr((++it)->u.jsCell);
+ int id0 = (++it)->u.operand;
+ printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).c_str());
+ it += 2;
+ break;
+ }
+ case op_get_scoped_var: {
+ int r0 = (++it)->u.operand;
+ int index = (++it)->u.operand;
+ int skipLevels = (++it)->u.operand;
+ printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(r0).c_str(), 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(r0).c_str());
+ break;
+ }
+ case op_get_global_var: {
+ int r0 = (++it)->u.operand;
+ JSValuePtr scope = JSValuePtr((++it)->u.jsCell);
+ int index = (++it)->u.operand;
+ printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), index);
+ break;
+ }
+ case op_put_global_var: {
+ JSValuePtr scope = JSValuePtr((++it)->u.jsCell);
+ int index = (++it)->u.operand;
+ int r0 = (++it)->u.operand;
+ printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(r0).c_str());
+ 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(r0).c_str(), idName(id0, m_identifiers[id0]).c_str());
+ 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(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
+ break;
+ }
+ case op_resolve_func: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int id0 = (++it)->u.operand;
+ printf("[%4d] resolve_func\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
+ break;
+ }
+ case op_get_by_id: {
+ printGetByIdOp(location, it, m_identifiers, "get_by_id");
+ break;
+ }
+ case op_get_by_id_self: {
+ printGetByIdOp(location, it, m_identifiers, "get_by_id_self");
+ break;
+ }
+ case op_get_by_id_self_list: {
+ printGetByIdOp(location, it, m_identifiers, "get_by_id_self_list");
+ break;
+ }
+ case op_get_by_id_proto: {
+ printGetByIdOp(location, it, m_identifiers, "get_by_id_proto");
+ break;
+ }
+ case op_get_by_id_proto_list: {
+ printGetByIdOp(location, it, m_identifiers, "op_get_by_id_proto_list");
+ break;
+ }
+ case op_get_by_id_chain: {
+ printGetByIdOp(location, it, m_identifiers, "get_by_id_chain");
+ break;
+ }
+ case op_get_by_id_generic: {
+ printGetByIdOp(location, it, m_identifiers, "get_by_id_generic");
+ break;
+ }
+ case op_get_array_length: {
+ printGetByIdOp(location, it, m_identifiers, "get_array_length");
+ break;
+ }
+ case op_get_string_length: {
+ printGetByIdOp(location, it, m_identifiers, "get_string_length");
+ break;
+ }
+ case op_put_by_id: {
+ printPutByIdOp(location, it, m_identifiers, "put_by_id");
+ break;
+ }
+ case op_put_by_id_replace: {
+ printPutByIdOp(location, it, m_identifiers, "put_by_id_replace");
+ break;
+ }
+ case op_put_by_id_transition: {
+ printPutByIdOp(location, it, m_identifiers, "put_by_id_transition");
+ break;
+ }
+ case op_put_by_id_generic: {
+ printPutByIdOp(location, it, m_identifiers, "put_by_id_generic");
+ break;
+ }
+ case op_put_getter: {
+ 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(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());
+ 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(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());
+ break;
+ }
+ case op_del_by_id: {
+ 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(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
+ 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
+ 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
+ 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
+ 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(r0).c_str(), n0, registerName(r1).c_str());
+ break;
+ }
+ case op_jmp: {
+ int offset = (++it)->u.operand;
+ printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset));
+ break;
+ }
+ case op_loop: {
+ int offset = (++it)->u.operand;
+ printf("[%4d] loop\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset));
+ break;
+ }
+ case op_jtrue: {
+ printConditionalJump(begin, it, location, "jtrue");
+ break;
+ }
+ case op_loop_if_true: {
+ printConditionalJump(begin, it, location, "loop_if_true");
+ break;
+ }
+ case op_jfalse: {
+ printConditionalJump(begin, it, location, "jfalse");
+ break;
+ }
+ case op_jeq_null: {
+ printConditionalJump(begin, it, location, "jeq_null");
+ break;
+ }
+ case op_jneq_null: {
+ printConditionalJump(begin, it, location, "jneq_null");
+ 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(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+ break;
+ }
+ case op_loop_if_less: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+ break;
+ }
+ case op_loop_if_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(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, 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, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
+ 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, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
+ 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, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
+ 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(r0).c_str(), 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(r0).c_str(), f0);
+ break;
+ }
+ case op_call: {
+ int dst = (++it)->u.operand;
+ int func = (++it)->u.operand;
+ int argCount = (++it)->u.operand;
+ int registerOffset = (++it)->u.operand;
+ printf("[%4d] call\t\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset);
+ break;
+ }
+ case op_call_eval: {
+ int dst = (++it)->u.operand;
+ int func = (++it)->u.operand;
+ int argCount = (++it)->u.operand;
+ int registerOffset = (++it)->u.operand;
+ printf("[%4d] call_eval\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset);
+ break;
+ }
+ case op_tear_off_activation: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] tear_off_activation\t %s\n", location, registerName(r0).c_str());
+ break;
+ }
+ case op_tear_off_arguments: {
+ printf("[%4d] tear_off_arguments\n", location);
+ break;
+ }
+ case op_ret: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] ret\t\t %s\n", location, registerName(r0).c_str());
+ break;
+ }
+ case op_construct: {
+ int dst = (++it)->u.operand;
+ int func = (++it)->u.operand;
+ int argCount = (++it)->u.operand;
+ int registerOffset = (++it)->u.operand;
+ int proto = (++it)->u.operand;
+ int thisRegister = (++it)->u.operand;
+ printf("[%4d] construct\t %s, %s, %d, %d, %s, %s\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset, registerName(proto).c_str(), registerName(thisRegister).c_str());
+ 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(r0).c_str(), registerName(r1).c_str());
+ break;
+ }
+ case op_get_pnames: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ printf("[%4d] get_pnames\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
+ break;
+ }
+ case op_next_pname: {
+ int dest = (++it)->u.operand;
+ int iter = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, locationForOffset(begin, it, offset));
+ break;
+ }
+ case op_push_scope: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] push_scope\t %s\n", location, registerName(r0).c_str());
+ break;
+ }
+ case op_pop_scope: {
+ printf("[%4d] pop_scope\n", location);
+ break;
+ }
+ case op_push_new_scope: {
+ 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(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());
+ break;
+ }
+ case op_jmp_scopes: {
+ int scopeDelta = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, locationForOffset(begin, it, offset));
+ break;
+ }
+ case op_catch: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] catch\t\t %s\n", location, registerName(r0).c_str());
+ break;
+ }
+ case op_throw: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] throw\t\t %s\n", location, registerName(r0).c_str());
+ 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(r0).c_str(), errorType, constantName(exec, k0, unexpectedConstant(k0)).c_str());
+ 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(retAddrDst).c_str(), offset, locationForOffset(begin, it, offset));
+ break;
+ }
+ case op_sret: {
+ int retAddrSrc = (++it)->u.operand;
+ printf("[%4d] sret\t\t %s\n", location, registerName(retAddrSrc).c_str());
+ break;
+ }
+ case op_debug: {
+ int debugHookID = (++it)->u.operand;
+ int firstLine = (++it)->u.operand;
+ int lastLine = (++it)->u.operand;
+ printf("[%4d] debug\t\t %s, %d, %d\n", location, debugHookName(debugHookID), firstLine, lastLine);
+ break;
+ }
+ case op_profile_will_call: {
+ int function = (++it)->u.operand;
+ printf("[%4d] profile_will_call %s\n", location, registerName(function).c_str());
+ break;
+ }
+ case op_profile_did_call: {
+ int function = (++it)->u.operand;
+ printf("[%4d] profile_did_call\t %s\n", location, registerName(function).c_str());
+ break;
+ }
+ case op_end: {
+ int r0 = (++it)->u.operand;
+ printf("[%4d] end\t\t %s\n", location, registerName(r0).c_str());
+ break;
+ }
+ }
+}
+
+#endif // !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
+
+#if DUMP_CODE_BLOCK_STATISTICS
+static HashSet<CodeBlock*> liveCodeBlockSet;
+#endif
+
+#define FOR_EACH_MEMBER_VECTOR(macro) \
+ macro(instructions) \
+ macro(globalResolveInfos) \
+ macro(structureStubInfos) \
+ macro(callLinkInfos) \
+ macro(linkedCallerList) \
+ macro(identifiers) \
+ macro(functionExpressions) \
+ macro(constantRegisters)
+
+#define FOR_EACH_MEMBER_VECTOR_RARE_DATA(macro) \
+ macro(regexps) \
+ macro(functions) \
+ macro(unexpectedConstants) \
+ macro(exceptionHandlers) \
+ macro(immediateSwitchJumpTables) \
+ macro(characterSwitchJumpTables) \
+ macro(stringSwitchJumpTables) \
+ macro(functionRegisterInfos)
+
+#define FOR_EACH_MEMBER_VECTOR_EXCEPTION_INFO(macro) \
+ macro(expressionInfo) \
+ macro(lineInfo) \
+ macro(getByIdExceptionInfo) \
+ macro(pcVector)
+
+template<typename T>
+static size_t sizeInBytes(const Vector<T>& vector)
+{
+ return vector.capacity() * sizeof(T);
+}
+
+void CodeBlock::dumpStatistics()
+{
+#if DUMP_CODE_BLOCK_STATISTICS
+ #define DEFINE_VARS(name) size_t name##IsNotEmpty = 0; size_t name##TotalSize = 0;
+ FOR_EACH_MEMBER_VECTOR(DEFINE_VARS)
+ FOR_EACH_MEMBER_VECTOR_RARE_DATA(DEFINE_VARS)
+ FOR_EACH_MEMBER_VECTOR_EXCEPTION_INFO(DEFINE_VARS)
+ #undef DEFINE_VARS
+
+ // Non-vector data members
+ size_t evalCodeCacheIsNotEmpty = 0;
+
+ size_t symbolTableIsNotEmpty = 0;
+ size_t symbolTableTotalSize = 0;
+
+ size_t hasExceptionInfo = 0;
+ size_t hasRareData = 0;
+
+ size_t isFunctionCode = 0;
+ size_t isGlobalCode = 0;
+ size_t isEvalCode = 0;
+
+ HashSet<CodeBlock*>::const_iterator end = liveCodeBlockSet.end();
+ for (HashSet<CodeBlock*>::const_iterator it = liveCodeBlockSet.begin(); it != end; ++it) {
+ CodeBlock* codeBlock = *it;
+
+ #define GET_STATS(name) if (!codeBlock->m_##name.isEmpty()) { name##IsNotEmpty++; name##TotalSize += sizeInBytes(codeBlock->m_##name); }
+ FOR_EACH_MEMBER_VECTOR(GET_STATS)
+ #undef GET_STATS
+
+ if (!codeBlock->m_symbolTable.isEmpty()) {
+ symbolTableIsNotEmpty++;
+ symbolTableTotalSize += (codeBlock->m_symbolTable.capacity() * (sizeof(SymbolTable::KeyType) + sizeof(SymbolTable::MappedType)));
+ }
+
+ if (codeBlock->m_exceptionInfo) {
+ hasExceptionInfo++;
+ #define GET_STATS(name) if (!codeBlock->m_exceptionInfo->m_##name.isEmpty()) { name##IsNotEmpty++; name##TotalSize += sizeInBytes(codeBlock->m_exceptionInfo->m_##name); }
+ FOR_EACH_MEMBER_VECTOR_EXCEPTION_INFO(GET_STATS)
+ #undef GET_STATS
+ }
+
+ if (codeBlock->m_rareData) {
+ hasRareData++;
+ #define GET_STATS(name) if (!codeBlock->m_rareData->m_##name.isEmpty()) { name##IsNotEmpty++; name##TotalSize += sizeInBytes(codeBlock->m_rareData->m_##name); }
+ FOR_EACH_MEMBER_VECTOR_RARE_DATA(GET_STATS)
+ #undef GET_STATS
+
+ if (!codeBlock->m_rareData->m_evalCodeCache.isEmpty())
+ evalCodeCacheIsNotEmpty++;
+ }
+
+ switch (codeBlock->codeType()) {
+ case FunctionCode:
+ ++isFunctionCode;
+ break;
+ case GlobalCode:
+ ++isGlobalCode;
+ break;
+ case EvalCode:
+ ++isEvalCode;
+ break;
+ }
+ }
+
+ size_t totalSize = 0;
+
+ #define GET_TOTAL_SIZE(name) totalSize += name##TotalSize;
+ FOR_EACH_MEMBER_VECTOR(GET_TOTAL_SIZE)
+ FOR_EACH_MEMBER_VECTOR_RARE_DATA(GET_TOTAL_SIZE)
+ FOR_EACH_MEMBER_VECTOR_EXCEPTION_INFO(GET_TOTAL_SIZE)
+ #undef GET_TOTAL_SIZE
+
+ totalSize += symbolTableTotalSize;
+ totalSize += (liveCodeBlockSet.size() * sizeof(CodeBlock));
+
+ printf("Number of live CodeBlocks: %d\n", liveCodeBlockSet.size());
+ printf("Size of a single CodeBlock [sizeof(CodeBlock)]: %zu\n", sizeof(CodeBlock));
+ printf("Size of all CodeBlocks: %zu\n", totalSize);
+ printf("Average size of a CodeBlock: %zu\n", totalSize / liveCodeBlockSet.size());
+
+ printf("Number of FunctionCode CodeBlocks: %zu (%.3f%%)\n", isFunctionCode, static_cast<double>(isFunctionCode) * 100.0 / liveCodeBlockSet.size());
+ printf("Number of GlobalCode CodeBlocks: %zu (%.3f%%)\n", isGlobalCode, static_cast<double>(isGlobalCode) * 100.0 / liveCodeBlockSet.size());
+ printf("Number of EvalCode CodeBlocks: %zu (%.3f%%)\n", isEvalCode, static_cast<double>(isEvalCode) * 100.0 / liveCodeBlockSet.size());
+
+ printf("Number of CodeBlocks with exception info: %zu (%.3f%%)\n", hasExceptionInfo, static_cast<double>(hasExceptionInfo) * 100.0 / liveCodeBlockSet.size());
+ printf("Number of CodeBlocks with rare data: %zu (%.3f%%)\n", hasRareData, static_cast<double>(hasRareData) * 100.0 / liveCodeBlockSet.size());
+
+ #define PRINT_STATS(name) printf("Number of CodeBlocks with " #name ": %zu\n", name##IsNotEmpty); printf("Size of all " #name ": %zu\n", name##TotalSize);
+ FOR_EACH_MEMBER_VECTOR(PRINT_STATS)
+ FOR_EACH_MEMBER_VECTOR_RARE_DATA(PRINT_STATS)
+ FOR_EACH_MEMBER_VECTOR_EXCEPTION_INFO(PRINT_STATS)
+ #undef PRINT_STATS
+
+ printf("Number of CodeBlocks with evalCodeCache: %zu\n", evalCodeCacheIsNotEmpty);
+ printf("Number of CodeBlocks with symbolTable: %zu\n", symbolTableIsNotEmpty);
+
+ printf("Size of all symbolTables: %zu\n", symbolTableTotalSize);
+
+#else
+ printf("Dumping CodeBlock statistics is not enabled.\n");
+#endif
+}
+
+
+CodeBlock::CodeBlock(ScopeNode* ownerNode, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset)
+ : m_numCalleeRegisters(0)
+ , m_numConstants(0)
+ , m_numVars(0)
+ , m_numParameters(0)
+ , m_ownerNode(ownerNode)
+ , m_globalData(0)
+#ifndef NDEBUG
+ , m_instructionCount(0)
+#endif
+ , m_needsFullScopeChain(ownerNode->needsActivation())
+ , m_usesEval(ownerNode->usesEval())
+ , m_isNumericCompareFunction(false)
+ , m_codeType(codeType)
+ , m_source(sourceProvider)
+ , m_sourceOffset(sourceOffset)
+ , m_exceptionInfo(new ExceptionInfo)
+{
+ ASSERT(m_source);
+
+#if DUMP_CODE_BLOCK_STATISTICS
+ liveCodeBlockSet.add(this);
+#endif
+}
+
+CodeBlock::~CodeBlock()
+{
+#if !ENABLE(JIT)
+ for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
+ derefStructures(&m_instructions[m_globalResolveInstructions[i]]);
+
+ for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
+ derefStructures(&m_instructions[m_propertyAccessInstructions[i]]);
+#else
+ for (size_t size = m_globalResolveInfos.size(), i = 0; i < size; ++i) {
+ if (m_globalResolveInfos[i].structure)
+ m_globalResolveInfos[i].structure->deref();
+ }
+
+ for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i)
+ m_structureStubInfos[i].deref();
+
+ for (size_t size = m_callLinkInfos.size(), i = 0; i < size; ++i) {
+ CallLinkInfo* callLinkInfo = &m_callLinkInfos[i];
+ if (callLinkInfo->isLinked())
+ callLinkInfo->callee->removeCaller(callLinkInfo);
+ }
+
+ unlinkCallers();
+#endif
+
+#if DUMP_CODE_BLOCK_STATISTICS
+ liveCodeBlockSet.remove(this);
+#endif
+}
+
+#if ENABLE(JIT)
+void CodeBlock::unlinkCallers()
+{
+ size_t size = m_linkedCallerList.size();
+ for (size_t i = 0; i < size; ++i) {
+ CallLinkInfo* currentCaller = m_linkedCallerList[i];
+ JIT::unlinkCall(currentCaller);
+ currentCaller->setUnlinked();
+ }
+ m_linkedCallerList.clear();
+}
+#endif
+
+void CodeBlock::derefStructures(Instruction* vPC) const
+{
+ Interpreter* interpreter = m_globalData->interpreter;
+
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
+ vPC[4].u.structure->deref();
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
+ vPC[4].u.structure->deref();
+ vPC[5].u.structure->deref();
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
+ vPC[4].u.structure->deref();
+ vPC[5].u.structureChain->deref();
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
+ vPC[4].u.structure->deref();
+ vPC[5].u.structure->deref();
+ vPC[6].u.structureChain->deref();
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
+ vPC[4].u.structure->deref();
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global)) {
+ if(vPC[4].u.structure)
+ vPC[4].u.structure->deref();
+ return;
+ }
+ if ((vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto_list))
+ || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self_list))) {
+ PolymorphicAccessStructureList* polymorphicStructures = vPC[4].u.polymorphicStructures;
+ polymorphicStructures->derefStructures(vPC[5].u.operand);
+ delete polymorphicStructures;
+ return;
+ }
+
+ // These instructions don't ref their Structures.
+ ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_get_array_length) || vPC[0].u.opcode == interpreter->getOpcode(op_get_string_length));
+}
+
+void CodeBlock::refStructures(Instruction* vPC) const
+{
+ Interpreter* interpreter = m_globalData->interpreter;
+
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
+ vPC[4].u.structure->ref();
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
+ vPC[4].u.structure->ref();
+ vPC[5].u.structure->ref();
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
+ vPC[4].u.structure->ref();
+ vPC[5].u.structureChain->ref();
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
+ vPC[4].u.structure->ref();
+ vPC[5].u.structure->ref();
+ vPC[6].u.structureChain->ref();
+ return;
+ }
+ if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
+ vPC[4].u.structure->ref();
+ return;
+ }
+
+ // These instructions don't ref their Structures.
+ ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic));
+}
+
+void CodeBlock::mark()
+{
+ for (size_t i = 0; i < m_constantRegisters.size(); ++i)
+ if (!m_constantRegisters[i].marked())
+ m_constantRegisters[i].mark();
+
+ for (size_t i = 0; i < m_functionExpressions.size(); ++i)
+ m_functionExpressions[i]->body()->mark();
+
+ if (m_rareData) {
+ for (size_t i = 0; i < m_rareData->m_functions.size(); ++i)
+ m_rareData->m_functions[i]->body()->mark();
+
+ for (size_t i = 0; i < m_rareData->m_unexpectedConstants.size(); ++i) {
+ if (!m_rareData->m_unexpectedConstants[i].marked())
+ m_rareData->m_unexpectedConstants[i].mark();
+ }
+ m_rareData->m_evalCodeCache.mark();
+ }
+}
+
+void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
+{
+ if (m_exceptionInfo)
+ return;
+
+ ScopeChainNode* scopeChain = callFrame->scopeChain();
+ if (m_needsFullScopeChain) {
+ ScopeChain sc(scopeChain);
+ int scopeDelta = sc.localDepth();
+ if (m_codeType == EvalCode)
+ scopeDelta -= static_cast<EvalCodeBlock*>(this)->baseScopeDepth();
+ else if (m_codeType == FunctionCode)
+ scopeDelta++; // Compilation of function code assumes activation is not on the scope chain yet.
+ ASSERT(scopeDelta >= 0);
+ while (scopeDelta--)
+ scopeChain = scopeChain->next;
+ }
+
+ switch (m_codeType) {
+ case FunctionCode: {
+ FunctionBodyNode* ownerFunctionBodyNode = static_cast<FunctionBodyNode*>(m_ownerNode);
+ RefPtr<FunctionBodyNode> newFunctionBody = m_globalData->parser->reparse<FunctionBodyNode>(m_globalData, ownerFunctionBodyNode);
+ ASSERT(newFunctionBody);
+ newFunctionBody->finishParsing(ownerFunctionBodyNode->copyParameters(), ownerFunctionBodyNode->parameterCount());
+
+ m_globalData->scopeNodeBeingReparsed = newFunctionBody.get();
+
+ CodeBlock& newCodeBlock = newFunctionBody->bytecodeForExceptionInfoReparse(scopeChain, this);
+ ASSERT(newCodeBlock.m_exceptionInfo);
+ ASSERT(newCodeBlock.m_instructionCount == m_instructionCount);
+
+#if ENABLE(JIT)
+ JIT::compile(m_globalData, &newCodeBlock);
+ ASSERT(newCodeBlock.m_jitCode.codeSize == m_jitCode.codeSize);
+#endif
+
+ m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release());
+
+ m_globalData->scopeNodeBeingReparsed = 0;
+
+ break;
+ }
+ case EvalCode: {
+ EvalNode* ownerEvalNode = static_cast<EvalNode*>(m_ownerNode);
+ RefPtr<EvalNode> newEvalBody = m_globalData->parser->reparse<EvalNode>(m_globalData, ownerEvalNode);
+
+ m_globalData->scopeNodeBeingReparsed = newEvalBody.get();
+
+ EvalCodeBlock& newCodeBlock = newEvalBody->bytecodeForExceptionInfoReparse(scopeChain, this);
+ ASSERT(newCodeBlock.m_exceptionInfo);
+ ASSERT(newCodeBlock.m_instructionCount == m_instructionCount);
+
+#if ENABLE(JIT)
+ JIT::compile(m_globalData, &newCodeBlock);
+ ASSERT(newCodeBlock.m_jitCode.codeSize == m_jitCode.codeSize);
+#endif
+
+ m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release());
+
+ m_globalData->scopeNodeBeingReparsed = 0;
+
+ break;
+ }
+ default:
+ // CodeBlocks for Global code blocks are transient and therefore to not gain from
+ // from throwing out there exception information.
+ ASSERT_NOT_REACHED();
+ }
+}
+
+HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
+{
+ ASSERT(bytecodeOffset < m_instructionCount);
+
+ if (!m_rareData)
+ return 0;
+
+ Vector<HandlerInfo>& exceptionHandlers = m_rareData->m_exceptionHandlers;
+ for (size_t i = 0; i < exceptionHandlers.size(); ++i) {
+ // Handlers are ordered innermost first, so the first handler we encounter
+ // that contains the source address is the correct handler to use.
+ if (exceptionHandlers[i].start <= bytecodeOffset && exceptionHandlers[i].end >= bytecodeOffset)
+ return &exceptionHandlers[i];
+ }
+
+ return 0;
+}
+
+int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset)
+{
+ ASSERT(bytecodeOffset < m_instructionCount);
+
+ reparseForExceptionInfoIfNecessary(callFrame);
+ ASSERT(m_exceptionInfo);
+
+ if (!m_exceptionInfo->m_lineInfo.size())
+ return m_ownerNode->source().firstLine(); // Empty function
+
+ int low = 0;
+ int high = m_exceptionInfo->m_lineInfo.size();
+ while (low < high) {
+ int mid = low + (high - low) / 2;
+ if (m_exceptionInfo->m_lineInfo[mid].instructionOffset <= bytecodeOffset)
+ low = mid + 1;
+ else
+ high = mid;
+ }
+
+ if (!low)
+ return m_ownerNode->source().firstLine();
+ return m_exceptionInfo->m_lineInfo[low - 1].lineNumber;
+}
+
+int CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
+{
+ ASSERT(bytecodeOffset < m_instructionCount);
+
+ reparseForExceptionInfoIfNecessary(callFrame);
+ ASSERT(m_exceptionInfo);
+
+ if (!m_exceptionInfo->m_expressionInfo.size()) {
+ // We didn't think anything could throw. Apparently we were wrong.
+ startOffset = 0;
+ endOffset = 0;
+ divot = 0;
+ return lineNumberForBytecodeOffset(callFrame, bytecodeOffset);
+ }
+
+ int low = 0;
+ int high = m_exceptionInfo->m_expressionInfo.size();
+ while (low < high) {
+ int mid = low + (high - low) / 2;
+ if (m_exceptionInfo->m_expressionInfo[mid].instructionOffset <= bytecodeOffset)
+ low = mid + 1;
+ else
+ high = mid;
+ }
+
+ ASSERT(low);
+ if (!low) {
+ startOffset = 0;
+ endOffset = 0;
+ divot = 0;
+ return lineNumberForBytecodeOffset(callFrame, bytecodeOffset);
+ }
+
+ startOffset = m_exceptionInfo->m_expressionInfo[low - 1].startOffset;
+ endOffset = m_exceptionInfo->m_expressionInfo[low - 1].endOffset;
+ divot = m_exceptionInfo->m_expressionInfo[low - 1].divotPoint + m_sourceOffset;
+ return lineNumberForBytecodeOffset(callFrame, bytecodeOffset);
+}
+
+bool CodeBlock::getByIdExceptionInfoForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, OpcodeID& opcodeID)
+{
+ ASSERT(bytecodeOffset < m_instructionCount);
+
+ reparseForExceptionInfoIfNecessary(callFrame);
+ ASSERT(m_exceptionInfo);
+
+ if (!m_exceptionInfo->m_getByIdExceptionInfo.size())
+ return false;
+
+ int low = 0;
+ int high = m_exceptionInfo->m_getByIdExceptionInfo.size();
+ while (low < high) {
+ int mid = low + (high - low) / 2;
+ if (m_exceptionInfo->m_getByIdExceptionInfo[mid].bytecodeOffset <= bytecodeOffset)
+ low = mid + 1;
+ else
+ high = mid;
+ }
+
+ if (!low || m_exceptionInfo->m_getByIdExceptionInfo[low - 1].bytecodeOffset != bytecodeOffset)
+ return false;
+
+ opcodeID = m_exceptionInfo->m_getByIdExceptionInfo[low - 1].isOpConstruct ? op_construct : op_instanceof;
+ return true;
+}
+
+#if ENABLE(JIT)
+bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex)
+{
+ ASSERT(bytecodeOffset < m_instructionCount);
+
+ if (!m_rareData || !m_rareData->m_functionRegisterInfos.size())
+ return false;
+
+ int low = 0;
+ int high = m_rareData->m_functionRegisterInfos.size();
+ while (low < high) {
+ int mid = low + (high - low) / 2;
+ if (m_rareData->m_functionRegisterInfos[mid].bytecodeOffset <= bytecodeOffset)
+ low = mid + 1;
+ else
+ high = mid;
+ }
+
+ if (!low || m_rareData->m_functionRegisterInfos[low - 1].bytecodeOffset != bytecodeOffset)
+ return false;
+
+ functionRegisterIndex = m_rareData->m_functionRegisterInfos[low - 1].functionRegisterIndex;
+ return true;
+}
+#endif
+
+#if !ENABLE(JIT)
+bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset)
+{
+ if (m_globalResolveInstructions.isEmpty())
+ return false;
+
+ int low = 0;
+ int high = m_globalResolveInstructions.size();
+ while (low < high) {
+ int mid = low + (high - low) / 2;
+ if (m_globalResolveInstructions[mid] <= bytecodeOffset)
+ low = mid + 1;
+ else
+ high = mid;
+ }
+
+ if (!low || m_globalResolveInstructions[low - 1] != bytecodeOffset)
+ return false;
+ return true;
+}
+#else
+bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
+{
+ if (m_globalResolveInfos.isEmpty())
+ return false;
+
+ int low = 0;
+ int high = m_globalResolveInfos.size();
+ while (low < high) {
+ int mid = low + (high - low) / 2;
+ if (m_globalResolveInfos[mid].bytecodeOffset <= bytecodeOffset)
+ low = mid + 1;
+ else
+ high = mid;
+ }
+
+ if (!low || m_globalResolveInfos[low - 1].bytecodeOffset != bytecodeOffset)
+ return false;
+ return true;
+}
+#endif
+
+#if ENABLE(JIT)
+void CodeBlock::setJITCode(JITCodeRef& jitCode)
+{
+ m_jitCode = jitCode;
+#if !ENABLE(OPCODE_SAMPLING)
+ if (!BytecodeGenerator::dumpsGeneratedCode())
+ m_instructions.clear();
+#endif
+}
+#endif
+
+void CodeBlock::shrinkToFit()
+{
+ m_instructions.shrinkToFit();
+
+#if !ENABLE(JIT)
+ m_propertyAccessInstructions.shrinkToFit();
+ m_globalResolveInstructions.shrinkToFit();
+#else
+ m_structureStubInfos.shrinkToFit();
+ m_globalResolveInfos.shrinkToFit();
+ m_callLinkInfos.shrinkToFit();
+ m_linkedCallerList.shrinkToFit();
+#endif
+
+ m_identifiers.shrinkToFit();
+ m_functionExpressions.shrinkToFit();
+ m_constantRegisters.shrinkToFit();
+
+ if (m_exceptionInfo) {
+ m_exceptionInfo->m_expressionInfo.shrinkToFit();
+ m_exceptionInfo->m_lineInfo.shrinkToFit();
+ m_exceptionInfo->m_getByIdExceptionInfo.shrinkToFit();
+ }
+
+ if (m_rareData) {
+ m_rareData->m_exceptionHandlers.shrinkToFit();
+ m_rareData->m_functions.shrinkToFit();
+ m_rareData->m_unexpectedConstants.shrinkToFit();
+ m_rareData->m_regexps.shrinkToFit();
+ m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
+ m_rareData->m_characterSwitchJumpTables.shrinkToFit();
+ m_rareData->m_stringSwitchJumpTables.shrinkToFit();
+#if ENABLE(JIT)
+ m_rareData->m_functionRegisterInfos.shrinkToFit();
+#endif
+ }
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/bytecode/CodeBlock.h b/JavaScriptCore/bytecode/CodeBlock.h
new file mode 100644
index 0000000..e5d78d3
--- /dev/null
+++ b/JavaScriptCore/bytecode/CodeBlock.h
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CodeBlock_h
+#define CodeBlock_h
+
+#include "EvalCodeCache.h"
+#include "Instruction.h"
+#include "JSGlobalObject.h"
+#include "JumpTable.h"
+#include "Nodes.h"
+#include "RegExp.h"
+#include "UString.h"
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+#if ENABLE(JIT)
+#include "StructureStubInfo.h"
+#endif
+
+namespace JSC {
+
+ class ExecState;
+
+ enum CodeType { GlobalCode, EvalCode, FunctionCode };
+
+ static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); }
+
+ struct HandlerInfo {
+ uint32_t start;
+ uint32_t end;
+ uint32_t target;
+ uint32_t scopeDepth;
+#if ENABLE(JIT)
+ void* nativeCode;
+#endif
+ };
+
+#if ENABLE(JIT)
+ // The code, and the associated pool from which it was allocated.
+ struct JITCodeRef {
+ void* code;
+#ifndef NDEBUG
+ unsigned codeSize;
+#endif
+ RefPtr<ExecutablePool> executablePool;
+
+ JITCodeRef()
+ : code(0)
+#ifndef NDEBUG
+ , codeSize(0)
+#endif
+ {
+ }
+
+ JITCodeRef(void* code, PassRefPtr<ExecutablePool> executablePool)
+ : code(code)
+#ifndef NDEBUG
+ , codeSize(0)
+#endif
+ , executablePool(executablePool)
+ {
+ }
+ };
+#endif
+
+ struct ExpressionRangeInfo {
+ enum {
+ MaxOffset = (1 << 7) - 1,
+ MaxDivot = (1 << 25) - 1
+ };
+ uint32_t instructionOffset : 25;
+ uint32_t divotPoint : 25;
+ uint32_t startOffset : 7;
+ uint32_t endOffset : 7;
+ };
+
+ struct LineInfo {
+ uint32_t instructionOffset;
+ int32_t lineNumber;
+ };
+
+ // Both op_construct and op_instanceof require a use of op_get_by_id to get
+ // the prototype property from an object. The exception messages for exceptions
+ // thrown by these instances op_get_by_id need to reflect this.
+ struct GetByIdExceptionInfo {
+ unsigned bytecodeOffset : 31;
+ bool isOpConstruct : 1;
+ };
+
+#if ENABLE(JIT)
+ struct CallLinkInfo {
+ CallLinkInfo()
+ : callReturnLocation(0)
+ , hotPathBegin(0)
+ , hotPathOther(0)
+ , coldPathOther(0)
+ , callee(0)
+ {
+ }
+
+ unsigned bytecodeIndex;
+ void* callReturnLocation;
+ void* hotPathBegin;
+ void* hotPathOther;
+ void* coldPathOther;
+ CodeBlock* callee;
+ unsigned position;
+
+ void setUnlinked() { callee = 0; }
+ bool isLinked() { return callee; }
+ };
+
+ struct FunctionRegisterInfo {
+ FunctionRegisterInfo(unsigned bytecodeOffset, int functionRegisterIndex)
+ : bytecodeOffset(bytecodeOffset)
+ , functionRegisterIndex(functionRegisterIndex)
+ {
+ }
+
+ unsigned bytecodeOffset;
+ int functionRegisterIndex;
+ };
+
+ struct GlobalResolveInfo {
+ GlobalResolveInfo(unsigned bytecodeOffset)
+ : structure(0)
+ , offset(0)
+ , bytecodeOffset(bytecodeOffset)
+ {
+ }
+
+ Structure* structure;
+ unsigned offset;
+ unsigned bytecodeOffset;
+ };
+
+ struct PC {
+ PC(ptrdiff_t nativePCOffset, unsigned bytecodeIndex)
+ : nativePCOffset(nativePCOffset)
+ , bytecodeIndex(bytecodeIndex)
+ {
+ }
+
+ ptrdiff_t nativePCOffset;
+ unsigned bytecodeIndex;
+ };
+
+ // valueAtPosition helpers for the binaryChop algorithm below.
+
+ inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
+ {
+ return structureStubInfo->callReturnLocation;
+ }
+
+ inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo)
+ {
+ return callLinkInfo->callReturnLocation;
+ }
+
+ inline ptrdiff_t getNativePCOffset(PC* pc)
+ {
+ return pc->nativePCOffset;
+ }
+
+ // Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array,
+ // compares result with key (KeyTypes should be comparable with '--', '<', '>').
+ // Optimized for cases where the array contains the key, checked by assertions.
+ template<typename ArrayType, typename KeyType, KeyType(*valueAtPosition)(ArrayType*)>
+ inline ArrayType* binaryChop(ArrayType* array, size_t size, KeyType key)
+ {
+ // The array must contain at least one element (pre-condition, array does conatin key).
+ // If the array only contains one element, no need to do the comparison.
+ while (size > 1) {
+ // Pick an element to check, half way through the array, and read the value.
+ int pos = (size - 1) >> 1;
+ KeyType val = valueAtPosition(&array[pos]);
+
+ // If the key matches, success!
+ if (val == key)
+ return &array[pos];
+ // The item we are looking for is smaller than the item being check; reduce the value of 'size',
+ // chopping off the right hand half of the array.
+ else if (key < val)
+ size = pos;
+ // Discard all values in the left hand half of the array, up to and including the item at pos.
+ else {
+ size -= (pos + 1);
+ array += (pos + 1);
+ }
+
+ // 'size' should never reach zero.
+ ASSERT(size);
+ }
+
+ // If we reach this point we've chopped down to one element, no need to check it matches
+ ASSERT(size == 1);
+ ASSERT(key == valueAtPosition(&array[0]));
+ return &array[0];
+ }
+#endif
+
+ class CodeBlock {
+ friend class JIT;
+ public:
+ CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset);
+ ~CodeBlock();
+
+ void mark();
+ void refStructures(Instruction* vPC) const;
+ void derefStructures(Instruction* vPC) const;
+#if ENABLE(JIT)
+ void unlinkCallers();
+#endif
+
+ static void dumpStatistics();
+
+#if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING
+ void dump(ExecState*) const;
+ void printStructures(const Instruction*) const;
+ void printStructure(const char* name, const Instruction*, int operand) const;
+#endif
+
+ inline bool isKnownNotImmediate(int index)
+ {
+ if (index == m_thisRegister)
+ return true;
+
+ if (isConstantRegisterIndex(index))
+ return getConstant(index).isCell();
+
+ return false;
+ }
+
+ ALWAYS_INLINE bool isConstantRegisterIndex(int index)
+ {
+ return index >= m_numVars && index < m_numVars + m_numConstants;
+ }
+
+ ALWAYS_INLINE JSValuePtr getConstant(int index)
+ {
+ return m_constantRegisters[index - m_numVars].getJSValue();
+ }
+
+ ALWAYS_INLINE bool isTemporaryRegisterIndex(int index)
+ {
+ return index >= m_numVars + m_numConstants;
+ }
+
+ HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset);
+ int lineNumberForBytecodeOffset(CallFrame*, unsigned bytecodeOffset);
+ int expressionRangeForBytecodeOffset(CallFrame*, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset);
+ bool getByIdExceptionInfoForBytecodeOffset(CallFrame*, unsigned bytecodeOffset, OpcodeID&);
+
+#if ENABLE(JIT)
+ void addCaller(CallLinkInfo* caller)
+ {
+ caller->callee = this;
+ caller->position = m_linkedCallerList.size();
+ m_linkedCallerList.append(caller);
+ }
+
+ void removeCaller(CallLinkInfo* caller)
+ {
+ unsigned pos = caller->position;
+ unsigned lastPos = m_linkedCallerList.size() - 1;
+
+ if (pos != lastPos) {
+ m_linkedCallerList[pos] = m_linkedCallerList[lastPos];
+ m_linkedCallerList[pos]->position = pos;
+ }
+ m_linkedCallerList.shrink(lastPos);
+ }
+
+ StructureStubInfo& getStubInfo(void* returnAddress)
+ {
+ return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress));
+ }
+
+ CallLinkInfo& getCallLinkInfo(void* returnAddress)
+ {
+ return *(binaryChop<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress));
+ }
+
+ unsigned getBytecodeIndex(CallFrame* callFrame, void* nativePC)
+ {
+ reparseForExceptionInfoIfNecessary(callFrame);
+ ptrdiff_t nativePCOffset = reinterpret_cast<void**>(nativePC) - reinterpret_cast<void**>(m_jitCode.code);
+ return binaryChop<PC, ptrdiff_t, getNativePCOffset>(m_exceptionInfo->m_pcVector.begin(), m_exceptionInfo->m_pcVector.size(), nativePCOffset)->bytecodeIndex;
+ }
+
+ bool functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex);
+#endif
+
+ void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
+ bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
+
+ Vector<Instruction>& instructions() { return m_instructions; }
+#ifndef NDEBUG
+ void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; }
+#endif
+
+#if ENABLE(JIT)
+ void setJITCode(JITCodeRef& jitCode);
+ void* jitCode() { return m_jitCode.code; }
+ ExecutablePool* executablePool() { return m_jitCode.executablePool.get(); }
+#endif
+
+ ScopeNode* ownerNode() const { return m_ownerNode; }
+
+ void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; }
+
+ void setThisRegister(int thisRegister) { m_thisRegister = thisRegister; }
+ int thisRegister() const { return m_thisRegister; }
+
+ void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; }
+ bool needsFullScopeChain() const { return m_needsFullScopeChain; }
+ void setUsesEval(bool usesEval) { m_usesEval = usesEval; }
+ bool usesEval() const { return m_usesEval; }
+ void setUsesArguments(bool usesArguments) { m_usesArguments = usesArguments; }
+ bool usesArguments() const { return m_usesArguments; }
+
+ CodeType codeType() const { return m_codeType; }
+
+ SourceProvider* source() const { return m_source.get(); }
+ unsigned sourceOffset() const { return m_sourceOffset; }
+
+ size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
+ void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
+ unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
+ unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
+
+#if !ENABLE(JIT)
+ void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { m_propertyAccessInstructions.append(propertyAccessInstruction); }
+ void addGlobalResolveInstruction(unsigned globalResolveInstruction) { m_globalResolveInstructions.append(globalResolveInstruction); }
+ bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
+#else
+ size_t numberOfStructureStubInfos() const { return m_structureStubInfos.size(); }
+ void addStructureStubInfo(const StructureStubInfo& stubInfo) { m_structureStubInfos.append(stubInfo); }
+ StructureStubInfo& structureStubInfo(int index) { return m_structureStubInfos[index]; }
+
+ void addGlobalResolveInfo(unsigned globalResolveInstruction) { m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction)); }
+ GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
+ bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);
+
+ size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); }
+ void addCallLinkInfo() { m_callLinkInfos.append(CallLinkInfo()); }
+ CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
+
+ void addFunctionRegisterInfo(unsigned bytecodeOffset, int functionIndex) { createRareDataIfNecessary(); m_rareData->m_functionRegisterInfos.append(FunctionRegisterInfo(bytecodeOffset, functionIndex)); }
+#endif
+
+ // Exception handling support
+
+ size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
+ void addExceptionHandler(const HandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
+ HandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
+
+ bool hasExceptionInfo() const { return m_exceptionInfo; }
+ void clearExceptionInfo() { m_exceptionInfo.clear(); }
+
+ void addExpressionInfo(const ExpressionRangeInfo& expressionInfo) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_expressionInfo.append(expressionInfo); }
+ void addGetByIdExceptionInfo(const GetByIdExceptionInfo& info) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_getByIdExceptionInfo.append(info); }
+
+ size_t numberOfLineInfos() const { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_lineInfo.size(); }
+ void addLineInfo(const LineInfo& lineInfo) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_lineInfo.append(lineInfo); }
+ LineInfo& lastLineInfo() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_lineInfo.last(); }
+
+#if ENABLE(JIT)
+ Vector<PC>& pcVector() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_pcVector; }
+#endif
+
+ // Constant Pool
+
+ size_t numberOfIdentifiers() const { return m_identifiers.size(); }
+ void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
+ Identifier& identifier(int index) { return m_identifiers[index]; }
+
+ size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
+ void addConstantRegister(const Register& r) { return m_constantRegisters.append(r); }
+ Register& constantRegister(int index) { return m_constantRegisters[index]; }
+
+ unsigned addFunctionExpression(FuncExprNode* n) { unsigned size = m_functionExpressions.size(); m_functionExpressions.append(n); return size; }
+ FuncExprNode* functionExpression(int index) const { return m_functionExpressions[index].get(); }
+
+ unsigned addFunction(FuncDeclNode* n) { createRareDataIfNecessary(); unsigned size = m_rareData->m_functions.size(); m_rareData->m_functions.append(n); return size; }
+ FuncDeclNode* function(int index) const { ASSERT(m_rareData); return m_rareData->m_functions[index].get(); }
+
+ bool hasFunctions() const { return m_functionExpressions.size() || (m_rareData && m_rareData->m_functions.size()); }
+
+ unsigned addUnexpectedConstant(JSValuePtr v) { createRareDataIfNecessary(); unsigned size = m_rareData->m_unexpectedConstants.size(); m_rareData->m_unexpectedConstants.append(v); return size; }
+ JSValuePtr unexpectedConstant(int index) const { ASSERT(m_rareData); return m_rareData->m_unexpectedConstants[index]; }
+
+ unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
+ RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
+
+
+ // Jump Tables
+
+ size_t numberOfImmediateSwitchJumpTables() const { return m_rareData ? m_rareData->m_immediateSwitchJumpTables.size() : 0; }
+ SimpleJumpTable& addImmediateSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_immediateSwitchJumpTables.append(SimpleJumpTable()); return m_rareData->m_immediateSwitchJumpTables.last(); }
+ SimpleJumpTable& immediateSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_immediateSwitchJumpTables[tableIndex]; }
+
+ size_t numberOfCharacterSwitchJumpTables() const { return m_rareData ? m_rareData->m_characterSwitchJumpTables.size() : 0; }
+ SimpleJumpTable& addCharacterSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_characterSwitchJumpTables.append(SimpleJumpTable()); return m_rareData->m_characterSwitchJumpTables.last(); }
+ SimpleJumpTable& characterSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_characterSwitchJumpTables[tableIndex]; }
+
+ size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
+ StringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(StringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
+ StringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
+
+
+ SymbolTable& symbolTable() { return m_symbolTable; }
+
+ EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
+
+ void shrinkToFit();
+
+ // FIXME: Make these remaining members private.
+
+ int m_numCalleeRegisters;
+ // NOTE: numConstants holds the number of constant registers allocated
+ // by the code generator, not the number of constant registers used.
+ // (Duplicate constants are uniqued during code generation, and spare
+ // constant registers may be allocated.)
+ int m_numConstants;
+ int m_numVars;
+ int m_numParameters;
+
+ private:
+#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
+ void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
+#endif
+
+ void reparseForExceptionInfoIfNecessary(CallFrame*);
+
+ void createRareDataIfNecessary()
+ {
+ if (!m_rareData)
+ m_rareData.set(new RareData);
+ }
+
+ ScopeNode* m_ownerNode;
+ JSGlobalData* m_globalData;
+
+ Vector<Instruction> m_instructions;
+#ifndef NDEBUG
+ unsigned m_instructionCount;
+#endif
+#if ENABLE(JIT)
+ JITCodeRef m_jitCode;
+#endif
+
+ int m_thisRegister;
+
+ bool m_needsFullScopeChain;
+ bool m_usesEval;
+ bool m_usesArguments;
+ bool m_isNumericCompareFunction;
+
+ CodeType m_codeType;
+
+ RefPtr<SourceProvider> m_source;
+ unsigned m_sourceOffset;
+
+#if !ENABLE(JIT)
+ Vector<unsigned> m_propertyAccessInstructions;
+ Vector<unsigned> m_globalResolveInstructions;
+#else
+ Vector<StructureStubInfo> m_structureStubInfos;
+ Vector<GlobalResolveInfo> m_globalResolveInfos;
+ Vector<CallLinkInfo> m_callLinkInfos;
+ Vector<CallLinkInfo*> m_linkedCallerList;
+#endif
+
+ Vector<unsigned> m_jumpTargets;
+
+ // Constant Pool
+ Vector<Identifier> m_identifiers;
+ Vector<Register> m_constantRegisters;
+ Vector<RefPtr<FuncExprNode> > m_functionExpressions;
+
+ SymbolTable m_symbolTable;
+
+ struct ExceptionInfo {
+ Vector<ExpressionRangeInfo> m_expressionInfo;
+ Vector<LineInfo> m_lineInfo;
+ Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo;
+
+#if ENABLE(JIT)
+ Vector<PC> m_pcVector;
+#endif
+ };
+ OwnPtr<ExceptionInfo> m_exceptionInfo;
+
+ struct RareData {
+ Vector<HandlerInfo> m_exceptionHandlers;
+
+ // Rare Constants
+ Vector<RefPtr<FuncDeclNode> > m_functions;
+ Vector<JSValuePtr> m_unexpectedConstants;
+ Vector<RefPtr<RegExp> > m_regexps;
+
+ // Jump Tables
+ Vector<SimpleJumpTable> m_immediateSwitchJumpTables;
+ Vector<SimpleJumpTable> m_characterSwitchJumpTables;
+ Vector<StringJumpTable> m_stringSwitchJumpTables;
+
+ EvalCodeCache m_evalCodeCache;
+
+#if ENABLE(JIT)
+ Vector<FunctionRegisterInfo> m_functionRegisterInfos;
+#endif
+ };
+ OwnPtr<RareData> m_rareData;
+ };
+
+ // Program code is not marked by any function, so we make the global object
+ // responsible for marking it.
+
+ class ProgramCodeBlock : public CodeBlock {
+ public:
+ ProgramCodeBlock(ScopeNode* ownerNode, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider)
+ : CodeBlock(ownerNode, codeType, sourceProvider, 0)
+ , m_globalObject(globalObject)
+ {
+ m_globalObject->codeBlocks().add(this);
+ }
+
+ ~ProgramCodeBlock()
+ {
+ if (m_globalObject)
+ m_globalObject->codeBlocks().remove(this);
+ }
+
+ void clearGlobalObject() { m_globalObject = 0; }
+
+ private:
+ JSGlobalObject* m_globalObject; // For program and eval nodes, the global object that marks the constant pool.
+ };
+
+ class EvalCodeBlock : public ProgramCodeBlock {
+ public:
+ EvalCodeBlock(ScopeNode* ownerNode, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth)
+ : ProgramCodeBlock(ownerNode, EvalCode, globalObject, sourceProvider)
+ , m_baseScopeDepth(baseScopeDepth)
+ {
+ }
+
+ int baseScopeDepth() const { return m_baseScopeDepth; }
+
+ private:
+ int m_baseScopeDepth;
+ };
+
+} // namespace JSC
+
+#endif // CodeBlock_h
diff --git a/JavaScriptCore/bytecode/EvalCodeCache.h b/JavaScriptCore/bytecode/EvalCodeCache.h
new file mode 100644
index 0000000..2d6f7dc
--- /dev/null
+++ b/JavaScriptCore/bytecode/EvalCodeCache.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ * 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 EvalCodeCache_h
+#define EvalCodeCache_h
+
+#include "JSGlobalObject.h"
+#include "Nodes.h"
+#include "Parser.h"
+#include "SourceCode.h"
+#include "UString.h"
+#include <wtf/HashMap.h>
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+
+ class EvalCodeCache {
+ public:
+ PassRefPtr<EvalNode> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValuePtr& exceptionValue)
+ {
+ RefPtr<EvalNode> evalNode;
+
+ if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())
+ evalNode = m_cacheMap.get(evalSource.rep());
+
+ if (!evalNode) {
+ int errorLine;
+ UString errorMessage;
+
+ SourceCode source = makeSource(evalSource);
+ evalNode = exec->globalData().parser->parse<EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errorLine, &errorMessage);
+ if (evalNode) {
+ if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
+ m_cacheMap.set(evalSource.rep(), evalNode);
+ } else {
+ exceptionValue = Error::create(exec, SyntaxError, errorMessage, errorLine, source.provider()->asID(), 0);
+ return 0;
+ }
+ }
+
+ return evalNode.release();
+ }
+
+ bool isEmpty() const { return m_cacheMap.isEmpty(); }
+
+ void mark()
+ {
+ EvalCacheMap::iterator end = m_cacheMap.end();
+ for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr)
+ ptr->second->mark();
+ }
+ private:
+ static const int maxCacheableSourceLength = 256;
+ static const int maxCacheEntries = 64;
+
+ typedef HashMap<RefPtr<UString::Rep>, RefPtr<EvalNode> > EvalCacheMap;
+ EvalCacheMap m_cacheMap;
+ };
+
+} // namespace JSC
+
+#endif // EvalCodeCache_h
diff --git a/JavaScriptCore/bytecode/Instruction.h b/JavaScriptCore/bytecode/Instruction.h
new file mode 100644
index 0000000..1fab106
--- /dev/null
+++ b/JavaScriptCore/bytecode/Instruction.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Instruction_h
+#define Instruction_h
+
+#include "Opcode.h"
+#include "Structure.h"
+#include <wtf/VectorTraits.h>
+
+#define POLYMORPHIC_LIST_CACHE_SIZE 4
+
+namespace JSC {
+
+ class JSCell;
+ class Structure;
+ class StructureChain;
+
+ // Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream.
+ struct PolymorphicAccessStructureList {
+ struct PolymorphicStubInfo {
+ bool isChain;
+ void* stubRoutine;
+ Structure* base;
+ union {
+ Structure* proto;
+ StructureChain* chain;
+ } u;
+
+ void set(void* _stubRoutine, Structure* _base)
+ {
+ stubRoutine = _stubRoutine;
+ base = _base;
+ u.proto = 0;
+ isChain = false;
+ }
+
+ void set(void* _stubRoutine, Structure* _base, Structure* _proto)
+ {
+ stubRoutine = _stubRoutine;
+ base = _base;
+ u.proto = _proto;
+ isChain = false;
+ }
+
+ void set(void* _stubRoutine, Structure* _base, StructureChain* _chain)
+ {
+ stubRoutine = _stubRoutine;
+ base = _base;
+ u.chain = _chain;
+ isChain = true;
+ }
+ } list[POLYMORPHIC_LIST_CACHE_SIZE];
+
+ PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase)
+ {
+ list[0].set(stubRoutine, firstBase);
+ }
+
+ PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase, Structure* firstProto)
+ {
+ list[0].set(stubRoutine, firstBase, firstProto);
+ }
+
+ PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase, StructureChain* firstChain)
+ {
+ list[0].set(stubRoutine, firstBase, firstChain);
+ }
+
+ void derefStructures(int count)
+ {
+ for (int i = 0; i < count; ++i) {
+ PolymorphicStubInfo& info = list[i];
+
+ ASSERT(info.base);
+ info.base->deref();
+
+ if (info.u.proto) {
+ if (info.isChain)
+ info.u.chain->deref();
+ else
+ info.u.proto->deref();
+ }
+ }
+ }
+ };
+
+ struct Instruction {
+ Instruction(Opcode opcode)
+ {
+#if !HAVE(COMPUTED_GOTO)
+ // We have to initialize one of the pointer members to ensure that
+ // the entire struct is initialized, when opcode is not a pointer.
+ u.jsCell = 0;
+#endif
+ u.opcode = opcode;
+ }
+
+ Instruction(int operand)
+ {
+ // We have to initialize one of the pointer members to ensure that
+ // the entire struct is initialized in 64-bit.
+ u.jsCell = 0;
+ u.operand = operand;
+ }
+
+ Instruction(Structure* structure) { u.structure = structure; }
+ Instruction(StructureChain* structureChain) { u.structureChain = structureChain; }
+ Instruction(JSCell* jsCell) { u.jsCell = jsCell; }
+ Instruction(PolymorphicAccessStructureList* polymorphicStructures) { u.polymorphicStructures = polymorphicStructures; }
+
+ union {
+ Opcode opcode;
+ int operand;
+ Structure* structure;
+ StructureChain* structureChain;
+ JSCell* jsCell;
+ PolymorphicAccessStructureList* polymorphicStructures;
+ } u;
+ };
+
+} // namespace JSC
+
+namespace WTF {
+
+ template<> struct VectorTraits<JSC::Instruction> : VectorTraitsBase<true, JSC::Instruction> { };
+
+} // namespace WTF
+
+#endif // Instruction_h
diff --git a/JavaScriptCore/VM/Instruction.h b/JavaScriptCore/bytecode/JumpTable.cpp
index 6e32c06..175c1b3 100644
--- a/JavaScriptCore/VM/Instruction.h
+++ b/JavaScriptCore/bytecode/JumpTable.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,49 +27,19 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Instruction_h
-#define Instruction_h
-
-#include "Opcode.h"
-#include "ResultType.h"
-#include <wtf/VectorTraits.h>
+#include "config.h"
+#include "JumpTable.h"
namespace JSC {
- class JSCell;
- class StructureID;
- class StructureIDChain;
-
- struct Instruction {
- Instruction(Opcode opcode) { u.opcode = opcode; }
- Instruction(int operand)
- {
- // We have to initialize one of the pointer members to ensure that
- // the entire struct is initialised in 64-bit.
- u.jsCell = 0;
- u.operand = operand;
- }
-
- Instruction(StructureID* structureID) { u.structureID = structureID; }
- Instruction(StructureIDChain* structureIDChain) { u.structureIDChain = structureIDChain; }
- Instruction(JSCell* jsCell) { u.jsCell = jsCell; }
-
- union {
- Opcode opcode;
- int operand;
- StructureID* structureID;
- StructureIDChain* structureIDChain;
- JSCell* jsCell;
- ResultType::Type resultType;
- } u;
- };
+int32_t SimpleJumpTable::offsetForValue(int32_t value, int32_t defaultOffset)
+{
+ if (value >= min && static_cast<uint32_t>(value - min) < branchOffsets.size()) {
+ int32_t offset = branchOffsets[value - min];
+ if (offset)
+ return offset;
+ }
+ return defaultOffset;
+}
} // namespace JSC
-
-namespace WTF {
-
- template<> struct VectorTraits<JSC::Instruction> : VectorTraitsBase<true, JSC::Instruction> { };
-
-} // namespace WTF
-
-#endif // Instruction_h
diff --git a/JavaScriptCore/bytecode/JumpTable.h b/JavaScriptCore/bytecode/JumpTable.h
new file mode 100644
index 0000000..44e224d
--- /dev/null
+++ b/JavaScriptCore/bytecode/JumpTable.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JumpTable_h
+#define JumpTable_h
+
+#include "UString.h"
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+ struct OffsetLocation {
+ int32_t branchOffset;
+#if ENABLE(JIT)
+ void* ctiOffset;
+#endif
+ };
+
+ struct StringJumpTable {
+ typedef HashMap<RefPtr<UString::Rep>, OffsetLocation> StringOffsetTable;
+ StringOffsetTable offsetTable;
+#if ENABLE(JIT)
+ void* ctiDefault; // FIXME: it should not be necessary to store this.
+#endif
+
+ inline int32_t offsetForValue(UString::Rep* value, int32_t defaultOffset)
+ {
+ StringOffsetTable::const_iterator end = offsetTable.end();
+ StringOffsetTable::const_iterator loc = offsetTable.find(value);
+ if (loc == end)
+ return defaultOffset;
+ return loc->second.branchOffset;
+ }
+
+#if ENABLE(JIT)
+ inline void* ctiForValue(UString::Rep* value)
+ {
+ StringOffsetTable::const_iterator end = offsetTable.end();
+ StringOffsetTable::const_iterator loc = offsetTable.find(value);
+ if (loc == end)
+ return ctiDefault;
+ return loc->second.ctiOffset;
+ }
+#endif
+ };
+
+ struct SimpleJumpTable {
+ // FIXME: The two Vectors can be combind into one Vector<OffsetLocation>
+ Vector<int32_t> branchOffsets;
+ int32_t min;
+#if ENABLE(JIT)
+ Vector<void*> ctiOffsets;
+ void* ctiDefault;
+#endif
+
+ int32_t offsetForValue(int32_t value, int32_t defaultOffset);
+ void add(int32_t key, int32_t offset)
+ {
+ if (!branchOffsets[key])
+ branchOffsets[key] = offset;
+ }
+
+#if ENABLE(JIT)
+ inline void* ctiForValue(int32_t value)
+ {
+ if (value >= min && static_cast<uint32_t>(value - min) < ctiOffsets.size())
+ return ctiOffsets[value - min];
+ return ctiDefault;
+ }
+#endif
+ };
+
+} // namespace JSC
+
+#endif // JumpTable_h
diff --git a/JavaScriptCore/VM/Opcode.cpp b/JavaScriptCore/bytecode/Opcode.cpp
index cc70418..bb7696d 100644
--- a/JavaScriptCore/VM/Opcode.cpp
+++ b/JavaScriptCore/bytecode/Opcode.cpp
@@ -37,7 +37,7 @@ namespace JSC {
#if ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS)
const char* const opcodeNames[] = {
-#define OPCODE_NAME_ENTRY(opcode) #opcode,
+#define OPCODE_NAME_ENTRY(opcode, size) #opcode,
FOR_EACH_OPCODE_ID(OPCODE_NAME_ENTRY)
#undef OPCODE_NAME_ENTRY
};
diff --git a/JavaScriptCore/bytecode/Opcode.h b/JavaScriptCore/bytecode/Opcode.h
new file mode 100644
index 0000000..d00178b
--- /dev/null
+++ b/JavaScriptCore/bytecode/Opcode.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Opcode_h
+#define Opcode_h
+
+#include <algorithm>
+#include <string.h>
+
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+ #define FOR_EACH_OPCODE_ID(macro) \
+ macro(op_enter, 1) \
+ macro(op_enter_with_activation, 2) \
+ macro(op_create_arguments, 1) \
+ macro(op_convert_this, 2) \
+ \
+ macro(op_unexpected_load, 3) \
+ macro(op_new_object, 2) \
+ macro(op_new_array, 4) \
+ macro(op_new_regexp, 3) \
+ macro(op_mov, 3) \
+ \
+ macro(op_not, 3) \
+ macro(op_eq, 4) \
+ macro(op_eq_null, 3) \
+ macro(op_neq, 4) \
+ macro(op_neq_null, 3) \
+ macro(op_stricteq, 4) \
+ macro(op_nstricteq, 4) \
+ macro(op_less, 4) \
+ macro(op_lesseq, 4) \
+ \
+ macro(op_pre_inc, 2) \
+ macro(op_pre_dec, 2) \
+ macro(op_post_inc, 3) \
+ macro(op_post_dec, 3) \
+ macro(op_to_jsnumber, 3) \
+ macro(op_negate, 3) \
+ macro(op_add, 5) \
+ macro(op_mul, 5) \
+ macro(op_div, 4) \
+ macro(op_mod, 4) \
+ macro(op_sub, 5) \
+ \
+ macro(op_lshift, 4) \
+ macro(op_rshift, 4) \
+ macro(op_urshift, 4) \
+ macro(op_bitand, 5) \
+ macro(op_bitxor, 5) \
+ macro(op_bitor, 5) \
+ macro(op_bitnot, 3) \
+ \
+ macro(op_instanceof, 5) \
+ macro(op_typeof, 3) \
+ macro(op_is_undefined, 3) \
+ macro(op_is_boolean, 3) \
+ macro(op_is_number, 3) \
+ macro(op_is_string, 3) \
+ macro(op_is_object, 3) \
+ macro(op_is_function, 3) \
+ macro(op_in, 4) \
+ \
+ macro(op_resolve, 3) \
+ macro(op_resolve_skip, 4) \
+ macro(op_resolve_global, 6) \
+ macro(op_get_scoped_var, 4) \
+ macro(op_put_scoped_var, 4) \
+ macro(op_get_global_var, 4) \
+ macro(op_put_global_var, 4) \
+ macro(op_resolve_base, 3) \
+ macro(op_resolve_with_base, 4) \
+ macro(op_resolve_func, 4) \
+ macro(op_get_by_id, 8) \
+ macro(op_get_by_id_self, 8) \
+ macro(op_get_by_id_self_list, 8) \
+ macro(op_get_by_id_proto, 8) \
+ macro(op_get_by_id_proto_list, 8) \
+ macro(op_get_by_id_chain, 8) \
+ macro(op_get_by_id_generic, 8) \
+ macro(op_get_array_length, 8) \
+ macro(op_get_string_length, 8) \
+ macro(op_put_by_id, 8) \
+ macro(op_put_by_id_transition, 8) \
+ macro(op_put_by_id_replace, 8) \
+ macro(op_put_by_id_generic, 8) \
+ macro(op_del_by_id, 4) \
+ macro(op_get_by_val, 4) \
+ macro(op_put_by_val, 4) \
+ macro(op_del_by_val, 4) \
+ macro(op_put_by_index, 4) \
+ macro(op_put_getter, 4) \
+ macro(op_put_setter, 4) \
+ \
+ macro(op_jmp, 2) \
+ macro(op_jtrue, 3) \
+ macro(op_jfalse, 3) \
+ macro(op_jeq_null, 3) \
+ macro(op_jneq_null, 3) \
+ macro(op_jnless, 4) \
+ macro(op_jmp_scopes, 3) \
+ macro(op_loop, 2) \
+ macro(op_loop_if_true, 3) \
+ macro(op_loop_if_less, 4) \
+ macro(op_loop_if_lesseq, 4) \
+ macro(op_switch_imm, 4) \
+ macro(op_switch_char, 4) \
+ macro(op_switch_string, 4) \
+ \
+ macro(op_new_func, 3) \
+ macro(op_new_func_exp, 3) \
+ macro(op_call, 5) \
+ macro(op_call_eval, 5) \
+ macro(op_tear_off_activation, 2) \
+ macro(op_tear_off_arguments, 1) \
+ macro(op_ret, 2) \
+ \
+ macro(op_construct, 7) \
+ macro(op_construct_verify, 3) \
+ \
+ macro(op_get_pnames, 3) \
+ macro(op_next_pname, 4) \
+ \
+ macro(op_push_scope, 2) \
+ macro(op_pop_scope, 1) \
+ macro(op_push_new_scope, 4) \
+ \
+ macro(op_catch, 2) \
+ macro(op_throw, 2) \
+ macro(op_new_error, 4) \
+ \
+ macro(op_jsr, 3) \
+ macro(op_sret, 2) \
+ \
+ macro(op_debug, 4) \
+ macro(op_profile_will_call, 2) \
+ macro(op_profile_did_call, 2) \
+ \
+ macro(op_end, 2) // end must be the last opcode in the list
+
+ #define OPCODE_ID_ENUM(opcode, length) opcode,
+ typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;
+ #undef OPCODE_ID_ENUM
+
+ const int numOpcodeIDs = op_end + 1;
+
+ #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;
+ FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTHS);
+ #undef OPCODE_ID_SIZES
+
+ #define OPCODE_LENGTH(opcode) opcode##_length
+
+ #define OPCODE_ID_LENGTH_MAP(opcode, length) length,
+ const int opcodeLengths[numOpcodeIDs] = { FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTH_MAP) };
+ #undef OPCODE_ID_LENGTH_MAP
+
+ #define VERIFY_OPCODE_ID(id, size) COMPILE_ASSERT(id <= op_end, ASSERT_THAT_JS_OPCODE_IDS_ARE_VALID);
+ FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
+ #undef VERIFY_OPCODE_ID
+
+#if HAVE(COMPUTED_GOTO)
+ typedef void* Opcode;
+#else
+ typedef OpcodeID Opcode;
+#endif
+
+#if ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS)
+
+#define PADDING_STRING " "
+#define PADDING_STRING_LENGTH static_cast<unsigned>(strlen(PADDING_STRING))
+
+ extern const char* const opcodeNames[];
+
+ inline const char* padOpcodeName(OpcodeID op, unsigned width)
+ {
+ unsigned pad = width - strlen(opcodeNames[op]);
+ pad = std::min(pad, PADDING_STRING_LENGTH);
+ return PADDING_STRING + PADDING_STRING_LENGTH - pad;
+ }
+
+#undef PADDING_STRING_LENGTH
+#undef PADDING_STRING
+
+#endif
+
+#if ENABLE(OPCODE_STATS)
+
+ struct OpcodeStats {
+ OpcodeStats();
+ ~OpcodeStats();
+ static long long opcodeCounts[numOpcodeIDs];
+ static long long opcodePairCounts[numOpcodeIDs][numOpcodeIDs];
+ static int lastOpcode;
+
+ static void recordInstruction(int opcode);
+ static void resetLastInstruction();
+ };
+
+#endif
+
+} // namespace JSC
+
+#endif // Opcode_h
diff --git a/JavaScriptCore/VM/SamplingTool.cpp b/JavaScriptCore/bytecode/SamplingTool.cpp
index 3de3ff5..215ebe5 100644
--- a/JavaScriptCore/VM/SamplingTool.cpp
+++ b/JavaScriptCore/bytecode/SamplingTool.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
#include "SamplingTool.h"
#include "CodeBlock.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "Opcode.h"
#if !PLATFORM(WIN_OS)
@@ -42,14 +42,14 @@ namespace JSC {
void ScopeSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC)
{
if (!m_samples) {
- m_size = codeBlock->instructions.size();
+ m_size = codeBlock->instructions().size();
m_samples = static_cast<int*>(calloc(m_size, sizeof(int)));
m_codeBlock = codeBlock;
}
++m_sampleCount;
- unsigned offest = vPC - codeBlock->instructions.begin();
+ unsigned offest = vPC - codeBlock->instructions().begin();
// Since we don't read and write codeBlock and vPC atomically, this check
// can fail if we sample mid op_call / op_ret.
if (offest < m_size) {
@@ -94,7 +94,7 @@ void SamplingTool::run()
continue;
if (!sample.inHostFunction()) {
- unsigned opcodeID = m_machine->getOpcodeID(sample.vPC()[0].u.opcode);
+ unsigned opcodeID = m_interpreter->getOpcodeID(sample.vPC()[0].u.opcode);
++m_opcodeSampleCount;
++m_opcodeSamples[opcodeID];
@@ -105,7 +105,7 @@ void SamplingTool::run()
#if ENABLE(CODEBLOCK_SAMPLING)
MutexLocker locker(m_scopeSampleMapMutex);
- ScopeSampleRecord* record = m_scopeSampleMap->get(sample.codeBlock()->ownerNode);
+ ScopeSampleRecord* record = m_scopeSampleMap->get(sample.codeBlock()->ownerNode());
ASSERT(record);
record->sample(sample.codeBlock(), sample.vPC());
#endif
@@ -196,7 +196,7 @@ void SamplingTool::dump(ExecState* exec)
// (2) Print Opcode sampling results.
- printf("\nOpcode samples [*]\n");
+ printf("\nBytecode samples [*]\n");
printf(" sample %% of %% of | cti cti %%\n");
printf("opcode count VM total | count of self\n");
printf("------------------------------------------------------- | ----------------\n");
@@ -206,10 +206,10 @@ void SamplingTool::dump(ExecState* exec)
if (!count)
continue;
- OpcodeID opcode = opcodeSampleInfo[i].opcode;
+ OpcodeID opcodeID = opcodeSampleInfo[i].opcode;
- const char* opcodeName = opcodeNames[opcode];
- const char* opcodePadding = padOpcodeName(opcode, 28);
+ const char* opcodeName = opcodeNames[opcodeID];
+ const char* opcodePadding = padOpcodeName(opcodeID, 28);
double percentOfVM = (static_cast<double>(count) * 100) / m_opcodeSampleCount;
double percentOfTotal = (static_cast<double>(count) * 100) / m_sampleCount;
long long countInCTIFunctions = opcodeSampleInfo[i].countInCTIFunctions;
@@ -217,7 +217,7 @@ void SamplingTool::dump(ExecState* exec)
fprintf(stdout, "%s:%s%-6lld %.3f%%\t%.3f%%\t | %-6lld %.3f%%\n", opcodeName, opcodePadding, count, percentOfVM, percentOfTotal, countInCTIFunctions, percentInCTIFunctions);
}
- printf("\n[*] Samples inside host code are not charged to any Opcode.\n\n");
+ printf("\n[*] Samples inside host code are not charged to any Bytecode.\n\n");
printf("\tSamples inside VM:\t\t%lld / %lld (%.3f%%)\n", m_opcodeSampleCount, m_sampleCount, (static_cast<double>(m_opcodeSampleCount) * 100) / m_sampleCount);
printf("\tSamples inside host code:\t%lld / %lld (%.3f%%)\n\n", m_sampleCount - m_opcodeSampleCount, m_sampleCount, (static_cast<double>(m_sampleCount - m_opcodeSampleCount) * 100) / m_sampleCount);
printf("\tsample count:\tsamples inside this opcode\n");
@@ -248,8 +248,8 @@ void SamplingTool::dump(ExecState* exec)
double blockPercent = (record->m_sampleCount * 100.0) / m_sampleCount;
if (blockPercent >= 1) {
- Instruction* code = codeBlock->instructions.begin();
- printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_scope->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForVPC(code), record->m_sampleCount, m_sampleCount, blockPercent);
+ //Instruction* code = codeBlock->instructions().begin();
+ printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_scope->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent);
if (i < 10) {
HashMap<unsigned,unsigned> lineCounts;
codeBlock->dump(exec);
@@ -259,7 +259,7 @@ void SamplingTool::dump(ExecState* exec)
int count = record->m_samples[op];
if (count) {
printf(" [% 4d] has sample count: % 4d\n", op, count);
- unsigned line = codeBlock->lineNumberForVPC(code+op);
+ unsigned line = codeBlock->lineNumberForBytecodeOffset(exec, op);
lineCounts.set(line, (lineCounts.contains(line) ? lineCounts.get(line) : 0) + count);
}
}
@@ -279,7 +279,7 @@ void SamplingTool::dump(ExecState* exec)
printf(" Line #%d has sample count %d.\n", lineCountInfo[lineno].line, lineCountInfo[lineno].count);
}
printf("\n");
- printf(" [*] Samples inside host code are charged to the calling Opcode.\n");
+ printf(" [*] Samples inside host code are charged to the calling Bytecode.\n");
printf(" Samples on a call / return boundary are not charged to a specific opcode or line.\n\n");
printf(" Samples on a call / return boundary: %d / %d (%.3f%%)\n\n", record->m_sampleCount - record->m_opcodeSampleCount, record->m_sampleCount, (static_cast<double>(record->m_sampleCount - record->m_opcodeSampleCount) * 100) / record->m_sampleCount);
}
diff --git a/JavaScriptCore/VM/SamplingTool.h b/JavaScriptCore/bytecode/SamplingTool.h
index 059f0d5..d1cf2e88 100644
--- a/JavaScriptCore/VM/SamplingTool.h
+++ b/JavaScriptCore/bytecode/SamplingTool.h
@@ -33,14 +33,14 @@
#include <wtf/HashMap.h>
#include <wtf/Threading.h>
-#include "nodes.h"
+#include "Nodes.h"
#include "Opcode.h"
namespace JSC {
class CodeBlock;
class ExecState;
- class Machine;
+ class Interpreter;
class ScopeNode;
struct Instruction;
@@ -125,8 +125,8 @@ namespace JSC {
};
#endif
- SamplingTool(Machine* machine)
- : m_machine(machine)
+ SamplingTool(Interpreter* interpreter)
+ : m_interpreter(interpreter)
, m_running(false)
, m_codeBlock(0)
, m_sample(0)
@@ -159,10 +159,10 @@ namespace JSC {
CodeBlock** codeBlockSlot() { return &m_codeBlock; }
intptr_t* sampleSlot() { return &m_sample; }
- unsigned encodeSample(Instruction* vPC, bool inCTIFunction = false, bool inHostFunction = false)
+ void* encodeSample(Instruction* vPC, bool inCTIFunction = false, bool inHostFunction = false)
{
ASSERT(!(reinterpret_cast<intptr_t>(vPC) & 0x3));
- return reinterpret_cast<intptr_t>(vPC) | (static_cast<intptr_t>(inCTIFunction) << 1) | static_cast<intptr_t>(inHostFunction);
+ return reinterpret_cast<void*>(reinterpret_cast<intptr_t>(vPC) | (static_cast<intptr_t>(inCTIFunction) << 1) | static_cast<intptr_t>(inHostFunction));
}
private:
@@ -188,7 +188,7 @@ namespace JSC {
static void* threadStartFunc(void*);
void run();
- Machine* m_machine;
+ Interpreter* m_interpreter;
// Sampling thread state.
bool m_running;
diff --git a/JavaScriptCore/bytecode/StructureStubInfo.cpp b/JavaScriptCore/bytecode/StructureStubInfo.cpp
new file mode 100644
index 0000000..bf3fdc4
--- /dev/null
+++ b/JavaScriptCore/bytecode/StructureStubInfo.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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 "StructureStubInfo.h"
+
+namespace JSC {
+
+#if ENABLE(JIT)
+void StructureStubInfo::deref()
+{
+ switch (opcodeID) {
+ case op_get_by_id_self:
+ u.getByIdSelf.baseObjectStructure->deref();
+ return;
+ case op_get_by_id_proto:
+ u.getByIdProto.baseObjectStructure->deref();
+ u.getByIdProto.prototypeStructure->deref();
+ return;
+ case op_get_by_id_chain:
+ u.getByIdChain.baseObjectStructure->deref();
+ u.getByIdChain.chain->deref();
+ return;
+ case op_get_by_id_self_list: {
+ PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
+ polymorphicStructures->derefStructures(u.getByIdSelfList.listSize);
+ delete polymorphicStructures;
+ return;
+ }
+ case op_get_by_id_proto_list: {
+ PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList;
+ polymorphicStructures->derefStructures(u.getByIdProtoList.listSize);
+ delete polymorphicStructures;
+ return;
+ }
+ case op_put_by_id_transition:
+ u.putByIdTransition.previousStructure->deref();
+ u.putByIdTransition.structure->deref();
+ u.putByIdTransition.chain->deref();
+ return;
+ case op_put_by_id_replace:
+ u.putByIdReplace.baseObjectStructure->deref();
+ return;
+ case op_get_by_id:
+ case op_put_by_id:
+ case op_get_by_id_generic:
+ case op_put_by_id_generic:
+ case op_get_array_length:
+ case op_get_string_length:
+ // These instructions don't ref their Structures.
+ return;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+#endif
+
+} // namespace JSC
diff --git a/JavaScriptCore/bytecode/StructureStubInfo.h b/JavaScriptCore/bytecode/StructureStubInfo.h
new file mode 100644
index 0000000..a9e0678
--- /dev/null
+++ b/JavaScriptCore/bytecode/StructureStubInfo.h
@@ -0,0 +1,156 @@
+/*
+ * 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 StructureStubInfo_h
+#define StructureStubInfo_h
+
+#include "Instruction.h"
+#include "Opcode.h"
+#include "Structure.h"
+
+namespace JSC {
+
+#if ENABLE(JIT)
+ struct StructureStubInfo {
+ StructureStubInfo(OpcodeID opcodeID)
+ : opcodeID(opcodeID)
+ , stubRoutine(0)
+ , callReturnLocation(0)
+ , hotPathBegin(0)
+ {
+ }
+
+ void initGetByIdSelf(Structure* baseObjectStructure)
+ {
+ opcodeID = op_get_by_id_self;
+
+ u.getByIdSelf.baseObjectStructure = baseObjectStructure;
+ baseObjectStructure->ref();
+ }
+
+ void initGetByIdProto(Structure* baseObjectStructure, Structure* prototypeStructure)
+ {
+ opcodeID = op_get_by_id_proto;
+
+ u.getByIdProto.baseObjectStructure = baseObjectStructure;
+ baseObjectStructure->ref();
+
+ u.getByIdProto.prototypeStructure = prototypeStructure;
+ prototypeStructure->ref();
+ }
+
+ void initGetByIdChain(Structure* baseObjectStructure, StructureChain* chain)
+ {
+ opcodeID = op_get_by_id_chain;
+
+ u.getByIdChain.baseObjectStructure = baseObjectStructure;
+ baseObjectStructure->ref();
+
+ u.getByIdChain.chain = chain;
+ chain->ref();
+ }
+
+ void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
+ {
+ opcodeID = op_get_by_id_self_list;
+
+ u.getByIdProtoList.structureList = structureList;
+ u.getByIdProtoList.listSize = listSize;
+ }
+
+ void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize)
+ {
+ opcodeID = op_get_by_id_proto_list;
+
+ u.getByIdProtoList.structureList = structureList;
+ u.getByIdProtoList.listSize = listSize;
+ }
+
+ // PutById*
+
+ void initPutByIdTransition(Structure* previousStructure, Structure* structure, StructureChain* chain)
+ {
+ opcodeID = op_put_by_id_transition;
+
+ u.putByIdTransition.previousStructure = previousStructure;
+ previousStructure->ref();
+
+ u.putByIdTransition.structure = structure;
+ structure->ref();
+
+ u.putByIdTransition.chain = chain;
+ chain->ref();
+ }
+
+ void initPutByIdReplace(Structure* baseObjectStructure)
+ {
+ opcodeID = op_put_by_id_replace;
+
+ u.putByIdReplace.baseObjectStructure = baseObjectStructure;
+ baseObjectStructure->ref();
+ }
+
+ void deref();
+
+ OpcodeID opcodeID;
+ union {
+ struct {
+ Structure* baseObjectStructure;
+ } getByIdSelf;
+ struct {
+ Structure* baseObjectStructure;
+ Structure* prototypeStructure;
+ } getByIdProto;
+ struct {
+ Structure* baseObjectStructure;
+ StructureChain* chain;
+ } getByIdChain;
+ struct {
+ PolymorphicAccessStructureList* structureList;
+ int listSize;
+ } getByIdSelfList;
+ struct {
+ PolymorphicAccessStructureList* structureList;
+ int listSize;
+ } getByIdProtoList;
+ struct {
+ Structure* previousStructure;
+ Structure* structure;
+ StructureChain* chain;
+ } putByIdTransition;
+ struct {
+ Structure* baseObjectStructure;
+ } putByIdReplace;
+ } u;
+
+ void* stubRoutine;
+ void* callReturnLocation;
+ void* hotPathBegin;
+ };
+#endif
+
+} // namespace JSC
+
+#endif // StructureStubInfo_h
diff --git a/JavaScriptCore/VM/CodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 3bfea93..cd89c1e 100644
--- a/JavaScriptCore/VM/CodeGenerator.cpp
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
*
* Redistribution and use in source and binary forms, with or without
@@ -28,12 +28,12 @@
*/
#include "config.h"
-#include "CodeGenerator.h"
+#include "BytecodeGenerator.h"
#include "BatchedTransitionOptimizer.h"
#include "JSFunction.h"
-#include "Machine.h"
-#include "ustring.h"
+#include "Interpreter.h"
+#include "UString.h"
using namespace std;
@@ -115,10 +115,10 @@ namespace JSC {
*/
#ifndef NDEBUG
-bool CodeGenerator::s_dumpsGeneratedCode = false;
+static bool s_dumpsGeneratedCode = false;
#endif
-void CodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode)
+void BytecodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode)
{
#ifndef NDEBUG
s_dumpsGeneratedCode = dumpsGeneratedCode;
@@ -127,27 +127,42 @@ void CodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode)
#endif
}
-void CodeGenerator::generate()
+bool BytecodeGenerator::dumpsGeneratedCode()
{
- m_codeBlock->thisRegister = m_thisRegister.index();
+#ifndef NDEBUG
+ return s_dumpsGeneratedCode;
+#else
+ return false;
+#endif
+}
+
+void BytecodeGenerator::generate()
+{
+ m_codeBlock->setThisRegister(m_thisRegister.index());
- m_scopeNode->emitCode(*this);
+ m_scopeNode->emitBytecode(*this);
#ifndef NDEBUG
- if (s_dumpsGeneratedCode) {
- JSGlobalObject* globalObject = m_scopeChain->globalObject();
- m_codeBlock->dump(globalObject->globalExec());
- }
+ m_codeBlock->setInstructionCount(m_codeBlock->instructions().size());
+
+ if (s_dumpsGeneratedCode)
+ m_codeBlock->dump(m_scopeChain->globalObject()->globalExec());
#endif
- m_scopeNode->children().shrinkCapacity(0);
- if (m_codeType != EvalCode) { // eval code needs to hang on to its declaration stacks to keep declaration info alive until Machine::execute time.
- m_scopeNode->varStack().shrinkCapacity(0);
- m_scopeNode->functionStack().shrinkCapacity(0);
- }
+ if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
+ symbolTable().clear();
+
+ m_codeBlock->setIsNumericCompareFunction(instructions() == m_globalData->numericCompareFunction(m_scopeChain->globalObject()->globalExec()));
+
+#if !ENABLE(OPCODE_SAMPLING)
+ if (!m_regeneratingForExceptionInfo && (m_codeType == FunctionCode || m_codeType == EvalCode))
+ m_codeBlock->clearExceptionInfo();
+#endif
+
+ m_codeBlock->shrinkToFit();
}
-bool CodeGenerator::addVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
+bool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
{
int index = m_calleeRegisters.size();
SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
@@ -158,21 +173,21 @@ bool CodeGenerator::addVar(const Identifier& ident, bool isConstant, RegisterID*
return false;
}
- ++m_codeBlock->numVars;
+ ++m_codeBlock->m_numVars;
r0 = newRegister();
return true;
}
-bool CodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
+bool BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
{
- int index = m_nextGlobal;
+ int index = m_nextGlobalIndex;
SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.ustring().rep(), newEntry);
if (!result.second)
index = result.first->second.getIndex();
else {
- --m_nextGlobal;
+ --m_nextGlobalIndex;
m_globals.append(index + m_globalVarStorageOffset);
}
@@ -180,20 +195,20 @@ bool CodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, Regis
return result.second;
}
-void CodeGenerator::allocateConstants(size_t count)
+void BytecodeGenerator::allocateConstants(size_t count)
{
- m_codeBlock->numConstants = count;
+ m_codeBlock->m_numConstants = count;
if (!count)
return;
- m_nextConstant = m_calleeRegisters.size();
+ m_nextConstantIndex = m_calleeRegisters.size();
for (size_t i = 0; i < count; ++i)
newRegister();
m_lastConstant = &m_calleeRegisters.last();
}
-CodeGenerator::CodeGenerator(ProgramNode* programNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock, VarStack& varStack, FunctionStack& functionStack)
+BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock)
: m_shouldEmitDebugHooks(!!debugger)
, m_shouldEmitProfileHooks(scopeChain.globalObject()->supportsProfiling())
, m_scopeChain(&scopeChain)
@@ -203,27 +218,31 @@ CodeGenerator::CodeGenerator(ProgramNode* programNode, const Debugger* debugger,
, m_thisRegister(RegisterFile::ProgramCodeThisRegister)
, m_finallyDepth(0)
, m_dynamicScopeDepth(0)
+ , m_baseScopeDepth(0)
, m_codeType(GlobalCode)
- , m_nextGlobal(-1)
+ , m_nextGlobalIndex(-1)
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
+ , m_emitNodeDepth(0)
+ , m_regeneratingForExceptionInfo(false)
+ , m_codeBlockBeingRegeneratedFrom(0)
{
if (m_shouldEmitDebugHooks)
- m_codeBlock->needsFullScopeChain = true;
+ m_codeBlock->setNeedsFullScopeChain(true);
emitOpcode(op_enter);
- codeBlock->globalData = m_globalData;
+ codeBlock->setGlobalData(m_globalData);
- // FIXME: Move code that modifies the global object to Machine::execute.
+ // FIXME: Move code that modifies the global object to Interpreter::execute.
- m_codeBlock->numParameters = 1; // Allocate space for "this"
+ m_codeBlock->m_numParameters = 1; // Allocate space for "this"
JSGlobalObject* globalObject = scopeChain.globalObject();
ExecState* exec = globalObject->globalExec();
- RegisterFile* registerFile = &exec->globalData().machine->registerFile();
+ RegisterFile* registerFile = &exec->globalData().interpreter->registerFile();
// Shift register indexes in generated code to elide registers allocated by intermediate stack frames.
- m_globalVarStorageOffset = -RegisterFile::CallFrameHeaderSize - m_codeBlock->numParameters - registerFile->size();
+ m_globalVarStorageOffset = -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters - registerFile->size();
// Add previously defined symbols to bookkeeping.
m_globals.grow(symbolTable->size());
@@ -233,10 +252,12 @@ CodeGenerator::CodeGenerator(ProgramNode* programNode, const Debugger* debugger,
BatchedTransitionOptimizer optimizer(globalObject);
+ const VarStack& varStack = programNode->varStack();
+ const FunctionStack& functionStack = programNode->functionStack();
bool canOptimizeNewGlobals = symbolTable->size() + functionStack.size() + varStack.size() < registerFile->maxGlobals();
if (canOptimizeNewGlobals) {
// Shift new symbols so they get stored prior to existing symbols.
- m_nextGlobal -= symbolTable->size();
+ m_nextGlobalIndex -= symbolTable->size();
for (size_t i = 0; i < functionStack.size(); ++i) {
FuncDeclNode* funcDecl = functionStack[i].get();
@@ -271,7 +292,7 @@ CodeGenerator::CodeGenerator(ProgramNode* programNode, const Debugger* debugger,
}
}
-CodeGenerator::CodeGenerator(FunctionBodyNode* functionBody, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock)
+BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock)
: m_shouldEmitDebugHooks(!!debugger)
, m_shouldEmitProfileHooks(scopeChain.globalObject()->supportsProfiling())
, m_scopeChain(&scopeChain)
@@ -280,24 +301,28 @@ CodeGenerator::CodeGenerator(FunctionBodyNode* functionBody, const Debugger* deb
, m_codeBlock(codeBlock)
, m_finallyDepth(0)
, m_dynamicScopeDepth(0)
+ , m_baseScopeDepth(0)
, m_codeType(FunctionCode)
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
+ , m_emitNodeDepth(0)
+ , m_regeneratingForExceptionInfo(false)
+ , m_codeBlockBeingRegeneratedFrom(0)
{
if (m_shouldEmitDebugHooks)
- m_codeBlock->needsFullScopeChain = true;
+ m_codeBlock->setNeedsFullScopeChain(true);
- codeBlock->globalData = m_globalData;
+ codeBlock->setGlobalData(m_globalData);
bool usesArguments = functionBody->usesArguments();
- codeBlock->usesArguments = usesArguments;
+ codeBlock->setUsesArguments(usesArguments);
if (usesArguments) {
m_argumentsRegister.setIndex(RegisterFile::OptionalCalleeArguments);
addVar(propertyNames().arguments, false);
}
- if (m_codeBlock->needsFullScopeChain) {
- ++m_codeBlock->numVars;
+ if (m_codeBlock->needsFullScopeChain()) {
+ ++m_codeBlock->m_numVars;
m_activationRegisterIndex = newRegister()->index();
emitOpcode(op_enter_with_activation);
instructions().append(m_activationRegisterIndex);
@@ -307,7 +332,7 @@ CodeGenerator::CodeGenerator(FunctionBodyNode* functionBody, const Debugger* deb
if (usesArguments)
emitOpcode(op_create_arguments);
- const Node::FunctionStack& functionStack = functionBody->functionStack();
+ const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
for (size_t i = 0; i < functionStack.size(); ++i) {
FuncDeclNode* funcDecl = functionStack[i].get();
const Identifier& ident = funcDecl->m_ident;
@@ -315,21 +340,21 @@ CodeGenerator::CodeGenerator(FunctionBodyNode* functionBody, const Debugger* deb
emitNewFunction(addVar(ident, false), funcDecl);
}
- const Node::VarStack& varStack = functionBody->varStack();
+ const DeclarationStacks::VarStack& varStack = functionBody->varStack();
for (size_t i = 0; i < varStack.size(); ++i)
addVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant);
const Identifier* parameters = functionBody->parameters();
size_t parameterCount = functionBody->parameterCount();
- m_nextParameter = -RegisterFile::CallFrameHeaderSize - parameterCount - 1;
+ m_nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1;
m_parameters.grow(1 + parameterCount); // reserve space for "this"
// Add "this" as a parameter
- m_thisRegister.setIndex(m_nextParameter);
- ++m_nextParameter;
- ++m_codeBlock->numParameters;
+ m_thisRegister.setIndex(m_nextParameterIndex);
+ ++m_nextParameterIndex;
+ ++m_codeBlock->m_numParameters;
- if (functionBody->usesThis()) {
+ if (functionBody->usesThis() || m_shouldEmitDebugHooks) {
emitOpcode(op_convert_this);
instructions().append(m_thisRegister.index());
}
@@ -340,7 +365,7 @@ CodeGenerator::CodeGenerator(FunctionBodyNode* functionBody, const Debugger* deb
allocateConstants(functionBody->neededConstants());
}
-CodeGenerator::CodeGenerator(EvalNode* evalNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock)
+BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock)
: m_shouldEmitDebugHooks(!!debugger)
, m_shouldEmitProfileHooks(scopeChain.globalObject()->supportsProfiling())
, m_scopeChain(&scopeChain)
@@ -350,40 +375,44 @@ CodeGenerator::CodeGenerator(EvalNode* evalNode, const Debugger* debugger, const
, m_thisRegister(RegisterFile::ProgramCodeThisRegister)
, m_finallyDepth(0)
, m_dynamicScopeDepth(0)
+ , m_baseScopeDepth(codeBlock->baseScopeDepth())
, m_codeType(EvalCode)
, m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
, m_lastOpcodeID(op_end)
+ , m_emitNodeDepth(0)
+ , m_regeneratingForExceptionInfo(false)
+ , m_codeBlockBeingRegeneratedFrom(0)
{
- if (m_shouldEmitDebugHooks)
- m_codeBlock->needsFullScopeChain = true;
+ if (m_shouldEmitDebugHooks || m_baseScopeDepth)
+ m_codeBlock->setNeedsFullScopeChain(true);
emitOpcode(op_enter);
- codeBlock->globalData = m_globalData;
- m_codeBlock->numParameters = 1; // Allocate space for "this"
+ codeBlock->setGlobalData(m_globalData);
+ m_codeBlock->m_numParameters = 1; // Allocate space for "this"
allocateConstants(evalNode->neededConstants());
}
-RegisterID* CodeGenerator::addParameter(const Identifier& ident)
+RegisterID* BytecodeGenerator::addParameter(const Identifier& ident)
{
// Parameters overwrite var declarations, but not function declarations.
RegisterID* result = 0;
UString::Rep* rep = ident.ustring().rep();
if (!m_functions.contains(rep)) {
- symbolTable().set(rep, m_nextParameter);
- RegisterID& parameter = registerFor(m_nextParameter);
- parameter.setIndex(m_nextParameter);
+ symbolTable().set(rep, m_nextParameterIndex);
+ RegisterID& parameter = registerFor(m_nextParameterIndex);
+ parameter.setIndex(m_nextParameterIndex);
result = &parameter;
}
// To maintain the calling convention, we have to allocate unique space for
// each parameter, even if the parameter doesn't make it into the symbol table.
- ++m_nextParameter;
- ++m_codeBlock->numParameters;
+ ++m_nextParameterIndex;
+ ++m_codeBlock->m_numParameters;
return result;
}
-RegisterID* CodeGenerator::registerFor(const Identifier& ident)
+RegisterID* BytecodeGenerator::registerFor(const Identifier& ident)
{
if (ident == propertyNames().thisIdentifier)
return &m_thisRegister;
@@ -398,7 +427,7 @@ RegisterID* CodeGenerator::registerFor(const Identifier& ident)
return &registerFor(entry.getIndex());
}
-RegisterID* CodeGenerator::constRegisterFor(const Identifier& ident)
+RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident)
{
if (m_codeType == EvalCode)
return 0;
@@ -409,7 +438,7 @@ RegisterID* CodeGenerator::constRegisterFor(const Identifier& ident)
return &registerFor(entry.getIndex());
}
-bool CodeGenerator::isLocal(const Identifier& ident)
+bool BytecodeGenerator::isLocal(const Identifier& ident)
{
if (ident == propertyNames().thisIdentifier)
return true;
@@ -417,19 +446,19 @@ bool CodeGenerator::isLocal(const Identifier& ident)
return shouldOptimizeLocals() && symbolTable().contains(ident.ustring().rep());
}
-bool CodeGenerator::isLocalConstant(const Identifier& ident)
+bool BytecodeGenerator::isLocalConstant(const Identifier& ident)
{
return symbolTable().get(ident.ustring().rep()).isReadOnly();
}
-RegisterID* CodeGenerator::newRegister()
+RegisterID* BytecodeGenerator::newRegister()
{
m_calleeRegisters.append(m_calleeRegisters.size());
- m_codeBlock->numCalleeRegisters = max<int>(m_codeBlock->numCalleeRegisters, m_calleeRegisters.size());
+ m_codeBlock->m_numCalleeRegisters = max<int>(m_codeBlock->m_numCalleeRegisters, m_calleeRegisters.size());
return &m_calleeRegisters.last();
}
-RegisterID* CodeGenerator::newTemporary()
+RegisterID* BytecodeGenerator::newTemporary()
{
// Reclaim free register IDs.
while (m_calleeRegisters.size() && !m_calleeRegisters.last().refCount())
@@ -440,15 +469,15 @@ RegisterID* CodeGenerator::newTemporary()
return result;
}
-RegisterID* CodeGenerator::highestUsedRegister()
+RegisterID* BytecodeGenerator::highestUsedRegister()
{
- size_t count = m_codeBlock->numCalleeRegisters;
+ size_t count = m_codeBlock->m_numCalleeRegisters;
while (m_calleeRegisters.size() < count)
newRegister();
return &m_calleeRegisters.last();
}
-PassRefPtr<LabelScope> CodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
+PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
{
// Reclaim free label scopes.
while (m_labelScopes.size() && !m_labelScopes.last().refCount())
@@ -460,7 +489,7 @@ PassRefPtr<LabelScope> CodeGenerator::newLabelScope(LabelScope::Type type, const
return &m_labelScopes.last();
}
-PassRefPtr<LabelID> CodeGenerator::newLabel()
+PassRefPtr<Label> BytecodeGenerator::newLabel()
{
// Reclaim free label IDs.
while (m_labels.size() && !m_labels.last().refCount())
@@ -471,23 +500,34 @@ PassRefPtr<LabelID> CodeGenerator::newLabel()
return &m_labels.last();
}
-PassRefPtr<LabelID> CodeGenerator::emitLabel(LabelID* l0)
+PassRefPtr<Label> BytecodeGenerator::emitLabel(Label* l0)
{
- l0->setLocation(instructions().size());
-
+ unsigned newLabelIndex = instructions().size();
+ l0->setLocation(newLabelIndex);
+
+ if (m_codeBlock->numberOfJumpTargets()) {
+ unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
+ ASSERT(lastLabelIndex <= newLabelIndex);
+ if (newLabelIndex == lastLabelIndex) {
+ // Peephole optimizations have already been disabled by emitting the last label
+ return l0;
+ }
+ }
+
+ m_codeBlock->addJumpTarget(newLabelIndex);
+
// This disables peephole optimizations when an instruction is a jump target
m_lastOpcodeID = op_end;
-
return l0;
}
-void CodeGenerator::emitOpcode(OpcodeID opcodeID)
+void BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
{
- instructions().append(globalData()->machine->getOpcode(opcodeID));
+ instructions().append(globalData()->interpreter->getOpcode(opcodeID));
m_lastOpcodeID = opcodeID;
}
-void CodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
+void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
{
ASSERT(instructions().size() >= 4);
size_t size = instructions().size();
@@ -496,7 +536,7 @@ void CodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src
src2Index = instructions().at(size - 1).u.operand;
}
-void CodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
+void BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
{
ASSERT(instructions().size() >= 3);
size_t size = instructions().size();
@@ -504,28 +544,28 @@ void CodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
srcIndex = instructions().at(size - 1).u.operand;
}
-void ALWAYS_INLINE CodeGenerator::rewindBinaryOp()
+void ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp()
{
ASSERT(instructions().size() >= 4);
instructions().shrink(instructions().size() - 4);
}
-void ALWAYS_INLINE CodeGenerator::rewindUnaryOp()
+void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
{
ASSERT(instructions().size() >= 3);
instructions().shrink(instructions().size() - 3);
}
-PassRefPtr<LabelID> CodeGenerator::emitJump(LabelID* target)
+PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
{
- emitOpcode(target->isForwardLabel() ? op_jmp : op_loop);
+ emitOpcode(target->isForward() ? op_jmp : op_loop);
instructions().append(target->offsetFrom(instructions().size()));
return target;
}
-PassRefPtr<LabelID> CodeGenerator::emitJumpIfTrue(RegisterID* cond, LabelID* target)
+PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target)
{
- if (m_lastOpcodeID == op_less && !target->isForwardLabel()) {
+ if (m_lastOpcodeID == op_less && !target->isForward()) {
int dstIndex;
int src1Index;
int src2Index;
@@ -540,7 +580,7 @@ PassRefPtr<LabelID> CodeGenerator::emitJumpIfTrue(RegisterID* cond, LabelID* tar
instructions().append(target->offsetFrom(instructions().size()));
return target;
}
- } else if (m_lastOpcodeID == op_lesseq && !target->isForwardLabel()) {
+ } else if (m_lastOpcodeID == op_lesseq && !target->isForward()) {
int dstIndex;
int src1Index;
int src2Index;
@@ -555,7 +595,7 @@ PassRefPtr<LabelID> CodeGenerator::emitJumpIfTrue(RegisterID* cond, LabelID* tar
instructions().append(target->offsetFrom(instructions().size()));
return target;
}
- } else if (m_lastOpcodeID == op_eq_null && target->isForwardLabel()) {
+ } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
int dstIndex;
int srcIndex;
@@ -568,7 +608,7 @@ PassRefPtr<LabelID> CodeGenerator::emitJumpIfTrue(RegisterID* cond, LabelID* tar
instructions().append(target->offsetFrom(instructions().size()));
return target;
}
- } else if (m_lastOpcodeID == op_neq_null && target->isForwardLabel()) {
+ } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
int dstIndex;
int srcIndex;
@@ -583,15 +623,15 @@ PassRefPtr<LabelID> CodeGenerator::emitJumpIfTrue(RegisterID* cond, LabelID* tar
}
}
- emitOpcode(target->isForwardLabel() ? op_jtrue : op_loop_if_true);
+ emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
instructions().append(cond->index());
instructions().append(target->offsetFrom(instructions().size()));
return target;
}
-PassRefPtr<LabelID> CodeGenerator::emitJumpIfFalse(RegisterID* cond, LabelID* target)
+PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target)
{
- ASSERT(target->isForwardLabel());
+ ASSERT(target->isForward());
if (m_lastOpcodeID == op_less) {
int dstIndex;
@@ -655,62 +695,54 @@ PassRefPtr<LabelID> CodeGenerator::emitJumpIfFalse(RegisterID* cond, LabelID* ta
return target;
}
-unsigned CodeGenerator::addConstant(FuncDeclNode* n)
+unsigned BytecodeGenerator::addConstant(FuncDeclNode* n)
{
// No need to explicitly unique function body nodes -- they're unique already.
- int index = m_codeBlock->functions.size();
- m_codeBlock->functions.append(n);
- return index;
+ return m_codeBlock->addFunction(n);
}
-unsigned CodeGenerator::addConstant(FuncExprNode* n)
+unsigned BytecodeGenerator::addConstant(FuncExprNode* n)
{
// No need to explicitly unique function expression nodes -- they're unique already.
- int index = m_codeBlock->functionExpressions.size();
- m_codeBlock->functionExpressions.append(n);
- return index;
+ return m_codeBlock->addFunctionExpression(n);
}
-unsigned CodeGenerator::addConstant(const Identifier& ident)
+unsigned BytecodeGenerator::addConstant(const Identifier& ident)
{
UString::Rep* rep = ident.ustring().rep();
- pair<IdentifierMap::iterator, bool> result = m_identifierMap.add(rep, m_codeBlock->identifiers.size());
+ pair<IdentifierMap::iterator, bool> result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
if (result.second) // new entry
- m_codeBlock->identifiers.append(Identifier(m_globalData, rep));
+ m_codeBlock->addIdentifier(Identifier(m_globalData, rep));
return result.first->second;
}
-RegisterID* CodeGenerator::addConstant(JSValue* v)
+RegisterID* BytecodeGenerator::addConstant(JSValuePtr v)
{
- pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(v, m_nextConstant);
+ pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValuePtr::encode(v), m_nextConstantIndex);
if (result.second) {
- RegisterID& constant = m_calleeRegisters[m_nextConstant];
+ RegisterID& constant = m_calleeRegisters[m_nextConstantIndex];
- ++m_nextConstant;
+ ++m_nextConstantIndex;
- m_codeBlock->constantRegisters.append(v);
+ m_codeBlock->addConstantRegister(JSValuePtr(v));
return &constant;
}
return &registerFor(result.first->second);
}
-unsigned CodeGenerator::addUnexpectedConstant(JSValue* v)
+unsigned BytecodeGenerator::addUnexpectedConstant(JSValuePtr v)
{
- int index = m_codeBlock->unexpectedConstants.size();
- m_codeBlock->unexpectedConstants.append(v);
- return index;
+ return m_codeBlock->addUnexpectedConstant(v);
}
-unsigned CodeGenerator::addRegExp(RegExp* r)
+unsigned BytecodeGenerator::addRegExp(RegExp* r)
{
- int index = m_codeBlock->regexps.size();
- m_codeBlock->regexps.append(r);
- return index;
+ return m_codeBlock->addRegExp(r);
}
-RegisterID* CodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
+RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
{
emitOpcode(op_mov);
instructions().append(dst->index());
@@ -718,31 +750,29 @@ RegisterID* CodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
return dst;
}
-RegisterID* CodeGenerator::emitUnaryOp(OpcodeID opcode, RegisterID* dst, RegisterID* src, ResultType type)
+RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
{
- emitOpcode(opcode);
+ emitOpcode(opcodeID);
instructions().append(dst->index());
instructions().append(src->index());
- if (opcode == op_negate)
- instructions().append(type.toInt());
return dst;
}
-RegisterID* CodeGenerator::emitPreInc(RegisterID* srcDst)
+RegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst)
{
emitOpcode(op_pre_inc);
instructions().append(srcDst->index());
return srcDst;
}
-RegisterID* CodeGenerator::emitPreDec(RegisterID* srcDst)
+RegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst)
{
emitOpcode(op_pre_dec);
instructions().append(srcDst->index());
return srcDst;
}
-RegisterID* CodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst)
+RegisterID* BytecodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst)
{
emitOpcode(op_post_inc);
instructions().append(dst->index());
@@ -750,7 +780,7 @@ RegisterID* CodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst)
return dst;
}
-RegisterID* CodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst)
+RegisterID* BytecodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst)
{
emitOpcode(op_post_dec);
instructions().append(dst->index());
@@ -758,22 +788,22 @@ RegisterID* CodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst)
return dst;
}
-RegisterID* CodeGenerator::emitBinaryOp(OpcodeID opcode, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
+RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
{
- emitOpcode(opcode);
+ emitOpcode(opcodeID);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
- if (opcode == op_bitor || opcode == op_bitand || opcode == op_bitxor ||
- opcode == op_add || opcode == op_mul || opcode == op_sub) {
+ if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
+ opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub) {
instructions().append(types.toInt());
}
return dst;
}
-RegisterID* CodeGenerator::emitEqualityOp(OpcodeID opcode, RegisterID* dst, RegisterID* src1, RegisterID* src2)
+RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
{
if (m_lastOpcodeID == op_typeof) {
int dstIndex;
@@ -783,14 +813,9 @@ RegisterID* CodeGenerator::emitEqualityOp(OpcodeID opcode, RegisterID* dst, Regi
if (src1->index() == dstIndex
&& src1->isTemporary()
- // FIXME: replace the following line by
- // && m_codeBlock->isConstant(src2->index())
- // after next merge:
- // see http://trac.webkit.org/changeset/38229
- // and http://trac.webkit.org/changeset/38230
- && (src2->index() >= m_codeBlock->numVars && src2->index() < m_codeBlock->numVars + m_codeBlock->numConstants)
- && m_codeBlock->constantRegisters[src2->index() - m_codeBlock->numVars].jsValue(m_scopeChain->globalObject()->globalExec())->isString()) {
- const UString& value = asString(m_codeBlock->constantRegisters[src2->index() - m_codeBlock->numVars].jsValue(m_scopeChain->globalObject()->globalExec()))->value();
+ && m_codeBlock->isConstantRegisterIndex(src2->index())
+ && m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue(m_scopeChain->globalObject()->globalExec()).isString()) {
+ const UString& value = asString(m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue(m_scopeChain->globalObject()->globalExec()))->value();
if (value == "undefined") {
rewindUnaryOp();
emitOpcode(op_is_undefined);
@@ -836,39 +861,39 @@ RegisterID* CodeGenerator::emitEqualityOp(OpcodeID opcode, RegisterID* dst, Regi
}
}
- emitOpcode(opcode);
+ emitOpcode(opcodeID);
instructions().append(dst->index());
instructions().append(src1->index());
instructions().append(src2->index());
return dst;
}
-RegisterID* CodeGenerator::emitLoad(RegisterID* dst, bool b)
+RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
{
return emitLoad(dst, jsBoolean(b));
}
-RegisterID* CodeGenerator::emitLoad(RegisterID* dst, double number)
+RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
{
// FIXME: Our hash tables won't hold infinity, so we make a new JSNumberCell each time.
// Later we can do the extra work to handle that like the other cases.
if (number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
return emitLoad(dst, jsNumber(globalData(), number));
- JSValue*& valueInMap = m_numberMap.add(number, noValue()).first->second;
+ JSValuePtr& valueInMap = m_numberMap.add(number, noValue()).first->second;
if (!valueInMap)
valueInMap = jsNumber(globalData(), number);
return emitLoad(dst, valueInMap);
}
-RegisterID* CodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
+RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
{
- JSString*& valueInMap = m_stringMap.add(identifier.ustring().rep(), 0).first->second;
- if (!valueInMap)
- valueInMap = jsOwnedString(globalData(), identifier.ustring());
- return emitLoad(dst, valueInMap);
+ JSString*& stringInMap = m_stringMap.add(identifier.ustring().rep(), 0).first->second;
+ if (!stringInMap)
+ stringInMap = jsOwnedString(globalData(), identifier.ustring());
+ return emitLoad(dst, JSValuePtr(stringInMap));
}
-RegisterID* CodeGenerator::emitLoad(RegisterID* dst, JSValue* v)
+RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValuePtr v)
{
RegisterID* constantID = addConstant(v);
if (dst)
@@ -876,13 +901,7 @@ RegisterID* CodeGenerator::emitLoad(RegisterID* dst, JSValue* v)
return constantID;
}
-RegisterID* CodeGenerator::emitLoad(RegisterID* dst, JSCell* cell)
-{
- JSValue* value = cell;
- return emitLoad(dst, value);
-}
-
-RegisterID* CodeGenerator::emitUnexpectedLoad(RegisterID* dst, bool b)
+RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, bool b)
{
emitOpcode(op_unexpected_load);
instructions().append(dst->index());
@@ -890,7 +909,7 @@ RegisterID* CodeGenerator::emitUnexpectedLoad(RegisterID* dst, bool b)
return dst;
}
-RegisterID* CodeGenerator::emitUnexpectedLoad(RegisterID* dst, double d)
+RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, double d)
{
emitOpcode(op_unexpected_load);
instructions().append(dst->index());
@@ -898,7 +917,7 @@ RegisterID* CodeGenerator::emitUnexpectedLoad(RegisterID* dst, double d)
return dst;
}
-bool CodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject)
+bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject)
{
// Cases where we cannot statically optimize the lookup.
if (property == propertyNames().arguments || !canOptimizeNonLocals()) {
@@ -952,7 +971,7 @@ bool CodeGenerator::findScopedProperty(const Identifier& property, int& index, s
return true;
}
-RegisterID* CodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype)
+RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype)
{
emitOpcode(op_instanceof);
instructions().append(dst->index());
@@ -962,7 +981,7 @@ RegisterID* CodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, Re
return dst;
}
-RegisterID* CodeGenerator::emitResolve(RegisterID* dst, const Identifier& property)
+RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& property)
{
size_t depth = 0;
int index = 0;
@@ -975,13 +994,26 @@ RegisterID* CodeGenerator::emitResolve(RegisterID* dst, const Identifier& proper
return dst;
}
- if (index != missingSymbolMarker()) {
- // Directly index the property lookup across multiple scopes. Yay!
- return emitGetScopedVar(dst, depth, index, globalObject);
- }
-
if (globalObject) {
- m_codeBlock->globalResolveInstructions.append(instructions().size());
+ bool forceGlobalResolve = false;
+ if (m_regeneratingForExceptionInfo) {
+#if ENABLE(JIT)
+ forceGlobalResolve = m_codeBlockBeingRegeneratedFrom->hasGlobalResolveInfoAtBytecodeOffset(instructions().size());
+#else
+ forceGlobalResolve = m_codeBlockBeingRegeneratedFrom->hasGlobalResolveInstructionAtBytecodeOffset(instructions().size());
+#endif
+ }
+
+ if (index != missingSymbolMarker() && !forceGlobalResolve) {
+ // Directly index the property lookup across multiple scopes.
+ return emitGetScopedVar(dst, depth, index, globalObject);
+ }
+
+#if ENABLE(JIT)
+ m_codeBlock->addGlobalResolveInfo(instructions().size());
+#else
+ m_codeBlock->addGlobalResolveInstruction(instructions().size());
+#endif
emitOpcode(op_resolve_global);
instructions().append(dst->index());
instructions().append(globalObject);
@@ -991,6 +1023,11 @@ RegisterID* CodeGenerator::emitResolve(RegisterID* dst, const Identifier& proper
return dst;
}
+ if (index != missingSymbolMarker()) {
+ // Directly index the property lookup across multiple scopes.
+ return emitGetScopedVar(dst, depth, index, globalObject);
+ }
+
// In this case we are at least able to drop a few scope chains from the
// lookup chain, although we still need to hash from then on.
emitOpcode(op_resolve_skip);
@@ -1000,7 +1037,7 @@ RegisterID* CodeGenerator::emitResolve(RegisterID* dst, const Identifier& proper
return dst;
}
-RegisterID* CodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValue* globalObject)
+RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValuePtr globalObject)
{
if (globalObject) {
emitOpcode(op_get_global_var);
@@ -1017,7 +1054,7 @@ RegisterID* CodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int i
return dst;
}
-RegisterID* CodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValue* globalObject)
+RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValuePtr globalObject)
{
if (globalObject) {
emitOpcode(op_put_global_var);
@@ -1033,7 +1070,7 @@ RegisterID* CodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID*
return value;
}
-RegisterID* CodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& property)
+RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& property)
{
emitOpcode(op_resolve_base);
instructions().append(dst->index());
@@ -1041,7 +1078,7 @@ RegisterID* CodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& pr
return dst;
}
-RegisterID* CodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
+RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
{
emitOpcode(op_resolve_with_base);
instructions().append(baseDst->index());
@@ -1050,7 +1087,7 @@ RegisterID* CodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID*
return baseDst;
}
-RegisterID* CodeGenerator::emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property)
+RegisterID* BytecodeGenerator::emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property)
{
emitOpcode(op_resolve_func);
instructions().append(baseDst->index());
@@ -1059,9 +1096,13 @@ RegisterID* CodeGenerator::emitResolveFunction(RegisterID* baseDst, RegisterID*
return baseDst;
}
-RegisterID* CodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
+RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
{
- m_codeBlock->propertyAccessInstructions.append(instructions().size());
+#if ENABLE(JIT)
+ m_codeBlock->addStructureStubInfo(StructureStubInfo(op_get_by_id));
+#else
+ m_codeBlock->addPropertyAccessInstruction(instructions().size());
+#endif
emitOpcode(op_get_by_id);
instructions().append(dst->index());
@@ -1074,9 +1115,13 @@ RegisterID* CodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const
return dst;
}
-RegisterID* CodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
+RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
{
- m_codeBlock->propertyAccessInstructions.append(instructions().size());
+#if ENABLE(JIT)
+ m_codeBlock->addStructureStubInfo(StructureStubInfo(op_put_by_id));
+#else
+ m_codeBlock->addPropertyAccessInstruction(instructions().size());
+#endif
emitOpcode(op_put_by_id);
instructions().append(base->index());
@@ -1089,7 +1134,7 @@ RegisterID* CodeGenerator::emitPutById(RegisterID* base, const Identifier& prope
return value;
}
-RegisterID* CodeGenerator::emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value)
+RegisterID* BytecodeGenerator::emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value)
{
emitOpcode(op_put_getter);
instructions().append(base->index());
@@ -1098,7 +1143,7 @@ RegisterID* CodeGenerator::emitPutGetter(RegisterID* base, const Identifier& pro
return value;
}
-RegisterID* CodeGenerator::emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value)
+RegisterID* BytecodeGenerator::emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value)
{
emitOpcode(op_put_setter);
instructions().append(base->index());
@@ -1107,7 +1152,7 @@ RegisterID* CodeGenerator::emitPutSetter(RegisterID* base, const Identifier& pro
return value;
}
-RegisterID* CodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
+RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
{
emitOpcode(op_del_by_id);
instructions().append(dst->index());
@@ -1116,7 +1161,7 @@ RegisterID* CodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, con
return dst;
}
-RegisterID* CodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
+RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
{
emitOpcode(op_get_by_val);
instructions().append(dst->index());
@@ -1125,7 +1170,7 @@ RegisterID* CodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, Regis
return dst;
}
-RegisterID* CodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
+RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
{
emitOpcode(op_put_by_val);
instructions().append(base->index());
@@ -1134,7 +1179,7 @@ RegisterID* CodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property,
return value;
}
-RegisterID* CodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
+RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
{
emitOpcode(op_del_by_val);
instructions().append(dst->index());
@@ -1143,7 +1188,7 @@ RegisterID* CodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, Re
return dst;
}
-RegisterID* CodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
+RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
{
emitOpcode(op_put_by_index);
instructions().append(base->index());
@@ -1152,20 +1197,22 @@ RegisterID* CodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, Regi
return value;
}
-RegisterID* CodeGenerator::emitNewObject(RegisterID* dst)
+RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
{
emitOpcode(op_new_object);
instructions().append(dst->index());
return dst;
}
-RegisterID* CodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
+RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
{
Vector<RefPtr<RegisterID>, 16> argv;
for (ElementNode* n = elements; n; n = n->next()) {
if (n->elision())
break;
argv.append(newTemporary());
+ // op_new_array requires the initial values to be a sequential range of registers
+ ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
emitNode(argv.last().get(), n->value());
}
emitOpcode(op_new_array);
@@ -1175,7 +1222,7 @@ RegisterID* CodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
return dst;
}
-RegisterID* CodeGenerator::emitNewFunction(RegisterID* dst, FuncDeclNode* n)
+RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FuncDeclNode* n)
{
emitOpcode(op_new_func);
instructions().append(dst->index());
@@ -1183,7 +1230,7 @@ RegisterID* CodeGenerator::emitNewFunction(RegisterID* dst, FuncDeclNode* n)
return dst;
}
-RegisterID* CodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
+RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
{
emitOpcode(op_new_regexp);
instructions().append(dst->index());
@@ -1192,7 +1239,7 @@ RegisterID* CodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
}
-RegisterID* CodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
+RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
{
emitOpcode(op_new_func_exp);
instructions().append(r0->index());
@@ -1200,27 +1247,43 @@ RegisterID* CodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNod
return r0;
}
-RegisterID* CodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
+RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
{
- return emitCall(op_call, dst, func, base, argumentsNode, divot, startOffset, endOffset);
+ return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
}
-RegisterID* CodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
+RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
{
- return emitCall(op_call_eval, dst, func, base, argumentsNode, divot, startOffset, endOffset);
+ return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
}
-RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
+RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
{
ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
ASSERT(func->refCount());
- ASSERT(!base || base->refCount());
-
+ ASSERT(thisRegister->refCount());
+
+ RegisterID* originalFunc = func;
+ if (m_shouldEmitProfileHooks) {
+ // If codegen decided to recycle func as this call's destination register,
+ // we need to undo that optimization here so that func will still be around
+ // for the sake of op_profile_did_call.
+ if (dst == func) {
+ RefPtr<RegisterID> movedThisRegister = emitMove(newTemporary(), thisRegister);
+ RefPtr<RegisterID> movedFunc = emitMove(thisRegister, func);
+
+ thisRegister = movedThisRegister.release().releaseRef();
+ func = movedFunc.release().releaseRef();
+ }
+ }
+
// Generate code for arguments.
Vector<RefPtr<RegisterID>, 16> argv;
- argv.append(newTemporary()); // reserve space for "this"
+ argv.append(thisRegister);
for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next.get()) {
argv.append(newTemporary());
+ // op_call requires the arguments to be a sequential range of registers
+ ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
emitNode(argv.last().get(), n);
}
@@ -1232,48 +1295,71 @@ RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Register
if (m_shouldEmitProfileHooks) {
emitOpcode(op_profile_will_call);
instructions().append(func->index());
+
+#if ENABLE(JIT)
+ m_codeBlock->addFunctionRegisterInfo(instructions().size(), func->index());
+#endif
}
emitExpressionInfo(divot, startOffset, endOffset);
- m_codeBlock->callLinkInfos.append(CallLinkInfo());
+
+#if ENABLE(JIT)
+ m_codeBlock->addCallLinkInfo();
+#endif
+
+ // Emit call.
emitOpcode(opcodeID);
- instructions().append(dst->index());
- instructions().append(func->index());
- instructions().append(base ? base->index() : missingThisObjectMarker()); // We encode the "this" value in the instruction stream, to avoid an explicit instruction for copying or loading it.
- instructions().append(argv[0]->index()); // argv
- instructions().append(argv.size()); // argc
+ instructions().append(dst->index()); // dst
+ instructions().append(func->index()); // func
+ instructions().append(argv.size()); // argCount
instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
if (m_shouldEmitProfileHooks) {
emitOpcode(op_profile_did_call);
instructions().append(func->index());
+
+ if (dst == originalFunc) {
+ thisRegister->deref();
+ func->deref();
+ }
}
return dst;
}
-RegisterID* CodeGenerator::emitReturn(RegisterID* src)
+RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
{
- if (m_codeBlock->needsFullScopeChain) {
+ if (m_codeBlock->needsFullScopeChain()) {
emitOpcode(op_tear_off_activation);
instructions().append(m_activationRegisterIndex);
- } else if (m_codeBlock->usesArguments && m_codeBlock->numParameters > 1)
+ } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1)
emitOpcode(op_tear_off_arguments);
return emitUnaryNoDstOp(op_ret, src);
}
-RegisterID* CodeGenerator::emitUnaryNoDstOp(OpcodeID opcode, RegisterID* src)
+RegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* src)
{
- emitOpcode(opcode);
+ emitOpcode(opcodeID);
instructions().append(src->index());
return src;
}
-RegisterID* CodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
+RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
{
ASSERT(func->refCount());
+ RegisterID* originalFunc = func;
+ if (m_shouldEmitProfileHooks) {
+ // If codegen decided to recycle func as this call's destination register,
+ // we need to undo that optimization here so that func will still be around
+ // for the sake of op_profile_did_call.
+ if (dst == func) {
+ RefPtr<RegisterID> movedFunc = emitMove(newTemporary(), func);
+ func = movedFunc.release().releaseRef();
+ }
+ }
+
RefPtr<RegisterID> funcProto = newTemporary();
// Generate code for arguments.
@@ -1281,6 +1367,8 @@ RegisterID* CodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, Argu
argv.append(newTemporary()); // reserve space for "this"
for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode.get() : 0; n; n = n->m_next.get()) {
argv.append(newTemporary());
+ // op_construct requires the arguments to be a sequential range of registers
+ ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
emitNode(argv.last().get(), n);
}
@@ -1291,6 +1379,7 @@ RegisterID* CodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, Argu
// Load prototype.
emitExpressionInfo(divot, startOffset, endOffset);
+ emitGetByIdExceptionInfo(op_construct);
emitGetById(funcProto.get(), func, globalData()->propertyNames->prototype);
// Reserve space for call frame.
@@ -1299,14 +1388,18 @@ RegisterID* CodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, Argu
callFrame.append(newTemporary());
emitExpressionInfo(divot, startOffset, endOffset);
- m_codeBlock->callLinkInfos.append(CallLinkInfo());
+
+#if ENABLE(JIT)
+ m_codeBlock->addCallLinkInfo();
+#endif
+
emitOpcode(op_construct);
- instructions().append(dst->index());
- instructions().append(func->index());
- instructions().append(funcProto->index());
- instructions().append(argv[0]->index()); // argv
- instructions().append(argv.size()); // argc
+ instructions().append(dst->index()); // dst
+ instructions().append(func->index()); // func
+ instructions().append(argv.size()); // argCount
instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
+ instructions().append(funcProto->index()); // proto
+ instructions().append(argv[0]->index()); // thisRegister
emitOpcode(op_construct_verify);
instructions().append(dst->index());
@@ -1315,13 +1408,17 @@ RegisterID* CodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, Argu
if (m_shouldEmitProfileHooks) {
emitOpcode(op_profile_did_call);
instructions().append(func->index());
+
+ if (dst == originalFunc)
+ func->deref();
}
return dst;
}
-RegisterID* CodeGenerator::emitPushScope(RegisterID* scope)
+RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope)
{
+ ASSERT(scope->isTemporary());
ControlFlowContext context;
context.isFinallyBlock = false;
m_scopeContextStack.append(context);
@@ -1330,7 +1427,7 @@ RegisterID* CodeGenerator::emitPushScope(RegisterID* scope)
return emitUnaryNoDstOp(op_push_scope, scope);
}
-void CodeGenerator::emitPopScope()
+void BytecodeGenerator::emitPopScope()
{
ASSERT(m_scopeContextStack.size());
ASSERT(!m_scopeContextStack.last().isFinallyBlock);
@@ -1341,7 +1438,7 @@ void CodeGenerator::emitPopScope()
m_dynamicScopeDepth--;
}
-void CodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
+void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
{
if (!m_shouldEmitDebugHooks)
return;
@@ -1351,7 +1448,7 @@ void CodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int la
instructions().append(lastLine);
}
-void CodeGenerator::pushFinallyContext(LabelID* target, RegisterID* retAddrDst)
+void BytecodeGenerator::pushFinallyContext(Label* target, RegisterID* retAddrDst)
{
ControlFlowContext scope;
scope.isFinallyBlock = true;
@@ -1361,7 +1458,7 @@ void CodeGenerator::pushFinallyContext(LabelID* target, RegisterID* retAddrDst)
m_finallyDepth++;
}
-void CodeGenerator::popFinallyContext()
+void BytecodeGenerator::popFinallyContext()
{
ASSERT(m_scopeContextStack.size());
ASSERT(m_scopeContextStack.last().isFinallyBlock);
@@ -1370,7 +1467,7 @@ void CodeGenerator::popFinallyContext()
m_finallyDepth--;
}
-LabelScope* CodeGenerator::breakTarget(const Identifier& name)
+LabelScope* BytecodeGenerator::breakTarget(const Identifier& name)
{
// Reclaim free label scopes.
while (m_labelScopes.size() && !m_labelScopes.last().refCount())
@@ -1403,7 +1500,7 @@ LabelScope* CodeGenerator::breakTarget(const Identifier& name)
return 0;
}
-LabelScope* CodeGenerator::continueTarget(const Identifier& name)
+LabelScope* BytecodeGenerator::continueTarget(const Identifier& name)
{
// Reclaim free label scopes.
while (m_labelScopes.size() && !m_labelScopes.last().refCount())
@@ -1438,7 +1535,7 @@ LabelScope* CodeGenerator::continueTarget(const Identifier& name)
return 0;
}
-PassRefPtr<LabelID> CodeGenerator::emitComplexJumpScopes(LabelID* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
+PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
{
while (topScope > bottomScope) {
// First we count the number of dynamic scopes we need to remove to get
@@ -1466,7 +1563,7 @@ PassRefPtr<LabelID> CodeGenerator::emitComplexJumpScopes(LabelID* target, Contro
// Otherwise we just use jmp_scopes to pop a group of scopes and go
// to the next instruction
- RefPtr<LabelID> nextInsn = newLabel();
+ RefPtr<Label> nextInsn = newLabel();
instructions().append(nextInsn->offsetFrom(instructions().size()));
emitLabel(nextInsn.get());
}
@@ -1483,10 +1580,10 @@ PassRefPtr<LabelID> CodeGenerator::emitComplexJumpScopes(LabelID* target, Contro
return emitJump(target);
}
-PassRefPtr<LabelID> CodeGenerator::emitJumpScopes(LabelID* target, int targetScopeDepth)
+PassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetScopeDepth)
{
ASSERT(scopeDepth() - targetScopeDepth >= 0);
- ASSERT(target->isForwardLabel());
+ ASSERT(target->isForward());
size_t scopeDelta = scopeDepth() - targetScopeDepth;
ASSERT(scopeDelta <= m_scopeContextStack.size());
@@ -1502,7 +1599,7 @@ PassRefPtr<LabelID> CodeGenerator::emitJumpScopes(LabelID* target, int targetSco
return target;
}
-RegisterID* CodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* iter, LabelID* target)
+RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target)
{
emitOpcode(op_next_pname);
instructions().append(dst->index());
@@ -1511,16 +1608,21 @@ RegisterID* CodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* ite
return dst;
}
-RegisterID* CodeGenerator::emitCatch(RegisterID* targetRegister, LabelID* start, LabelID* end)
+RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
{
- HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth, 0 };
- exceptionHandlers().append(info);
+#if ENABLE(JIT)
+ HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, 0 };
+#else
+ HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
+#endif
+
+ m_codeBlock->addExceptionHandler(info);
emitOpcode(op_catch);
instructions().append(targetRegister->index());
return targetRegister;
}
-RegisterID* CodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSValue* message)
+RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSValuePtr message)
{
emitOpcode(op_new_error);
instructions().append(dst->index());
@@ -1529,7 +1631,7 @@ RegisterID* CodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSValue
return dst;
}
-PassRefPtr<LabelID> CodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, LabelID* finally)
+PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally)
{
emitOpcode(op_jsr);
instructions().append(retAddrDst->index());
@@ -1537,13 +1639,13 @@ PassRefPtr<LabelID> CodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, La
return finally;
}
-void CodeGenerator::emitSubroutineReturn(RegisterID* retAddrSrc)
+void BytecodeGenerator::emitSubroutineReturn(RegisterID* retAddrSrc)
{
emitOpcode(op_sret);
instructions().append(retAddrSrc->index());
}
-void CodeGenerator::emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value)
+void BytecodeGenerator::emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value)
{
ControlFlowContext context;
context.isFinallyBlock = false;
@@ -1556,7 +1658,7 @@ void CodeGenerator::emitPushNewScope(RegisterID* dst, Identifier& property, Regi
instructions().append(value->index());
}
-void CodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
+void BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
{
SwitchInfo info = { instructions().size(), type };
switch (type) {
@@ -1584,15 +1686,15 @@ static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t
UNUSED_PARAM(max);
ASSERT(node->isNumber());
double value = static_cast<NumberNode*>(node)->value();
- ASSERT(JSImmediate::from(value));
int32_t key = static_cast<int32_t>(value);
+ ASSERT(JSValuePtr::makeInt32Fast(key) && (JSValuePtr::makeInt32Fast(key).getInt32Fast() == value));
ASSERT(key == value);
ASSERT(key >= min);
ASSERT(key <= max);
return key - min;
}
-static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<LabelID>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
+static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
{
jumpTable.min = min;
jumpTable.branchOffsets.resize(max - min + 1);
@@ -1600,7 +1702,7 @@ static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32
for (uint32_t i = 0; i < clauseCount; ++i) {
// We're emitting this after the clause labels should have been fixed, so
// the labels should not be "forward" references
- ASSERT(!labels[i]->isForwardLabel());
+ ASSERT(!labels[i]->isForward());
jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress));
}
}
@@ -1618,7 +1720,7 @@ static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t
return key - min;
}
-static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<LabelID>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
+static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
{
jumpTable.min = min;
jumpTable.branchOffsets.resize(max - min + 1);
@@ -1626,59 +1728,65 @@ static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32
for (uint32_t i = 0; i < clauseCount; ++i) {
// We're emitting this after the clause labels should have been fixed, so
// the labels should not be "forward" references
- ASSERT(!labels[i]->isForwardLabel());
+ ASSERT(!labels[i]->isForward());
jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress));
}
}
-static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<LabelID>* labels, ExpressionNode** nodes)
+static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes)
{
for (uint32_t i = 0; i < clauseCount; ++i) {
// We're emitting this after the clause labels should have been fixed, so
// the labels should not be "forward" references
- ASSERT(!labels[i]->isForwardLabel());
+ ASSERT(!labels[i]->isForward());
ASSERT(nodes[i]->isString());
UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep();
OffsetLocation location;
location.branchOffset = labels[i]->offsetFrom(switchAddress);
-#if ENABLE(CTI)
+#if ENABLE(JIT)
location.ctiOffset = 0;
#endif
jumpTable.offsetTable.add(clause, location);
}
}
-void CodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<LabelID>* labels, ExpressionNode** nodes, LabelID* defaultLabel, int32_t min, int32_t max)
+void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, Label* defaultLabel, int32_t min, int32_t max)
{
SwitchInfo switchInfo = m_switchContextStack.last();
m_switchContextStack.removeLast();
if (switchInfo.switchType == SwitchInfo::SwitchImmediate) {
- instructions()[switchInfo.opcodeOffset + 1] = m_codeBlock->immediateSwitchJumpTables.size();
- instructions()[switchInfo.opcodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.opcodeOffset + 3);
-
- m_codeBlock->immediateSwitchJumpTables.append(SimpleJumpTable());
- SimpleJumpTable& jumpTable = m_codeBlock->immediateSwitchJumpTables.last();
+ instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables();
+ instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
- prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.opcodeOffset + 3, clauseCount, labels, nodes, min, max);
+ SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable();
+ prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max);
} else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) {
- instructions()[switchInfo.opcodeOffset + 1] = m_codeBlock->characterSwitchJumpTables.size();
- instructions()[switchInfo.opcodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.opcodeOffset + 3);
+ instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables();
+ instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
- m_codeBlock->characterSwitchJumpTables.append(SimpleJumpTable());
- SimpleJumpTable& jumpTable = m_codeBlock->characterSwitchJumpTables.last();
-
- prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.opcodeOffset + 3, clauseCount, labels, nodes, min, max);
+ SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable();
+ prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max);
} else {
ASSERT(switchInfo.switchType == SwitchInfo::SwitchString);
- instructions()[switchInfo.opcodeOffset + 1] = m_codeBlock->stringSwitchJumpTables.size();
- instructions()[switchInfo.opcodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.opcodeOffset + 3);
-
- m_codeBlock->stringSwitchJumpTables.append(StringJumpTable());
- StringJumpTable& jumpTable = m_codeBlock->stringSwitchJumpTables.last();
+ instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables();
+ instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
- prepareJumpTableForStringSwitch(jumpTable, switchInfo.opcodeOffset + 3, clauseCount, labels, nodes);
+ StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
+ prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes);
}
}
+RegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException()
+{
+ // It would be nice to do an even better job of identifying exactly where the expression is.
+ // And we could make the caller pass the node pointer in, if there was some way of getting
+ // that from an arbitrary node. However, calling emitExpressionInfo without any useful data
+ // is still good enough to get us an accurate line number.
+ emitExpressionInfo(0, 0, 0);
+ RegisterID* exception = emitNewError(newTemporary(), SyntaxError, jsString(globalData(), "Expression too deep"));
+ emitThrow(exception);
+ return exception;
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/VM/CodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 75fc0a5..ceb5881 100644
--- a/JavaScriptCore/VM/CodeGenerator.h
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
*
* Redistribution and use in source and binary forms, with or without
@@ -27,20 +27,20 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CodeGenerator_h
-#define CodeGenerator_h
+#ifndef BytecodeGenerator_h
+#define BytecodeGenerator_h
#include "CodeBlock.h"
#include "HashTraits.h"
#include "Instruction.h"
-#include "LabelID.h"
+#include "Label.h"
#include "LabelScope.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "RegisterID.h"
#include "SegmentedVector.h"
#include "SymbolTable.h"
#include "Debugger.h"
-#include "nodes.h"
+#include "Nodes.h"
#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
@@ -51,7 +51,7 @@ namespace JSC {
class ScopeNode;
struct FinallyContext {
- LabelID* finallyAddr;
+ Label* finallyAddr;
RegisterID* retAddrDst;
};
@@ -60,16 +60,17 @@ namespace JSC {
FinallyContext finallyContext;
};
- class CodeGenerator {
+ class BytecodeGenerator {
public:
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
static void setDumpsGeneratedCode(bool dumpsGeneratedCode);
+ static bool dumpsGeneratedCode();
- CodeGenerator(ProgramNode*, const Debugger*, const ScopeChain&, SymbolTable*, CodeBlock*, VarStack&, FunctionStack&);
- CodeGenerator(FunctionBodyNode*, const Debugger*, const ScopeChain&, SymbolTable*, CodeBlock*);
- CodeGenerator(EvalNode*, const Debugger*, const ScopeChain&, SymbolTable*, EvalCodeBlock*);
+ BytecodeGenerator(ProgramNode*, const Debugger*, const ScopeChain&, SymbolTable*, ProgramCodeBlock*);
+ BytecodeGenerator(FunctionBodyNode*, const Debugger*, const ScopeChain&, SymbolTable*, CodeBlock*);
+ BytecodeGenerator(EvalNode*, const Debugger*, const ScopeChain&, SymbolTable*, EvalCodeBlock*);
JSGlobalData* globalData() const { return m_globalData; }
const CommonIdentifiers& propertyNames() const { return *m_globalData->propertyNames; }
@@ -118,6 +119,8 @@ namespace JSC {
// Functions for handling of dst register
+ RegisterID* ignoredResult() { return &m_ignoredResultRegister; }
+
// Returns a place to write intermediate values of an operation
// which reuses dst if it is safe to do so.
RegisterID* tempDestination(RegisterID* dst)
@@ -138,7 +141,7 @@ namespace JSC {
RegisterID* destinationForAssignResult(RegisterID* dst)
{
- if (dst && dst != ignoredResult() && m_codeBlock->needsFullScopeChain)
+ if (dst && dst != ignoredResult() && m_codeBlock->needsFullScopeChain())
return dst->isTemporary() ? dst : newTemporary();
return 0;
}
@@ -150,7 +153,7 @@ namespace JSC {
}
PassRefPtr<LabelScope> newLabelScope(LabelScope::Type, const Identifier* = 0);
- PassRefPtr<LabelID> newLabel();
+ PassRefPtr<Label> newLabel();
// The emitNode functions are just syntactic sugar for calling
// Node::emitCode. These functions accept a 0 for the register,
@@ -161,11 +164,16 @@ namespace JSC {
{
// Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
- if (!m_codeBlock->lineInfo.size() || m_codeBlock->lineInfo.last().lineNumber != n->lineNo()) {
+ if (!m_codeBlock->numberOfLineInfos() || m_codeBlock->lastLineInfo().lineNumber != n->lineNo()) {
LineInfo info = { instructions().size(), n->lineNo() };
- m_codeBlock->lineInfo.append(info);
+ m_codeBlock->addLineInfo(info);
}
- return n->emitCode(*this, dst);
+ if (m_emitNodeDepth >= s_maxEmitNodeDepth)
+ return emitThrowExpressionTooDeepException();
+ ++m_emitNodeDepth;
+ RegisterID* r = n->emitBytecode(*this, dst);
+ --m_emitNodeDepth;
+ return r;
}
RegisterID* emitNode(Node* n)
@@ -175,7 +183,7 @@ namespace JSC {
void emitExpressionInfo(unsigned divot, unsigned startOffset, unsigned endOffset)
{
- divot -= m_codeBlock->sourceOffset;
+ divot -= m_codeBlock->sourceOffset();
if (divot > ExpressionRangeInfo::MaxDivot) {
// Overflow has occurred, we can only give line number info for errors for this region
divot = 0;
@@ -199,12 +207,23 @@ namespace JSC {
info.divotPoint = divot;
info.startOffset = startOffset;
info.endOffset = endOffset;
- m_codeBlock->expressionInfo.append(info);
+ m_codeBlock->addExpressionInfo(info);
+ }
+
+ void emitGetByIdExceptionInfo(OpcodeID opcodeID)
+ {
+ // Only op_construct and op_instanceof need exception info for
+ // a preceding op_get_by_id.
+ ASSERT(opcodeID == op_construct || opcodeID == op_instanceof);
+ GetByIdExceptionInfo info;
+ info.bytecodeOffset = instructions().size();
+ info.isOpConstruct = (opcodeID == op_construct);
+ m_codeBlock->addGetByIdExceptionInfo(info);
}
ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsPure)
{
- return (m_codeType != FunctionCode || m_codeBlock->needsFullScopeChain || rightHasAssignments) && !rightIsPure;
+ return (m_codeType != FunctionCode || m_codeBlock->needsFullScopeChain() || rightHasAssignments) && !rightIsPure;
}
ALWAYS_INLINE PassRefPtr<RegisterID> emitNodeForLeftHandSide(ExpressionNode* n, bool rightHasAssignments, bool rightIsPure)
@@ -221,12 +240,11 @@ namespace JSC {
RegisterID* emitLoad(RegisterID* dst, bool);
RegisterID* emitLoad(RegisterID* dst, double);
RegisterID* emitLoad(RegisterID* dst, const Identifier&);
- RegisterID* emitLoad(RegisterID* dst, JSValue*);
- RegisterID* emitLoad(RegisterID* dst, JSCell*);
+ RegisterID* emitLoad(RegisterID* dst, JSValuePtr);
RegisterID* emitUnexpectedLoad(RegisterID* dst, bool);
RegisterID* emitUnexpectedLoad(RegisterID* dst, double);
- RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, ResultType);
+ RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes);
RegisterID* emitEqualityOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2);
RegisterID* emitUnaryNoDstOp(OpcodeID, RegisterID* src);
@@ -240,19 +258,19 @@ namespace JSC {
RegisterID* emitMove(RegisterID* dst, RegisterID* src);
- RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src, ResultType::unknown()); }
+ RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src); }
RegisterID* emitPreInc(RegisterID* srcDst);
RegisterID* emitPreDec(RegisterID* srcDst);
RegisterID* emitPostInc(RegisterID* dst, RegisterID* srcDst);
RegisterID* emitPostDec(RegisterID* dst, RegisterID* srcDst);
RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype);
- RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src, ResultType::unknown()); }
+ RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); }
RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); }
RegisterID* emitResolve(RegisterID* dst, const Identifier& property);
- RegisterID* emitGetScopedVar(RegisterID* dst, size_t skip, int index, JSValue* globalObject);
- RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value, JSValue* globalObject);
+ RegisterID* emitGetScopedVar(RegisterID* dst, size_t skip, int index, JSValuePtr globalObject);
+ RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value, JSValuePtr globalObject);
RegisterID* emitResolveBase(RegisterID* dst, const Identifier& property);
RegisterID* emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property);
@@ -268,29 +286,29 @@ namespace JSC {
RegisterID* emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value);
RegisterID* emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value);
- RegisterID* emitCall(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
- RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ RegisterID* emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
RegisterID* emitReturn(RegisterID* src);
RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); }
RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
- PassRefPtr<LabelID> emitLabel(LabelID*);
- PassRefPtr<LabelID> emitJump(LabelID* target);
- PassRefPtr<LabelID> emitJumpIfTrue(RegisterID* cond, LabelID* target);
- PassRefPtr<LabelID> emitJumpIfFalse(RegisterID* cond, LabelID* target);
- PassRefPtr<LabelID> emitJumpScopes(LabelID* target, int targetScopeDepth);
+ PassRefPtr<Label> emitLabel(Label*);
+ PassRefPtr<Label> emitJump(Label* target);
+ PassRefPtr<Label> emitJumpIfTrue(RegisterID* cond, Label* target);
+ PassRefPtr<Label> emitJumpIfFalse(RegisterID* cond, Label* target);
+ PassRefPtr<Label> emitJumpScopes(Label* target, int targetScopeDepth);
- PassRefPtr<LabelID> emitJumpSubroutine(RegisterID* retAddrDst, LabelID*);
+ PassRefPtr<Label> emitJumpSubroutine(RegisterID* retAddrDst, Label*);
void emitSubroutineReturn(RegisterID* retAddrSrc);
- RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base, ResultType::unknown()); }
- RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, LabelID* target);
+ RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base); }
+ RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target);
- RegisterID* emitCatch(RegisterID*, LabelID* start, LabelID* end);
+ RegisterID* emitCatch(RegisterID*, Label* start, Label* end);
void emitThrow(RegisterID* exc) { emitUnaryNoDstOp(op_throw, exc); }
- RegisterID* emitNewError(RegisterID* dst, ErrorType type, JSValue* message);
+ RegisterID* emitNewError(RegisterID* dst, ErrorType type, JSValuePtr message);
void emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value);
RegisterID* emitPushScope(RegisterID* scope);
@@ -300,17 +318,23 @@ namespace JSC {
int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; }
- void pushFinallyContext(LabelID* target, RegisterID* returnAddrDst);
+ void pushFinallyContext(Label* target, RegisterID* returnAddrDst);
void popFinallyContext();
LabelScope* breakTarget(const Identifier&);
LabelScope* continueTarget(const Identifier&);
void beginSwitch(RegisterID*, SwitchInfo::SwitchType);
- void endSwitch(uint32_t clauseCount, RefPtr<LabelID>*, ExpressionNode**, LabelID* defaultLabel, int32_t min, int32_t range);
+ void endSwitch(uint32_t clauseCount, RefPtr<Label>*, ExpressionNode**, Label* defaultLabel, int32_t min, int32_t range);
CodeType codeType() const { return m_codeType; }
+ void setRegeneratingForExceptionInfo(CodeBlock* originalCodeBlock)
+ {
+ m_regeneratingForExceptionInfo = true;
+ m_codeBlockBeingRegeneratedFrom = originalCodeBlock;
+ }
+
private:
void emitOpcode(OpcodeID);
void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
@@ -318,14 +342,14 @@ namespace JSC {
void rewindBinaryOp();
void rewindUnaryOp();
- PassRefPtr<LabelID> emitComplexJumpScopes(LabelID* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
+ PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
- struct JSValueHashTraits : HashTraits<JSValue*> {
- static void constructDeletedValue(JSValue*& slot) { slot = JSImmediate::impossibleValue(); }
- static bool isDeletedValue(JSValue* value) { return value == JSImmediate::impossibleValue(); }
+ struct JSValueHashTraits : HashTraits<JSValueEncodedAsPointer*> {
+ static void constructDeletedValue(JSValueEncodedAsPointer*& slot) { slot = JSValuePtr::encode(jsImpossibleValue()); }
+ static bool isDeletedValue(JSValueEncodedAsPointer* value) { return value == JSValuePtr::encode(jsImpossibleValue()); }
};
- typedef HashMap<JSValue*, unsigned, PtrHash<JSValue*>, JSValueHashTraits> JSValueMap;
+ typedef HashMap<JSValueEncodedAsPointer*, unsigned, PtrHash<JSValueEncodedAsPointer*>, JSValueHashTraits> JSValueMap;
struct IdentifierMapIndexHashTraits {
typedef int TraitType;
@@ -337,10 +361,10 @@ namespace JSC {
};
typedef HashMap<RefPtr<UString::Rep>, int, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, IdentifierMapIndexHashTraits> IdentifierMap;
- typedef HashMap<double, JSValue*> NumberMap;
+ typedef HashMap<double, JSValuePtr> NumberMap;
typedef HashMap<UString::Rep*, JSString*, IdentifierRepHash> IdentifierStringMap;
- RegisterID* emitCall(OpcodeID, RegisterID*, RegisterID*, RegisterID*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
RegisterID* newRegister();
@@ -387,17 +411,17 @@ namespace JSC {
unsigned addConstant(FuncDeclNode*);
unsigned addConstant(FuncExprNode*);
unsigned addConstant(const Identifier&);
- RegisterID* addConstant(JSValue*);
- unsigned addUnexpectedConstant(JSValue*);
+ RegisterID* addConstant(JSValuePtr);
+ unsigned addUnexpectedConstant(JSValuePtr);
unsigned addRegExp(RegExp*);
- StructureID* addStructureID();
- Vector<Instruction>& instructions() { return m_codeBlock->instructions; }
+ Vector<Instruction>& instructions() { return m_codeBlock->instructions(); }
SymbolTable& symbolTable() { return *m_symbolTable; }
- Vector<HandlerInfo>& exceptionHandlers() { return m_codeBlock->exceptionHandlers; }
bool shouldOptimizeLocals() { return (m_codeType != EvalCode) && !m_dynamicScopeDepth; }
- bool canOptimizeNonLocals() { return (m_codeType == FunctionCode) && !m_dynamicScopeDepth && !m_codeBlock->usesEval; }
+ bool canOptimizeNonLocals() { return (m_codeType == FunctionCode) && !m_dynamicScopeDepth && !m_codeBlock->usesEval(); }
+
+ RegisterID* emitThrowExpressionTooDeepException();
bool m_shouldEmitDebugHooks;
bool m_shouldEmitProfileHooks;
@@ -409,6 +433,7 @@ namespace JSC {
CodeBlock* m_codeBlock;
HashSet<RefPtr<UString::Rep>, IdentifierRepHash> m_functions;
+ RegisterID m_ignoredResultRegister;
RegisterID m_thisRegister;
RegisterID m_argumentsRegister;
int m_activationRegisterIndex;
@@ -416,18 +441,19 @@ namespace JSC {
SegmentedVector<RegisterID, 512> m_parameters;
SegmentedVector<RegisterID, 512> m_globals;
SegmentedVector<LabelScope, 256> m_labelScopes;
- SegmentedVector<LabelID, 256> m_labels;
+ SegmentedVector<Label, 256> m_labels;
RefPtr<RegisterID> m_lastConstant;
int m_finallyDepth;
int m_dynamicScopeDepth;
+ int m_baseScopeDepth;
CodeType m_codeType;
Vector<ControlFlowContext> m_scopeContextStack;
Vector<SwitchInfo> m_switchContextStack;
- int m_nextGlobal;
- int m_nextParameter;
- int m_nextConstant;
+ int m_nextGlobalIndex;
+ int m_nextParameterIndex;
+ int m_nextConstantIndex;
int m_globalVarStorageOffset;
@@ -441,11 +467,14 @@ namespace JSC {
OpcodeID m_lastOpcodeID;
-#ifndef NDEBUG
- static bool s_dumpsGeneratedCode;
-#endif
+ unsigned m_emitNodeDepth;
+
+ bool m_regeneratingForExceptionInfo;
+ CodeBlock* m_codeBlockBeingRegeneratedFrom;
+
+ static const unsigned s_maxEmitNodeDepth = 10000;
};
}
-#endif // CodeGenerator_h
+#endif // BytecodeGenerator_h
diff --git a/JavaScriptCore/VM/LabelID.h b/JavaScriptCore/bytecompiler/Label.h
index 6bcac26..0b3d038 100644
--- a/JavaScriptCore/VM/LabelID.h
+++ b/JavaScriptCore/bytecompiler/Label.h
@@ -26,8 +26,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef LabelID_h
-#define LabelID_h
+#ifndef Label_h
+#define Label_h
#include "CodeBlock.h"
#include "Instruction.h"
@@ -37,46 +37,28 @@
namespace JSC {
- class LabelID {
+ class Label {
public:
- explicit LabelID(CodeBlock* codeBlock)
+ explicit Label(CodeBlock* codeBlock)
: m_refCount(0)
, m_location(invalidLocation)
, m_codeBlock(codeBlock)
{
}
- // It doesn't really make sense to copy a LabelID, but we need this copy
- // constructor to support moving LabelIDs in a Vector.
-
- LabelID(const LabelID& other)
- : m_refCount(other.m_refCount)
- , m_location(other.m_location)
- , m_codeBlock(other.m_codeBlock)
- , m_unresolvedJumps(other.m_unresolvedJumps)
- {
- #ifndef NDEBUG
- const_cast<LabelID&>(other).m_codeBlock = 0;
- #endif
- }
-
void setLocation(unsigned location)
{
- ASSERT(m_codeBlock);
m_location = location;
unsigned size = m_unresolvedJumps.size();
for (unsigned i = 0; i < size; ++i) {
unsigned j = m_unresolvedJumps[i];
- m_codeBlock->instructions[j].u.operand = m_location - j;
+ m_codeBlock->instructions()[j].u.operand = m_location - j;
}
-
- m_codeBlock->labels.add(location);
}
int offsetFrom(int location) const
{
- ASSERT(m_codeBlock);
if (m_location == invalidLocation) {
m_unresolvedJumps.append(location);
return 0;
@@ -84,23 +66,15 @@ namespace JSC {
return m_location - location;
}
- void ref()
- {
- ++m_refCount;
- }
-
+ void ref() { ++m_refCount; }
void deref()
{
--m_refCount;
ASSERT(m_refCount >= 0);
}
+ int refCount() const { return m_refCount; }
- int refCount() const
- {
- return m_refCount;
- }
-
- bool isForwardLabel() const { return m_location == invalidLocation; }
+ bool isForward() const { return m_location == invalidLocation; }
private:
typedef Vector<int, 8> JumpVector;
@@ -115,4 +89,4 @@ namespace JSC {
} // namespace JSC
-#endif // LabelID_h
+#endif // Label_h
diff --git a/JavaScriptCore/kjs/LabelScope.h b/JavaScriptCore/bytecompiler/LabelScope.h
index 8c30be5..cc21fff 100644
--- a/JavaScriptCore/kjs/LabelScope.h
+++ b/JavaScriptCore/bytecompiler/LabelScope.h
@@ -30,7 +30,7 @@
#define LabelScope_h
#include <wtf/PassRefPtr.h>
-#include "LabelID.h"
+#include "Label.h"
namespace JSC {
@@ -40,7 +40,7 @@ namespace JSC {
public:
enum Type { Loop, Switch, NamedLabel };
- LabelScope(Type type, const Identifier* name, int scopeDepth, PassRefPtr<LabelID> breakTarget, PassRefPtr<LabelID> continueTarget)
+ LabelScope(Type type, const Identifier* name, int scopeDepth, PassRefPtr<Label> breakTarget, PassRefPtr<Label> continueTarget)
: m_refCount(0)
, m_type(type)
, m_name(name)
@@ -50,19 +50,6 @@ namespace JSC {
{
}
- // It doesn't really make sense to copy a LabelScope, but we need this copy
- // constructor to support moving LabelScopes in a Vector.
-
- LabelScope(const LabelScope& other)
- : m_refCount(other.m_refCount)
- , m_type(other.m_type)
- , m_name(other.m_name)
- , m_scopeDepth(other.m_scopeDepth)
- , m_breakTarget(other.m_breakTarget)
- , m_continueTarget(other.m_continueTarget)
- {
- }
-
void ref() { ++m_refCount; }
void deref()
{
@@ -71,8 +58,8 @@ namespace JSC {
}
int refCount() const { return m_refCount; }
- LabelID* breakTarget() const { return m_breakTarget.get(); }
- LabelID* continueTarget() const { return m_continueTarget.get(); }
+ Label* breakTarget() const { return m_breakTarget.get(); }
+ Label* continueTarget() const { return m_continueTarget.get(); }
Type type() const { return m_type; }
const Identifier* name() const { return m_name; }
@@ -83,8 +70,8 @@ namespace JSC {
Type m_type;
const Identifier* m_name;
int m_scopeDepth;
- RefPtr<LabelID> m_breakTarget;
- RefPtr<LabelID> m_continueTarget;
+ RefPtr<Label> m_breakTarget;
+ RefPtr<Label> m_continueTarget;
};
} // namespace JSC
diff --git a/JavaScriptCore/VM/RegisterID.h b/JavaScriptCore/bytecompiler/RegisterID.h
index bff653b..0223c2a 100644
--- a/JavaScriptCore/VM/RegisterID.h
+++ b/JavaScriptCore/bytecompiler/RegisterID.h
@@ -107,8 +107,6 @@ namespace JSC {
#endif
};
- inline RegisterID* ignoredResult() { return reinterpret_cast<RegisterID*>(1); }
-
} // namespace JSC
namespace WTF {
diff --git a/JavaScriptCore/VM/SegmentedVector.h b/JavaScriptCore/bytecompiler/SegmentedVector.h
index bbab04f..bbab04f 100644
--- a/JavaScriptCore/VM/SegmentedVector.h
+++ b/JavaScriptCore/bytecompiler/SegmentedVector.h
diff --git a/JavaScriptCore/kjs/config.h b/JavaScriptCore/config.h
index 53bc0a9..a85178c 100644
--- a/JavaScriptCore/kjs/config.h
+++ b/JavaScriptCore/config.h
@@ -25,11 +25,6 @@
#include <wtf/Platform.h>
-#if PLATFORM(ANDROID)
-
-#define ANDROID_MOBILE // change can be merged back to WebKit.org for MOBILE
-#endif
-
#if PLATFORM(WIN_OS)
// If we don't define these, they get defined in windef.h.
@@ -37,7 +32,7 @@
#define max max
#define min min
-#if !COMPILER(MSVC7)
+#if !COMPILER(MSVC7) && !PLATFORM(WIN_CE)
// We need to define this before the first #include of stdlib.h or it won't contain rand_s.
#ifndef _CRT_RAND_S
#define _CRT_RAND_S
@@ -68,3 +63,4 @@
#if !PLATFORM(QT) && !PLATFORM(WX)
#include <wtf/DisallowCType.h>
#endif
+
diff --git a/JavaScriptCore/kjs/create_hash_table b/JavaScriptCore/create_hash_table
index 829a024..3bd9f76 100755
--- a/JavaScriptCore/kjs/create_hash_table
+++ b/JavaScriptCore/create_hash_table
@@ -5,9 +5,7 @@
# (c) 2000-2002 by Harri Porten <porten@kde.org> and
# David Faure <faure@kde.org>
# Modified (c) 2004 by Nikolas Zimmermann <wildfox@kde.org>
-# Copyright (C) 2007 Apple Inc. All rights reserved.
-#
-# Part of the KJS library.
+# Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -30,7 +28,7 @@ my $file = $ARGV[0];
shift;
my $includelookup = 0;
-# Use -i as second argument to make it include "lookup.h"
+# Use -i as second argument to make it include "Lookup.h"
$includelookup = 1 if (defined($ARGV[0]) && $ARGV[0] eq "-i");
# Use -n as second argument to make it use the third argument as namespace parameter ie. -n KDOM
@@ -46,9 +44,12 @@ my @hashes = ();
my $inside = 0;
my $name;
-my $size;
+my $pefectHashSize;
+my $compactSize;
+my $compactHashSizeMask;
my $banner = 0;
-sub calcSize();
+sub calcPerfectHashSize();
+sub calcCompactHashSize();
sub output();
sub jsc_ucfirst($);
sub hashValue($);
@@ -65,7 +66,8 @@ while (<IN>) {
print STDERR "WARNING: \@begin without table name, skipping $_\n";
}
} elsif (/^\@end\s*$/ && $inside) {
- calcSize();
+ calcPerfectHashSize();
+ calcCompactHashSize();
output();
@keys = ();
@@ -116,23 +118,23 @@ sub jsc_ucfirst($)
sub ceilingToPowerOf2
{
- my ($size) = @_;
+ my ($pefectHashSize) = @_;
my $powerOf2 = 1;
- while ($size > $powerOf2) {
+ while ($pefectHashSize > $powerOf2) {
$powerOf2 <<= 1;
}
return $powerOf2;
}
-sub calcSize()
+sub calcPerfectHashSize()
{
tableSizeLoop:
- for ($size = ceilingToPowerOf2(scalar @keys); ; $size += $size) {
+ for ($pefectHashSize = ceilingToPowerOf2(scalar @keys); ; $pefectHashSize += $pefectHashSize) {
my @table = ();
foreach my $key (@keys) {
- my $h = hashValue($key) % $size;
+ my $h = hashValue($key) % $pefectHashSize;
next tableSizeLoop if $table[$h];
$table[$h] = 1;
}
@@ -145,6 +147,36 @@ sub leftShift($$) {
return (($value << $distance) & 0xFFFFFFFF);
}
+sub calcCompactHashSize()
+{
+ my @table = ();
+ my @links = ();
+ my $compactHashSize = ceilingToPowerOf2(2 * @keys);
+ $compactHashSizeMask = $compactHashSize - 1;
+ $compactSize = $compactHashSize;
+ my $collisions = 0;
+ my $maxdepth = 0;
+ my $i = 0;
+ foreach my $key (@keys) {
+ my $depth = 0;
+ my $h = hashValue($key) % $compactHashSize;
+ while (defined($table[$h])) {
+ if (defined($links[$h])) {
+ $h = $links[$h];
+ $depth++;
+ } else {
+ $collisions++;
+ $links[$h] = $compactSize;
+ $h = $compactSize;
+ $compactSize++;
+ }
+ }
+ $table[$h] = $i;
+ $i++;
+ $maxdepth = $depth if ( $depth > $maxdepth);
+ }
+}
+
# Paul Hsieh's SuperFastHash
# http://www.azillionmonkeys.com/qed/hash.html
# Ported from UString..
@@ -207,7 +239,7 @@ sub output() {
my $nameEntries = "${name}Values";
$nameEntries =~ s/:/_/g;
- print "\n#include \"lookup.h\"\n" if ($includelookup);
+ print "\n#include \"Lookup.h\"\n" if ($includelookup);
if ($useNameSpace) {
print "\nnamespace ${useNameSpace} {\n";
print "\nusing namespace JSC;\n";
@@ -236,7 +268,11 @@ sub output() {
}
print " { 0, 0, 0, 0 }\n";
print "};\n\n";
- print "extern const struct HashTable $name = ";
- print "\{ ", $size - 1, ", $nameEntries, 0 \};\n\n";
+ print "extern const struct HashTable $name =\n";
+ print "#if ENABLE(PERFECT_HASH_SIZE)\n";
+ print " \{ ", $pefectHashSize - 1, ", $nameEntries, 0 \};\n";
+ print "#else\n";
+ print " \{ $compactSize, $compactHashSizeMask, $nameEntries, 0 \};\n";
+ print "#endif\n\n";
print "} // namespace\n";
}
diff --git a/JavaScriptCore/debugger/Debugger.cpp b/JavaScriptCore/debugger/Debugger.cpp
index a52a542..da1cb3d 100644
--- a/JavaScriptCore/debugger/Debugger.cpp
+++ b/JavaScriptCore/debugger/Debugger.cpp
@@ -23,6 +23,8 @@
#include "Debugger.h"
#include "JSGlobalObject.h"
+#include "Interpreter.h"
+#include "Parser.h"
namespace JSC {
@@ -51,4 +53,18 @@ void Debugger::detach(JSGlobalObject* globalObject)
globalObject->setDebugger(0);
}
+JSValuePtr evaluateInGlobalCallFrame(const UString& script, JSValuePtr& exception, JSGlobalObject* globalObject)
+{
+ CallFrame* globalCallFrame = globalObject->globalExec();
+
+ int errLine;
+ UString errMsg;
+ SourceCode source = makeSource(script);
+ RefPtr<EvalNode> evalNode = globalObject->globalData()->parser->parse<EvalNode>(globalCallFrame, globalObject->debugger(), source, &errLine, &errMsg);
+ if (!evalNode)
+ return Error::create(globalCallFrame, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
+
+ return globalObject->globalData()->interpreter->execute(evalNode.get(), globalCallFrame, globalObject, globalCallFrame->scopeChain(), &exception);
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/debugger/Debugger.h b/JavaScriptCore/debugger/Debugger.h
index 4a6a9b3..0559898 100644
--- a/JavaScriptCore/debugger/Debugger.h
+++ b/JavaScriptCore/debugger/Debugger.h
@@ -22,7 +22,7 @@
#ifndef Debugger_h
#define Debugger_h
-#include "protect.h"
+#include "Protect.h"
namespace JSC {
@@ -54,6 +54,10 @@ namespace JSC {
HashSet<JSGlobalObject*> m_globalObjects;
};
+ // This method exists only for backwards compatibility with existing
+ // WebScriptDebugger clients
+ JSValuePtr evaluateInGlobalCallFrame(const UString&, JSValuePtr& exception, JSGlobalObject*);
+
} // namespace JSC
#endif // Debugger_h
diff --git a/JavaScriptCore/debugger/DebuggerActivation.cpp b/JavaScriptCore/debugger/DebuggerActivation.cpp
new file mode 100644
index 0000000..9d4dcbf
--- /dev/null
+++ b/JavaScriptCore/debugger/DebuggerActivation.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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 "DebuggerActivation.h"
+
+#include "JSActivation.h"
+
+namespace JSC {
+
+DebuggerActivation::DebuggerActivation(JSObject* activation)
+ : JSObject(DebuggerActivation::createStructure(jsNull()))
+{
+ ASSERT(activation);
+ ASSERT(activation->isActivationObject());
+ m_activation = static_cast<JSActivation*>(activation);
+}
+
+void DebuggerActivation::mark()
+{
+ JSObject::mark();
+ if (m_activation && !m_activation->marked())
+ m_activation->mark();
+}
+
+UString DebuggerActivation::className() const
+{
+ return m_activation->className();
+}
+
+bool DebuggerActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+ return m_activation->getOwnPropertySlot(exec, propertyName, slot);
+}
+
+void DebuggerActivation::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+{
+ m_activation->put(exec, propertyName, value, slot);
+}
+
+void DebuggerActivation::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+{
+ m_activation->putWithAttributes(exec, propertyName, value, attributes);
+}
+
+bool DebuggerActivation::deleteProperty(ExecState* exec, const Identifier& propertyName)
+{
+ return m_activation->deleteProperty(exec, propertyName);
+}
+
+void DebuggerActivation::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+{
+ m_activation->getPropertyNames(exec, propertyNames);
+}
+
+bool DebuggerActivation::getPropertyAttributes(JSC::ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
+{
+ return m_activation->getPropertyAttributes(exec, propertyName, attributes);
+}
+
+void DebuggerActivation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)
+{
+ m_activation->defineGetter(exec, propertyName, getterFunction);
+}
+
+void DebuggerActivation::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction)
+{
+ m_activation->defineSetter(exec, propertyName, setterFunction);
+}
+
+JSValuePtr DebuggerActivation::lookupGetter(ExecState* exec, const Identifier& propertyName)
+{
+ return m_activation->lookupGetter(exec, propertyName);
+}
+
+JSValuePtr DebuggerActivation::lookupSetter(ExecState* exec, const Identifier& propertyName)
+{
+ return m_activation->lookupSetter(exec, propertyName);
+}
+
+} // namespace JSC
diff --git a/JavaScriptCore/debugger/DebuggerActivation.h b/JavaScriptCore/debugger/DebuggerActivation.h
new file mode 100644
index 0000000..c2ede4f
--- /dev/null
+++ b/JavaScriptCore/debugger/DebuggerActivation.h
@@ -0,0 +1,63 @@
+/*
+ * 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 DebuggerActivation_h
+#define DebuggerActivation_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+ class JSActivation;
+
+ class DebuggerActivation : public JSObject {
+ public:
+ DebuggerActivation(JSObject*);
+
+ virtual void mark();
+ virtual UString className() const;
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+ virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr, unsigned attributes);
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+ virtual void getPropertyNames(ExecState*, PropertyNameArray&);
+ virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
+ virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction);
+ virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction);
+ virtual JSValuePtr lookupGetter(ExecState*, const Identifier& propertyName);
+ virtual JSValuePtr lookupSetter(ExecState*, const Identifier& propertyName);
+
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType));
+ }
+
+ private:
+ JSActivation* m_activation;
+ };
+
+} // namespace JSC
+
+#endif // DebuggerActivation_h
diff --git a/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/JavaScriptCore/debugger/DebuggerCallFrame.cpp
index ae62cd3..27b824c 100644
--- a/JavaScriptCore/debugger/DebuggerCallFrame.cpp
+++ b/JavaScriptCore/debugger/DebuggerCallFrame.cpp
@@ -31,7 +31,7 @@
#include "JSFunction.h"
#include "CodeBlock.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "Parser.h"
namespace JSC {
@@ -60,11 +60,10 @@ JSObject* DebuggerCallFrame::thisObject() const
if (!m_callFrame->codeBlock())
return 0;
- // FIXME: Why is it safe to assume this is an object?
return asObject(m_callFrame->thisValue());
}
-JSValue* DebuggerCallFrame::evaluate(const UString& script, JSValue*& exception) const
+JSValuePtr DebuggerCallFrame::evaluate(const UString& script, JSValuePtr& exception) const
{
if (!m_callFrame->codeBlock())
return noValue();
@@ -76,7 +75,7 @@ JSValue* DebuggerCallFrame::evaluate(const UString& script, JSValue*& exception)
if (!evalNode)
return Error::create(m_callFrame, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
- return m_callFrame->scopeChain()->globalData->machine->execute(evalNode.get(), m_callFrame, thisObject(), m_callFrame->scopeChain(), &exception);
+ return m_callFrame->scopeChain()->globalData->interpreter->execute(evalNode.get(), m_callFrame, thisObject(), m_callFrame->scopeChain(), &exception);
}
} // namespace JSC
diff --git a/JavaScriptCore/debugger/DebuggerCallFrame.h b/JavaScriptCore/debugger/DebuggerCallFrame.h
index 8326b20..cdf4965 100644
--- a/JavaScriptCore/debugger/DebuggerCallFrame.h
+++ b/JavaScriptCore/debugger/DebuggerCallFrame.h
@@ -29,7 +29,7 @@
#ifndef DebuggerCallFrame_h
#define DebuggerCallFrame_h
-#include "ExecState.h"
+#include "CallFrame.h"
namespace JSC {
@@ -43,7 +43,7 @@ namespace JSC {
{
}
- DebuggerCallFrame(CallFrame* callFrame, JSValue* exception)
+ DebuggerCallFrame(CallFrame* callFrame, JSValuePtr exception)
: m_callFrame(callFrame)
, m_exception(exception)
{
@@ -54,12 +54,12 @@ namespace JSC {
const UString* functionName() const;
Type type() const;
JSObject* thisObject() const;
- JSValue* evaluate(const UString&, JSValue*& exception) const;
- JSValue* exception() const { return m_exception; }
+ JSValuePtr evaluate(const UString&, JSValuePtr& exception) const;
+ JSValuePtr exception() const { return m_exception; }
private:
CallFrame* m_callFrame;
- JSValue* m_exception;
+ JSValuePtr m_exception;
};
} // namespace JSC
diff --git a/JavaScriptCore/docs/make-bytecode-docs.pl b/JavaScriptCore/docs/make-bytecode-docs.pl
index 0be22eb..9494d1b 100755
--- a/JavaScriptCore/docs/make-bytecode-docs.pl
+++ b/JavaScriptCore/docs/make-bytecode-docs.pl
@@ -10,9 +10,9 @@ my @undocumented = ();
print OUTPUT "<style>p code \{ font-size: 14px; \}</style>\n";
while (<MACHINE>) {
- if (/^ *BEGIN_OPCODE/) {
+ if (/^ *DEFINE_OPCODE/) {
chomp;
- s/^ *BEGIN_OPCODE\(op_//;
+ s/^ *DEFINE_OPCODE\(op_//;
s/\).*$//;
my $opcode = $_;
$_ = <MACHINE>;
diff --git a/JavaScriptCore/runtime/ExecState.cpp b/JavaScriptCore/interpreter/CallFrame.cpp
index 0144c14..1c74280 100644
--- a/JavaScriptCore/runtime/ExecState.cpp
+++ b/JavaScriptCore/interpreter/CallFrame.cpp
@@ -24,15 +24,15 @@
*/
#include "config.h"
-#include "ExecState.h"
+#include "CallFrame.h"
#include "CodeBlock.h"
namespace JSC {
-JSValue* CallFrame::thisValue()
+JSValuePtr CallFrame::thisValue()
{
- return this[codeBlock()->thisRegister].jsValue(this);
+ return this[codeBlock()->thisRegister()].jsValue(this);
}
}
diff --git a/JavaScriptCore/runtime/ExecState.h b/JavaScriptCore/interpreter/CallFrame.h
index f1891bb..d6b9b79 100644
--- a/JavaScriptCore/runtime/ExecState.h
+++ b/JavaScriptCore/interpreter/CallFrame.h
@@ -20,19 +20,18 @@
*
*/
-#ifndef ExecState_h
-#define ExecState_h
-
-// FIXME: Rename this file to CallFrame.h.
+#ifndef CallFrame_h
+#define CallFrame_h
#include "JSGlobalData.h"
-#include "Machine.h"
+#include "RegisterFile.h"
#include "ScopeChain.h"
namespace JSC {
class Arguments;
class JSActivation;
+ class Interpreter;
// Represents the current state of script execution.
// Passed as the first argument to most functions.
@@ -42,7 +41,7 @@ namespace JSC {
CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); }
ScopeChainNode* scopeChain() const { return this[RegisterFile::ScopeChain].Register::scopeChain(); }
- JSValue* thisValue();
+ JSValuePtr thisValue();
// Global object in which execution began.
JSGlobalObject* dynamicGlobalObject();
@@ -74,15 +73,15 @@ namespace JSC {
// pointer, so these are inefficient, and should be used sparingly in new code.
// But they're used in many places in legacy code, so they're not going away any time soon.
- void setException(JSValue* exception) { globalData().exception = exception; }
+ void setException(JSValuePtr exception) { globalData().exception = exception; }
void clearException() { globalData().exception = noValue(); }
- JSValue* exception() const { return globalData().exception; }
- JSValue** exceptionSlot() { return &globalData().exception; }
- bool hadException() const { return !!globalData().exception; }
+ JSValuePtr exception() const { return globalData().exception; }
+ JSValuePtr* exceptionSlot() { return &globalData().exception; }
+ bool hadException() const { return globalData().exception; }
const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; }
const ArgList& emptyList() const { return *globalData().emptyList; }
- Machine* machine() { return globalData().machine; }
+ Interpreter* interpreter() { return globalData().interpreter; }
Heap* heap() { return &globalData().heap; }
static const HashTable* arrayTable(CallFrame* callFrame) { return callFrame->globalData().arrayTable; }
@@ -97,7 +96,7 @@ namespace JSC {
friend class Arguments;
friend class JSActivation;
friend class JSGlobalObject;
- friend class Machine;
+ friend class Interpreter;
static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
Register* registers() { return this; }
@@ -125,7 +124,7 @@ namespace JSC {
setCodeBlock(codeBlock);
setScopeChain(scopeChain);
setCallerFrame(callerFrame);
- this[RegisterFile::ReturnPC] = vPC;
+ this[RegisterFile::ReturnPC] = vPC; // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*.
this[RegisterFile::ReturnValueRegister] = returnValueRegister;
setArgumentCount(argc); // original argument count (for the sake of the "arguments" object)
setCallee(function);
@@ -145,4 +144,4 @@ namespace JSC {
} // namespace JSC
-#endif // ExecState_h
+#endif // CallFrame_h
diff --git a/JavaScriptCore/VM/Machine.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index a605d25..135c42f 100644
--- a/JavaScriptCore/VM/Machine.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
*
* Redistribution and use in source and binary forms, with or without
@@ -28,17 +28,19 @@
*/
#include "config.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "Arguments.h"
#include "BatchedTransitionOptimizer.h"
#include "CodeBlock.h"
#include "DebuggerCallFrame.h"
+#include "EvalCodeCache.h"
#include "ExceptionHelpers.h"
-#include "ExecState.h"
+#include "CallFrame.h"
#include "GlobalEvalFunction.h"
#include "JSActivation.h"
#include "JSArray.h"
+#include "JSByteArray.h"
#include "JSFunction.h"
#include "JSNotAnObject.h"
#include "JSPropertyNameIterator.h"
@@ -50,14 +52,18 @@
#include "RegExpObject.h"
#include "RegExpPrototype.h"
#include "Register.h"
-#include "collector.h"
+#include "Collector.h"
#include "Debugger.h"
-#include "operations.h"
+#include "Operations.h"
#include "SamplingTool.h"
#include <stdio.h>
-#if ENABLE(CTI)
-#include "CTI.h"
+#if ENABLE(JIT)
+#include "JIT.h"
+#endif
+
+#if ENABLE(ASSEMBLER)
+#include "AssemblerBuffer.h"
#endif
#if PLATFORM(DARWIN)
@@ -83,107 +89,42 @@ namespace JSC {
// Preferred number of milliseconds between each timeout check
static const int preferredScriptCheckTimeInterval = 1000;
-#if HAVE(COMPUTED_GOTO)
-static void* op_throw_end_indirect;
-static void* op_call_indirect;
-#endif
-
-#if ENABLE(CTI)
-
-static ALWAYS_INLINE Instruction* vPCForPC(CodeBlock* codeBlock, void* pc)
+static ALWAYS_INLINE unsigned bytecodeOffsetForPC(CallFrame* callFrame, CodeBlock* codeBlock, void* pc)
{
- if (pc >= codeBlock->instructions.begin() && pc < codeBlock->instructions.end())
- return static_cast<Instruction*>(pc);
-
- ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(pc));
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(pc);
- return codeBlock->instructions.begin() + vPCIndex;
-}
-
-#else // ENABLE(CTI)
-
-static ALWAYS_INLINE Instruction* vPCForPC(CodeBlock*, void* pc)
-{
- return static_cast<Instruction*>(pc);
+#if ENABLE(JIT)
+ return codeBlock->getBytecodeIndex(callFrame, pc);
+#else
+ UNUSED_PARAM(callFrame);
+ return static_cast<Instruction*>(pc) - codeBlock->instructions().begin();
+#endif
}
-#endif // ENABLE(CTI)
-
// Returns the depth of the scope chain within a given call frame.
static int depth(CodeBlock* codeBlock, ScopeChain& sc)
{
- if (!codeBlock->needsFullScopeChain)
+ if (!codeBlock->needsFullScopeChain())
return 0;
- int scopeDepth = 0;
- ScopeChainIterator iter = sc.begin();
- ScopeChainIterator end = sc.end();
- while (!(*iter)->isObject(&JSActivation::info)) {
- ++iter;
- if (iter == end)
- break;
- ++scopeDepth;
- }
- return scopeDepth;
+ return sc.localDepth();
}
-// FIXME: This operation should be called "getNumber", not "isNumber" (as it is in JSValue.h).
-// FIXME: There's no need to have a "slow" version of this. All versions should be fast.
-static ALWAYS_INLINE bool fastIsNumber(JSValue* value, double& arg)
+static inline bool jsLess(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
{
- if (JSImmediate::isNumber(value))
- arg = JSImmediate::getTruncatedInt32(value);
- else if (LIKELY(!JSImmediate::isImmediate(value)) && LIKELY(Heap::isNumber(asCell(value))))
- arg = asNumberCell(value)->value();
- else
- return false;
- return true;
-}
-
-// FIXME: Why doesn't JSValue*::toInt32 have the Heap::isNumber optimization?
-static bool fastToInt32(JSValue* value, int32_t& arg)
-{
- if (JSImmediate::isNumber(value))
- arg = JSImmediate::getTruncatedInt32(value);
- else if (LIKELY(!JSImmediate::isImmediate(value)) && LIKELY(Heap::isNumber(asCell(value))))
- arg = asNumberCell(value)->toInt32();
- else
- return false;
- return true;
-}
-
-static ALWAYS_INLINE bool fastToUInt32(JSValue* value, uint32_t& arg)
-{
- if (JSImmediate::isNumber(value)) {
- if (JSImmediate::getTruncatedUInt32(value, arg))
- return true;
- bool scratch;
- arg = toUInt32SlowCase(JSImmediate::getTruncatedInt32(value), scratch);
- return true;
- } else if (!JSImmediate::isImmediate(value) && Heap::isNumber(asCell(value)))
- arg = asNumberCell(value)->toUInt32();
- else
- return false;
- return true;
-}
-
-static inline bool jsLess(CallFrame* callFrame, JSValue* v1, JSValue* v2)
-{
- if (JSImmediate::areBothImmediateNumbers(v1, v2))
- return JSImmediate::getTruncatedInt32(v1) < JSImmediate::getTruncatedInt32(v2);
+ if (JSValuePtr::areBothInt32Fast(v1, v2))
+ return v1.getInt32Fast() < v2.getInt32Fast();
double n1;
double n2;
- if (fastIsNumber(v1, n1) && fastIsNumber(v2, n2))
+ if (v1.getNumber(n1) && v2.getNumber(n2))
return n1 < n2;
- Machine* machine = callFrame->machine();
- if (machine->isJSString(v1) && machine->isJSString(v2))
+ Interpreter* interpreter = callFrame->interpreter();
+ if (interpreter->isJSString(v1) && interpreter->isJSString(v2))
return asString(v1)->value() < asString(v2)->value();
- JSValue* p1;
- JSValue* p2;
- bool wasNotString1 = v1->getPrimitiveNumber(callFrame, n1, p1);
- bool wasNotString2 = v2->getPrimitiveNumber(callFrame, n2, p2);
+ JSValuePtr p1;
+ JSValuePtr p2;
+ bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+ bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
if (wasNotString1 | wasNotString2)
return n1 < n2;
@@ -191,24 +132,24 @@ static inline bool jsLess(CallFrame* callFrame, JSValue* v1, JSValue* v2)
return asString(p1)->value() < asString(p2)->value();
}
-static inline bool jsLessEq(CallFrame* callFrame, JSValue* v1, JSValue* v2)
+static inline bool jsLessEq(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
{
- if (JSImmediate::areBothImmediateNumbers(v1, v2))
- return JSImmediate::getTruncatedInt32(v1) <= JSImmediate::getTruncatedInt32(v2);
+ if (JSValuePtr::areBothInt32Fast(v1, v2))
+ return v1.getInt32Fast() <= v2.getInt32Fast();
double n1;
double n2;
- if (fastIsNumber(v1, n1) && fastIsNumber(v2, n2))
+ if (v1.getNumber(n1) && v2.getNumber(n2))
return n1 <= n2;
- Machine* machine = callFrame->machine();
- if (machine->isJSString(v1) && machine->isJSString(v2))
+ Interpreter* interpreter = callFrame->interpreter();
+ if (interpreter->isJSString(v1) && interpreter->isJSString(v2))
return !(asString(v2)->value() < asString(v1)->value());
- JSValue* p1;
- JSValue* p2;
- bool wasNotString1 = v1->getPrimitiveNumber(callFrame, n1, p1);
- bool wasNotString2 = v2->getPrimitiveNumber(callFrame, n2, p2);
+ JSValuePtr p1;
+ JSValuePtr p2;
+ bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+ bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
if (wasNotString1 | wasNotString2)
return n1 <= n2;
@@ -216,20 +157,20 @@ static inline bool jsLessEq(CallFrame* callFrame, JSValue* v1, JSValue* v2)
return !(asString(p2)->value() < asString(p1)->value());
}
-static NEVER_INLINE JSValue* jsAddSlowCase(CallFrame* callFrame, JSValue* v1, JSValue* v2)
+static NEVER_INLINE JSValuePtr jsAddSlowCase(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
{
// exception for the Date exception in defaultValue()
- JSValue* p1 = v1->toPrimitive(callFrame);
- JSValue* p2 = v2->toPrimitive(callFrame);
+ JSValuePtr p1 = v1.toPrimitive(callFrame);
+ JSValuePtr p2 = v2.toPrimitive(callFrame);
- if (p1->isString() || p2->isString()) {
- RefPtr<UString::Rep> value = concatenate(p1->toString(callFrame).rep(), p2->toString(callFrame).rep());
+ if (p1.isString() || p2.isString()) {
+ RefPtr<UString::Rep> value = concatenate(p1.toString(callFrame).rep(), p2.toString(callFrame).rep());
if (!value)
return throwOutOfMemoryError(callFrame);
return jsString(callFrame, value.release());
}
- return jsNumber(callFrame, p1->toNumber(callFrame) + p2->toNumber(callFrame));
+ return jsNumber(callFrame, p1.toNumber(callFrame) + p2.toNumber(callFrame));
}
// Fast-path choices here are based on frequency data from SunSpider:
@@ -241,17 +182,17 @@ static NEVER_INLINE JSValue* jsAddSlowCase(CallFrame* callFrame, JSValue* v1, JS
// 13962 Add case: 5 3
// 4000 Add case: 3 5
-static ALWAYS_INLINE JSValue* jsAdd(CallFrame* callFrame, JSValue* v1, JSValue* v2)
+static ALWAYS_INLINE JSValuePtr jsAdd(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
{
double left;
double right = 0.0;
- bool rightIsNumber = fastIsNumber(v2, right);
- if (rightIsNumber && fastIsNumber(v1, left))
+ bool rightIsNumber = v2.getNumber(right);
+ if (rightIsNumber && v1.getNumber(left))
return jsNumber(callFrame, left + right);
- bool leftIsString = v1->isString();
- if (leftIsString && v2->isString()) {
+ bool leftIsString = v1.isString();
+ if (leftIsString && v2.isString()) {
RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
if (!value)
return throwOutOfMemoryError(callFrame);
@@ -259,8 +200,8 @@ static ALWAYS_INLINE JSValue* jsAdd(CallFrame* callFrame, JSValue* v1, JSValue*
}
if (rightIsNumber & leftIsString) {
- RefPtr<UString::Rep> value = JSImmediate::isImmediate(v2) ?
- concatenate(asString(v1)->value().rep(), JSImmediate::getTruncatedInt32(v2)) :
+ RefPtr<UString::Rep> value = v2.isInt32Fast() ?
+ concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) :
concatenate(asString(v1)->value().rep(), right);
if (!value)
@@ -272,20 +213,20 @@ static ALWAYS_INLINE JSValue* jsAdd(CallFrame* callFrame, JSValue* v1, JSValue*
return jsAddSlowCase(callFrame, v1, v2);
}
-static JSValue* jsTypeStringForValue(CallFrame* callFrame, JSValue* v)
+static JSValuePtr jsTypeStringForValue(CallFrame* callFrame, JSValuePtr v)
{
- if (v->isUndefined())
+ if (v.isUndefined())
return jsNontrivialString(callFrame, "undefined");
- if (v->isBoolean())
+ if (v.isBoolean())
return jsNontrivialString(callFrame, "boolean");
- if (v->isNumber())
+ if (v.isNumber())
return jsNontrivialString(callFrame, "number");
- if (v->isString())
+ if (v.isString())
return jsNontrivialString(callFrame, "string");
- if (v->isObject()) {
+ if (v.isObject()) {
// Return "undefined" for objects that should be treated
// as null when doing comparisons.
- if (asObject(v)->structureID()->typeInfo().masqueradesAsUndefined())
+ if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
return jsNontrivialString(callFrame, "undefined");
CallData callData;
if (asObject(v)->getCallData(callData) != CallTypeNone)
@@ -294,16 +235,16 @@ static JSValue* jsTypeStringForValue(CallFrame* callFrame, JSValue* v)
return jsNontrivialString(callFrame, "object");
}
-static bool jsIsObjectType(JSValue* v)
+static bool jsIsObjectType(JSValuePtr v)
{
- if (JSImmediate::isImmediate(v))
- return v->isNull();
+ if (!v.isCell())
+ return v.isNull();
- JSType type = asCell(v)->structureID()->typeInfo().type();
+ JSType type = asCell(v)->structure()->typeInfo().type();
if (type == NumberType || type == StringType)
return false;
if (type == ObjectType) {
- if (asObject(v)->structureID()->typeInfo().masqueradesAsUndefined())
+ if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
return false;
CallData callData;
if (asObject(v)->getCallData(callData) != CallTypeNone)
@@ -312,9 +253,9 @@ static bool jsIsObjectType(JSValue* v)
return true;
}
-static bool jsIsFunctionType(JSValue* v)
+static bool jsIsFunctionType(JSValuePtr v)
{
- if (v->isObject()) {
+ if (v.isObject()) {
CallData callData;
if (asObject(v)->getCallData(callData) != CallTypeNone)
return true;
@@ -322,7 +263,7 @@ static bool jsIsFunctionType(JSValue* v)
return false;
}
-NEVER_INLINE bool Machine::resolve(CallFrame* callFrame, Instruction* vPC, JSValue*& exceptionValue)
+NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
{
int dst = (vPC + 1)->u.operand;
int property = (vPC + 2)->u.operand;
@@ -333,30 +274,30 @@ NEVER_INLINE bool Machine::resolve(CallFrame* callFrame, Instruction* vPC, JSVal
ASSERT(iter != end);
CodeBlock* codeBlock = callFrame->codeBlock();
- Identifier& ident = codeBlock->identifiers[property];
+ Identifier& ident = codeBlock->identifier(property);
do {
JSObject* o = *iter;
PropertySlot slot(o);
if (o->getPropertySlot(callFrame, ident, slot)) {
- JSValue* result = slot.getValue(callFrame, ident);
+ JSValuePtr result = slot.getValue(callFrame, ident);
exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
- callFrame[dst] = result;
+ callFrame[dst] = JSValuePtr(result);
return true;
}
} while (++iter != end);
- exceptionValue = createUndefinedVariableError(callFrame, ident, vPC, codeBlock);
+ exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);
return false;
}
-NEVER_INLINE bool Machine::resolveSkip(CallFrame* callFrame, Instruction* vPC, JSValue*& exceptionValue)
+NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
{
CodeBlock* codeBlock = callFrame->codeBlock();
int dst = (vPC + 1)->u.operand;
int property = (vPC + 2)->u.operand;
- int skip = (vPC + 3)->u.operand + codeBlock->needsFullScopeChain;
+ int skip = (vPC + 3)->u.operand + codeBlock->needsFullScopeChain();
ScopeChainNode* scopeChain = callFrame->scopeChain();
ScopeChainIterator iter = scopeChain->begin();
@@ -366,64 +307,64 @@ NEVER_INLINE bool Machine::resolveSkip(CallFrame* callFrame, Instruction* vPC, J
++iter;
ASSERT(iter != end);
}
- Identifier& ident = codeBlock->identifiers[property];
+ Identifier& ident = codeBlock->identifier(property);
do {
JSObject* o = *iter;
PropertySlot slot(o);
if (o->getPropertySlot(callFrame, ident, slot)) {
- JSValue* result = slot.getValue(callFrame, ident);
+ JSValuePtr result = slot.getValue(callFrame, ident);
exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
- callFrame[dst] = result;
+ callFrame[dst] = JSValuePtr(result);
return true;
}
} while (++iter != end);
- exceptionValue = createUndefinedVariableError(callFrame, ident, vPC, codeBlock);
+ exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);
return false;
}
-NEVER_INLINE bool Machine::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValue*& exceptionValue)
+NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
{
int dst = (vPC + 1)->u.operand;
JSGlobalObject* globalObject = static_cast<JSGlobalObject*>((vPC + 2)->u.jsCell);
ASSERT(globalObject->isGlobalObject());
int property = (vPC + 3)->u.operand;
- StructureID* structureID = (vPC + 4)->u.structureID;
+ Structure* structure = (vPC + 4)->u.structure;
int offset = (vPC + 5)->u.operand;
- if (structureID == globalObject->structureID()) {
- callFrame[dst] = globalObject->getDirectOffset(offset);
+ if (structure == globalObject->structure()) {
+ callFrame[dst] = JSValuePtr(globalObject->getDirectOffset(offset));
return true;
}
CodeBlock* codeBlock = callFrame->codeBlock();
- Identifier& ident = codeBlock->identifiers[property];
+ Identifier& ident = codeBlock->identifier(property);
PropertySlot slot(globalObject);
if (globalObject->getPropertySlot(callFrame, ident, slot)) {
- JSValue* result = slot.getValue(callFrame, ident);
- if (slot.isCacheable()) {
- if (vPC[4].u.structureID)
- vPC[4].u.structureID->deref();
- globalObject->structureID()->ref();
- vPC[4] = globalObject->structureID();
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ if (slot.isCacheable() && !globalObject->structure()->isDictionary()) {
+ if (vPC[4].u.structure)
+ vPC[4].u.structure->deref();
+ globalObject->structure()->ref();
+ vPC[4] = globalObject->structure();
vPC[5] = slot.cachedOffset();
- callFrame[dst] = result;
+ callFrame[dst] = JSValuePtr(result);
return true;
}
exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
- callFrame[dst] = result;
+ callFrame[dst] = JSValuePtr(result);
return true;
}
- exceptionValue = createUndefinedVariableError(callFrame, ident, vPC, codeBlock);
+ exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);
return false;
}
-static ALWAYS_INLINE JSValue* inlineResolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
+static ALWAYS_INLINE JSValuePtr inlineResolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
{
ScopeChainIterator iter = scopeChain->begin();
ScopeChainIterator next = iter;
@@ -446,14 +387,14 @@ static ALWAYS_INLINE JSValue* inlineResolveBase(CallFrame* callFrame, Identifier
return noValue();
}
-NEVER_INLINE void Machine::resolveBase(CallFrame* callFrame, Instruction* vPC)
+NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC)
{
int dst = (vPC + 1)->u.operand;
int property = (vPC + 2)->u.operand;
- callFrame[dst] = inlineResolveBase(callFrame, callFrame->codeBlock()->identifiers[property], callFrame->scopeChain());
+ callFrame[dst] = JSValuePtr(inlineResolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain()));
}
-NEVER_INLINE bool Machine::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue*& exceptionValue)
+NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
{
int baseDst = (vPC + 1)->u.operand;
int propDst = (vPC + 2)->u.operand;
@@ -468,28 +409,28 @@ NEVER_INLINE bool Machine::resolveBaseAndProperty(CallFrame* callFrame, Instruct
ASSERT(iter != end);
CodeBlock* codeBlock = callFrame->codeBlock();
- Identifier& ident = codeBlock->identifiers[property];
+ Identifier& ident = codeBlock->identifier(property);
JSObject* base;
do {
base = *iter;
PropertySlot slot(base);
if (base->getPropertySlot(callFrame, ident, slot)) {
- JSValue* result = slot.getValue(callFrame, ident);
+ JSValuePtr result = slot.getValue(callFrame, ident);
exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
- callFrame[propDst] = result;
- callFrame[baseDst] = base;
+ callFrame[propDst] = JSValuePtr(result);
+ callFrame[baseDst] = JSValuePtr(base);
return true;
}
++iter;
} while (iter != end);
- exceptionValue = createUndefinedVariableError(callFrame, ident, vPC, codeBlock);
+ exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);
return false;
}
-NEVER_INLINE bool Machine::resolveBaseAndFunc(CallFrame* callFrame, Instruction* vPC, JSValue*& exceptionValue)
+NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
{
int baseDst = (vPC + 1)->u.operand;
int funcDst = (vPC + 2)->u.operand;
@@ -504,7 +445,7 @@ NEVER_INLINE bool Machine::resolveBaseAndFunc(CallFrame* callFrame, Instruction*
ASSERT(iter != end);
CodeBlock* codeBlock = callFrame->codeBlock();
- Identifier& ident = codeBlock->identifiers[property];
+ Identifier& ident = codeBlock->identifier(property);
JSObject* base;
do {
base = *iter;
@@ -518,33 +459,33 @@ NEVER_INLINE bool Machine::resolveBaseAndFunc(CallFrame* callFrame, Instruction*
// that in host objects you always get a valid object for this.
// We also handle wrapper substitution for the global object at the same time.
JSObject* thisObj = base->toThisObject(callFrame);
- JSValue* result = slot.getValue(callFrame, ident);
+ JSValuePtr result = slot.getValue(callFrame, ident);
exceptionValue = callFrame->globalData().exception;
if (exceptionValue)
return false;
- callFrame[baseDst] = thisObj;
- callFrame[funcDst] = result;
+ callFrame[baseDst] = JSValuePtr(thisObj);
+ callFrame[funcDst] = JSValuePtr(result);
return true;
}
++iter;
} while (iter != end);
- exceptionValue = createUndefinedVariableError(callFrame, ident, vPC, codeBlock);
+ exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);
return false;
}
-ALWAYS_INLINE CallFrame* Machine::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc)
+ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc)
{
Register* r = callFrame->registers();
- Register* newEnd = r + registerOffset + newCodeBlock->numCalleeRegisters;
+ Register* newEnd = r + registerOffset + newCodeBlock->m_numCalleeRegisters;
- if (LIKELY(argc == newCodeBlock->numParameters)) { // correct number of arguments
+ if (LIKELY(argc == newCodeBlock->m_numParameters)) { // correct number of arguments
if (UNLIKELY(!registerFile->grow(newEnd)))
return 0;
r += registerOffset;
- } else if (argc < newCodeBlock->numParameters) { // too few arguments -- fill in the blanks
- size_t omittedArgCount = newCodeBlock->numParameters - argc;
+ } else if (argc < newCodeBlock->m_numParameters) { // too few arguments -- fill in the blanks
+ size_t omittedArgCount = newCodeBlock->m_numParameters - argc;
registerOffset += omittedArgCount;
newEnd += omittedArgCount;
if (!registerFile->grow(newEnd))
@@ -555,7 +496,7 @@ ALWAYS_INLINE CallFrame* Machine::slideRegisterWindowForCall(CodeBlock* newCodeB
for (size_t i = 0; i < omittedArgCount; ++i)
argv[i] = jsUndefined();
} else { // too many arguments -- copy expected arguments, leaving the extra arguments behind
- size_t numParameters = newCodeBlock->numParameters;
+ size_t numParameters = newCodeBlock->m_numParameters;
registerOffset += numParameters;
newEnd += numParameters;
@@ -571,42 +512,45 @@ ALWAYS_INLINE CallFrame* Machine::slideRegisterWindowForCall(CodeBlock* newCodeB
return CallFrame::create(r);
}
-static NEVER_INLINE bool isNotObject(CallFrame* callFrame, bool forInstanceOf, CodeBlock* codeBlock, const Instruction* vPC, JSValue* value, JSValue*& exceptionData)
+static NEVER_INLINE bool isNotObject(CallFrame* callFrame, bool forInstanceOf, CodeBlock* codeBlock, const Instruction* vPC, JSValuePtr value, JSValuePtr& exceptionData)
{
- if (value->isObject())
+ if (value.isObject())
return false;
- exceptionData = createInvalidParamError(callFrame, forInstanceOf ? "instanceof" : "in" , value, vPC, codeBlock);
+ exceptionData = createInvalidParamError(callFrame, forInstanceOf ? "instanceof" : "in" , value, vPC - codeBlock->instructions().begin(), codeBlock);
return true;
}
-NEVER_INLINE JSValue* Machine::callEval(CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile* registerFile, int argv, int argc, JSValue*& exceptionValue)
+NEVER_INLINE JSValuePtr Interpreter::callEval(CallFrame* callFrame, RegisterFile* registerFile, Register* argv, int argc, int registerOffset, JSValuePtr& exceptionValue)
{
if (argc < 2)
return jsUndefined();
- JSValue* program = callFrame[argv + 1].jsValue(callFrame);
+ JSValuePtr program = argv[1].jsValue(callFrame);
- if (!program->isString())
+ if (!program.isString())
return program;
UString programSource = asString(program)->value();
+ ScopeChainNode* scopeChain = callFrame->scopeChain();
CodeBlock* codeBlock = callFrame->codeBlock();
- RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache.get(callFrame, programSource, scopeChain, exceptionValue);
+ RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache().get(callFrame, programSource, scopeChain, exceptionValue);
- JSValue* result = jsUndefined();
+ JSValuePtr result = jsUndefined();
if (evalNode)
- result = callFrame->globalData().machine->execute(evalNode.get(), callFrame, thisObj, callFrame->registers() - registerFile->start() + argv + 1 + RegisterFile::CallFrameHeaderSize, scopeChain, &exceptionValue);
+ result = callFrame->globalData().interpreter->execute(evalNode.get(), callFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue);
return result;
}
-Machine::Machine()
+Interpreter::Interpreter()
: m_sampler(0)
-#if ENABLE(CTI)
+#if ENABLE(JIT)
, m_ctiArrayLengthTrampoline(0)
, m_ctiStringLengthTrampoline(0)
- , m_jitCodeBuffer(new JITCodeBuffer(1024 * 1024))
+ , m_ctiVirtualCallPreLink(0)
+ , m_ctiVirtualCallLink(0)
+ , m_ctiVirtualCall(0)
#endif
, m_reentryDepth(0)
, m_timeoutTime(0)
@@ -621,44 +565,47 @@ Machine::Machine()
// Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
void* storage = fastMalloc(sizeof(CollectorBlock));
- JSCell* jsArray = new (storage) JSArray(JSArray::createStructureID(jsNull()));
+ JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull()));
m_jsArrayVptr = jsArray->vptr();
jsArray->~JSCell();
+ JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
+ m_jsByteArrayVptr = jsByteArray->vptr();
+ jsByteArray->~JSCell();
+
JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
m_jsStringVptr = jsString->vptr();
jsString->~JSCell();
- JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructureID(jsNull()));
+ JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
m_jsFunctionVptr = jsFunction->vptr();
jsFunction->~JSCell();
fastFree(storage);
}
-Machine::~Machine()
+void Interpreter::initialize(JSGlobalData* globalData)
{
-#if ENABLE(CTI)
- if (m_ctiArrayLengthTrampoline)
- fastFree(m_ctiArrayLengthTrampoline);
- if (m_ctiStringLengthTrampoline)
- fastFree(m_ctiStringLengthTrampoline);
+#if ENABLE(JIT)
+ JIT::compileCTIMachineTrampolines(globalData);
+#else
+ UNUSED_PARAM(globalData);
#endif
}
-#ifndef NDEBUG
-
-void Machine::dumpCallFrame(const RegisterFile* registerFile, CallFrame* callFrame)
+Interpreter::~Interpreter()
{
- JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
+}
- CodeBlock* codeBlock = callFrame->codeBlock();
- codeBlock->dump(globalObject->globalExec());
+#ifndef NDEBUG
- dumpRegisters(registerFile, callFrame);
+void Interpreter::dumpCallFrame(CallFrame* callFrame)
+{
+ callFrame->codeBlock()->dump(callFrame);
+ dumpRegisters(callFrame);
}
-void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFrame)
+void Interpreter::dumpRegisters(CallFrame* callFrame)
{
printf("Register frame: \n\n");
printf("----------------------------------------------------\n");
@@ -666,10 +613,11 @@ void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFra
printf("----------------------------------------------------\n");
CodeBlock* codeBlock = callFrame->codeBlock();
+ RegisterFile* registerFile = &callFrame->scopeChain()->globalObject()->globalData()->interpreter->registerFile();
const Register* it;
const Register* end;
- if (codeBlock->codeType == GlobalCode) {
+ if (codeBlock->codeType() == GlobalCode) {
it = registerFile->lastGlobal();
end = it + registerFile->numGlobals();
while (it != end) {
@@ -679,9 +627,9 @@ void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFra
printf("----------------------------------------------------\n");
}
- it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - codeBlock->numParameters;
+ it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - codeBlock->m_numParameters;
printf("[this] | %10p | %10p \n", it, (*it).v()); ++it;
- end = it + max(codeBlock->numParameters - 1, 0); // - 1 to skip "this"
+ end = it + max(codeBlock->m_numParameters - 1, 0); // - 1 to skip "this"
if (it != end) {
do {
printf("[param] | %10p | %10p \n", it, (*it).v());
@@ -702,7 +650,7 @@ void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFra
int registerCount = 0;
- end = it + codeBlock->numVars;
+ end = it + codeBlock->m_numVars;
if (it != end) {
do {
printf("[r%2d] | %10p | %10p \n", registerCount, it, (*it).v());
@@ -712,7 +660,7 @@ void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFra
}
printf("----------------------------------------------------\n");
- end = it + codeBlock->numConstants;
+ end = it + codeBlock->m_numConstants;
if (it != end) {
do {
printf("[r%2d] | %10p | %10p \n", registerCount, it, (*it).v());
@@ -722,7 +670,7 @@ void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFra
}
printf("----------------------------------------------------\n");
- end = it + codeBlock->numCalleeRegisters - codeBlock->numConstants - codeBlock->numVars;
+ end = it + codeBlock->m_numCalleeRegisters - codeBlock->m_numConstants - codeBlock->m_numVars;
if (it != end) {
do {
printf("[r%2d] | %10p | %10p \n", registerCount, it, (*it).v());
@@ -735,7 +683,7 @@ void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFra
#endif
-bool Machine::isOpcode(Opcode opcode)
+bool Interpreter::isOpcode(Opcode opcode)
{
#if HAVE(COMPUTED_GOTO)
return opcode != HashTraits<Opcode>::emptyValue()
@@ -746,7 +694,7 @@ bool Machine::isOpcode(Opcode opcode)
#endif
}
-NEVER_INLINE bool Machine::unwindCallFrame(CallFrame*& callFrame, JSValue* exceptionValue, const Instruction*& vPC, CodeBlock*& codeBlock)
+NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValuePtr exceptionValue, unsigned& bytecodeOffset, CodeBlock*& codeBlock)
{
CodeBlock* oldCodeBlock = codeBlock;
ScopeChainNode* scopeChain = callFrame->scopeChain();
@@ -754,20 +702,20 @@ NEVER_INLINE bool Machine::unwindCallFrame(CallFrame*& callFrame, JSValue* excep
if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
if (callFrame->callee())
- debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->lastLine());
+ debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->lastLine());
else
- debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->lastLine());
+ debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->lastLine());
}
if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
if (callFrame->callee())
profiler->didExecute(callFrame, callFrame->callee());
else
- profiler->didExecute(callFrame, codeBlock->ownerNode->sourceURL(), codeBlock->ownerNode->lineNo());
+ profiler->didExecute(callFrame, codeBlock->ownerNode()->sourceURL(), codeBlock->ownerNode()->lineNo());
}
// If this call frame created an activation or an 'arguments' object, tear it off.
- if (oldCodeBlock->codeType == FunctionCode && oldCodeBlock->needsFullScopeChain) {
+ if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsFullScopeChain()) {
while (!scopeChain->object->isObject(&JSActivation::info))
scopeChain = scopeChain->pop();
static_cast<JSActivation*>(scopeChain->object)->copyRegisters(callFrame->optionalCalleeArguments());
@@ -776,7 +724,7 @@ NEVER_INLINE bool Machine::unwindCallFrame(CallFrame*& callFrame, JSValue* excep
arguments->copyRegisters();
}
- if (oldCodeBlock->needsFullScopeChain)
+ if (oldCodeBlock->needsFullScopeChain())
scopeChain->deref();
void* returnPC = callFrame->returnPC();
@@ -785,19 +733,19 @@ NEVER_INLINE bool Machine::unwindCallFrame(CallFrame*& callFrame, JSValue* excep
return false;
codeBlock = callFrame->codeBlock();
- vPC = vPCForPC(codeBlock, returnPC);
+ bytecodeOffset = bytecodeOffsetForPC(callFrame, codeBlock, returnPC);
return true;
}
-NEVER_INLINE Instruction* Machine::throwException(CallFrame*& callFrame, JSValue*& exceptionValue, const Instruction* vPC, bool explicitThrow)
+NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValuePtr& exceptionValue, unsigned bytecodeOffset, bool explicitThrow)
{
// Set up the exception object
-
+
CodeBlock* codeBlock = callFrame->codeBlock();
- if (exceptionValue->isObject()) {
+ if (exceptionValue.isObject()) {
JSObject* exception = asObject(exceptionValue);
if (exception->isNotAnObjectErrorStub()) {
- exception = createNotAnObjectError(callFrame, static_cast<JSNotAnObjectErrorStub*>(exception), vPC, codeBlock);
+ exception = createNotAnObjectError(callFrame, static_cast<JSNotAnObjectErrorStub*>(exception), bytecodeOffset, codeBlock);
exceptionValue = exception;
} else {
if (!exception->hasProperty(callFrame, Identifier(callFrame, "line")) &&
@@ -810,7 +758,7 @@ NEVER_INLINE Instruction* Machine::throwException(CallFrame*& callFrame, JSValue
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
- int line = codeBlock->expressionRangeForVPC(vPC, divotPoint, startOffset, endOffset);
+ int line = codeBlock->expressionRangeForBytecodeOffset(callFrame, bytecodeOffset, divotPoint, startOffset, endOffset);
exception->putWithAttributes(callFrame, Identifier(callFrame, "line"), jsNumber(callFrame, line), ReadOnly | DontDelete);
// We only hit this path for error messages and throw statements, which don't have a specific failure position
@@ -818,13 +766,13 @@ NEVER_INLINE Instruction* Machine::throwException(CallFrame*& callFrame, JSValue
exception->putWithAttributes(callFrame, Identifier(callFrame, expressionBeginOffsetPropertyName), jsNumber(callFrame, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(callFrame, Identifier(callFrame, expressionEndOffsetPropertyName), jsNumber(callFrame, divotPoint + endOffset), ReadOnly | DontDelete);
} else
- exception->putWithAttributes(callFrame, Identifier(callFrame, "line"), jsNumber(callFrame, codeBlock->lineNumberForVPC(vPC)), ReadOnly | DontDelete);
- exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerNode->sourceID()), ReadOnly | DontDelete);
- exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceURL"), jsOwnedString(callFrame, codeBlock->ownerNode->sourceURL()), ReadOnly | DontDelete);
+ exception->putWithAttributes(callFrame, Identifier(callFrame, "line"), jsNumber(callFrame, codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset)), ReadOnly | DontDelete);
+ exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerNode()->sourceID()), ReadOnly | DontDelete);
+ exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceURL"), jsOwnedString(callFrame, codeBlock->ownerNode()->sourceURL()), ReadOnly | DontDelete);
}
if (exception->isWatchdogException()) {
- while (unwindCallFrame(callFrame, exceptionValue, vPC, codeBlock)) {
+ while (unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) {
// Don't need handler checks or anything, we just want to unroll all the JS callframes possible.
}
return 0;
@@ -834,61 +782,47 @@ NEVER_INLINE Instruction* Machine::throwException(CallFrame*& callFrame, JSValue
if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
- debugger->exception(debuggerCallFrame, codeBlock->ownerNode->sourceID(), codeBlock->lineNumberForVPC(vPC));
+ debugger->exception(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset));
}
// If we throw in the middle of a call instruction, we need to notify
// the profiler manually that the call instruction has returned, since
// we'll never reach the relevant op_profile_did_call.
if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
- if (isCallOpcode(vPC[0].u.opcode))
- profiler->didExecute(callFrame, callFrame[vPC[2].u.operand].jsValue(callFrame));
- else if (vPC[8].u.opcode == getOpcode(op_construct))
- profiler->didExecute(callFrame, callFrame[vPC[10].u.operand].jsValue(callFrame));
+#if !ENABLE(JIT)
+ if (isCallBytecode(codeBlock->instructions()[bytecodeOffset].u.opcode))
+ profiler->didExecute(callFrame, callFrame[codeBlock->instructions()[bytecodeOffset + 2].u.operand].jsValue(callFrame));
+ else if (codeBlock->instructions()[bytecodeOffset + 8].u.opcode == getOpcode(op_construct))
+ profiler->didExecute(callFrame, callFrame[codeBlock->instructions()[bytecodeOffset + 10].u.operand].jsValue(callFrame));
+#else
+ int functionRegisterIndex;
+ if (codeBlock->functionRegisterForBytecodeOffset(bytecodeOffset, functionRegisterIndex))
+ profiler->didExecute(callFrame, callFrame[functionRegisterIndex].jsValue(callFrame));
+#endif
}
// Calculate an exception handler vPC, unwinding call frames as necessary.
- int scopeDepth;
- Instruction* handlerVPC;
-
- while (!codeBlock->getHandlerForVPC(vPC, handlerVPC, scopeDepth)) {
- if (!unwindCallFrame(callFrame, exceptionValue, vPC, codeBlock))
+ HandlerInfo* handler = 0;
+ while (!(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
+ if (!unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock))
return 0;
}
// Now unwind the scope chain within the exception handler's call frame.
- ScopeChain sc(callFrame->scopeChain());
- int scopeDelta = depth(codeBlock, sc) - scopeDepth;
+ ScopeChainNode* scopeChain = callFrame->scopeChain();
+ ScopeChain sc(scopeChain);
+ int scopeDelta = depth(codeBlock, sc) - handler->scopeDepth;
ASSERT(scopeDelta >= 0);
while (scopeDelta--)
- sc.pop();
- callFrame->setScopeChain(sc.node());
+ scopeChain = scopeChain->pop();
+ callFrame->setScopeChain(scopeChain);
- return handlerVPC;
+ return handler;
}
-class DynamicGlobalObjectScope : Noncopyable {
-public:
- DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject)
- : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
- , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
- {
- m_dynamicGlobalObjectSlot = dynamicGlobalObject;
- }
-
- ~DynamicGlobalObjectScope()
- {
- m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject;
- }
-
-private:
- JSGlobalObject*& m_dynamicGlobalObjectSlot;
- JSGlobalObject* m_savedDynamicGlobalObject;
-};
-
-JSValue* Machine::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue** exception)
+JSValuePtr Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValuePtr* exception)
{
ASSERT(!scopeChain->globalData->exception);
@@ -897,10 +831,10 @@ JSValue* Machine::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeC
return jsNull();
}
- CodeBlock* codeBlock = &programNode->byteCode(scopeChain);
+ CodeBlock* codeBlock = &programNode->bytecode(scopeChain);
Register* oldEnd = m_registerFile.end();
- Register* newEnd = oldEnd + codeBlock->numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->numCalleeRegisters;
+ Register* newEnd = oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
if (!m_registerFile.grow(newEnd)) {
*exception = createStackOverflowError(callFrame);
return jsNull();
@@ -912,26 +846,26 @@ JSValue* Machine::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeC
JSGlobalObject* globalObject = callFrame->dynamicGlobalObject();
globalObject->copyGlobalsTo(m_registerFile);
- CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->numParameters + RegisterFile::CallFrameHeaderSize);
- newCallFrame[codeBlock->thisRegister] = thisObj;
+ CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize);
+ newCallFrame[codeBlock->thisRegister()] = JSValuePtr(thisObj);
newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), 0, 0, 0);
- if (codeBlock->needsFullScopeChain)
+ if (codeBlock->needsFullScopeChain())
scopeChain->ref();
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
(*profiler)->willExecute(newCallFrame, programNode->sourceURL(), programNode->lineNo());
- JSValue* result;
+ JSValuePtr result;
{
SamplingTool::CallRecord callRecord(m_sampler);
m_reentryDepth++;
-#if ENABLE(CTI)
- if (!codeBlock->ctiCode)
- CTI::compile(this, newCallFrame, codeBlock);
- result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
+#if ENABLE(JIT)
+ if (!codeBlock->jitCode())
+ JIT::compile(scopeChain->globalData, codeBlock);
+ result = JIT::execute(codeBlock->jitCode(), &m_registerFile, newCallFrame, scopeChain->globalData, exception);
#else
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
#endif
@@ -949,7 +883,7 @@ JSValue* Machine::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeC
return result;
}
-JSValue* Machine::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValue** exception)
+JSValuePtr Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValuePtr* exception)
{
ASSERT(!scopeChain->globalData->exception);
@@ -970,12 +904,12 @@ JSValue* Machine::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFra
CallFrame* newCallFrame = CallFrame::create(oldEnd);
size_t dst = 0;
- newCallFrame[0] = thisObj;
+ newCallFrame[0] = JSValuePtr(thisObj);
ArgList::const_iterator end = args.end();
for (ArgList::const_iterator it = args.begin(); it != end; ++it)
newCallFrame[++dst] = *it;
- CodeBlock* codeBlock = &functionBodyNode->byteCode(scopeChain);
+ CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain);
newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
if (UNLIKELY(!newCallFrame)) {
*exception = createStackOverflowError(callFrame);
@@ -987,17 +921,17 @@ JSValue* Machine::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFra
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
- (*profiler)->willExecute(newCallFrame, function);
+ (*profiler)->willExecute(callFrame, function);
- JSValue* result;
+ JSValuePtr result;
{
SamplingTool::CallRecord callRecord(m_sampler);
m_reentryDepth++;
-#if ENABLE(CTI)
- if (!codeBlock->ctiCode)
- CTI::compile(this, newCallFrame, codeBlock);
- result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
+#if ENABLE(JIT)
+ if (!codeBlock->jitCode())
+ JIT::compile(scopeChain->globalData, codeBlock);
+ result = JIT::execute(codeBlock->jitCode(), &m_registerFile, newCallFrame, scopeChain->globalData, exception);
#else
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
#endif
@@ -1005,18 +939,18 @@ JSValue* Machine::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFra
}
if (*profiler)
- (*profiler)->didExecute(newCallFrame, function);
+ (*profiler)->didExecute(callFrame, function);
m_registerFile.shrink(oldEnd);
return result;
}
-JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue** exception)
+JSValuePtr Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValuePtr* exception)
{
- return execute(evalNode, callFrame, thisObj, m_registerFile.size() + evalNode->byteCode(scopeChain).numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
+ return execute(evalNode, callFrame, thisObj, m_registerFile.size() + evalNode->bytecode(scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
}
-JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int registerOffset, ScopeChainNode* scopeChain, JSValue** exception)
+JSValuePtr Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValuePtr* exception)
{
ASSERT(!scopeChain->globalData->exception);
@@ -1027,7 +961,7 @@ JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* th
DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
- EvalCodeBlock* codeBlock = &evalNode->byteCode(scopeChain);
+ EvalCodeBlock* codeBlock = &evalNode->bytecode(scopeChain);
JSVariableObject* variableObject;
for (ScopeChainNode* node = scopeChain; ; node = node->next) {
@@ -1042,9 +976,9 @@ JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* th
BatchedTransitionOptimizer optimizer(variableObject);
- const Node::VarStack& varStack = codeBlock->ownerNode->varStack();
- Node::VarStack::const_iterator varStackEnd = varStack.end();
- for (Node::VarStack::const_iterator it = varStack.begin(); it != varStackEnd; ++it) {
+ const DeclarationStacks::VarStack& varStack = codeBlock->ownerNode()->varStack();
+ DeclarationStacks::VarStack::const_iterator varStackEnd = varStack.end();
+ for (DeclarationStacks::VarStack::const_iterator it = varStack.begin(); it != varStackEnd; ++it) {
const Identifier& ident = (*it).first;
if (!variableObject->hasProperty(callFrame, ident)) {
PutPropertySlot slot;
@@ -1052,9 +986,9 @@ JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* th
}
}
- const Node::FunctionStack& functionStack = codeBlock->ownerNode->functionStack();
- Node::FunctionStack::const_iterator functionStackEnd = functionStack.end();
- for (Node::FunctionStack::const_iterator it = functionStack.begin(); it != functionStackEnd; ++it) {
+ const DeclarationStacks::FunctionStack& functionStack = codeBlock->ownerNode()->functionStack();
+ DeclarationStacks::FunctionStack::const_iterator functionStackEnd = functionStack.end();
+ for (DeclarationStacks::FunctionStack::const_iterator it = functionStack.begin(); it != functionStackEnd; ++it) {
PutPropertySlot slot;
variableObject->put(callFrame, (*it)->m_ident, (*it)->makeFunction(callFrame, scopeChain), slot);
}
@@ -1062,34 +996,34 @@ JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* th
}
Register* oldEnd = m_registerFile.end();
- Register* newEnd = m_registerFile.start() + registerOffset + codeBlock->numCalleeRegisters;
+ Register* newEnd = m_registerFile.start() + globalRegisterOffset + codeBlock->m_numCalleeRegisters;
if (!m_registerFile.grow(newEnd)) {
*exception = createStackOverflowError(callFrame);
return jsNull();
}
- CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + registerOffset);
+ CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + globalRegisterOffset);
// a 0 codeBlock indicates a built-in caller
- newCallFrame[codeBlock->thisRegister] = thisObj;
+ newCallFrame[codeBlock->thisRegister()] = JSValuePtr(thisObj);
newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, 0, 0);
- if (codeBlock->needsFullScopeChain)
+ if (codeBlock->needsFullScopeChain())
scopeChain->ref();
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
(*profiler)->willExecute(newCallFrame, evalNode->sourceURL(), evalNode->lineNo());
- JSValue* result;
+ JSValuePtr result;
{
SamplingTool::CallRecord callRecord(m_sampler);
m_reentryDepth++;
-#if ENABLE(CTI)
- if (!codeBlock->ctiCode)
- CTI::compile(this, newCallFrame, codeBlock);
- result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
+#if ENABLE(JIT)
+ if (!codeBlock->jitCode())
+ JIT::compile(scopeChain->globalData, codeBlock);
+ result = JIT::execute(codeBlock->jitCode(), &m_registerFile, newCallFrame, scopeChain->globalData, exception);
#else
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
#endif
@@ -1103,7 +1037,7 @@ JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* th
return result;
}
-NEVER_INLINE void Machine::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine)
+NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine)
{
Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
if (!debugger)
@@ -1111,27 +1045,27 @@ NEVER_INLINE void Machine::debug(CallFrame* callFrame, DebugHookID debugHookID,
switch (debugHookID) {
case DidEnterCallFrame:
- debugger->callEvent(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
+ debugger->callEvent(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine);
return;
case WillLeaveCallFrame:
- debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
+ debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine);
return;
case WillExecuteStatement:
- debugger->atStatement(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
+ debugger->atStatement(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine);
return;
case WillExecuteProgram:
- debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
+ debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), firstLine);
return;
case DidExecuteProgram:
- debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
+ debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine);
return;
case DidReachBreakpoint:
- debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
+ debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerNode()->sourceID(), lastLine);
return;
}
}
-void Machine::resetTimeoutCheck()
+void Interpreter::resetTimeoutCheck()
{
m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
m_timeAtLastCheckTimeout = 0;
@@ -1146,7 +1080,9 @@ static inline unsigned getCPUTime()
thread_basic_info_data_t info;
// Get thread information
- thread_info(mach_thread_self(), THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
+ mach_port_t threadPort = mach_thread_self();
+ thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
+ mach_port_deallocate(mach_task_self(), threadPort);
unsigned time = info.user_time.seconds * 1000 + info.user_time.microseconds / 1000;
time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000;
@@ -1180,14 +1116,14 @@ static inline unsigned getCPUTime()
// We have to return a JSValue here, gcc seems to produce worse code if
// we attempt to return a bool
-ALWAYS_INLINE JSValue* Machine::checkTimeout(JSGlobalObject* globalObject)
+ALWAYS_INLINE bool Interpreter::checkTimeout(JSGlobalObject* globalObject)
{
unsigned currentTime = getCPUTime();
if (!m_timeAtLastCheckTimeout) {
// Suspicious amount of looping in a script -- start timing it
m_timeAtLastCheckTimeout = currentTime;
- return noValue();
+ return false;
}
unsigned timeDiff = currentTime - m_timeAtLastCheckTimeout;
@@ -1208,43 +1144,43 @@ ALWAYS_INLINE JSValue* Machine::checkTimeout(JSGlobalObject* globalObject)
if (m_timeoutTime && m_timeExecuting > m_timeoutTime) {
if (globalObject->shouldInterruptScript())
- return jsNull(); // Appeasing GCC, all we need is a non-null js value.
+ return true;
resetTimeoutCheck();
}
- return noValue();
+ return false;
}
-NEVER_INLINE ScopeChainNode* Machine::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
+NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
{
int dst = (++vPC)->u.operand;
CodeBlock* codeBlock = callFrame->codeBlock();
- Identifier& property = codeBlock->identifiers[(++vPC)->u.operand];
- JSValue* value = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ Identifier& property = codeBlock->identifier((++vPC)->u.operand);
+ JSValuePtr value = callFrame[(++vPC)->u.operand].jsValue(callFrame);
JSObject* scope = new (callFrame) JSStaticScopeObject(callFrame, property, value, DontDelete);
- callFrame[dst] = scope;
+ callFrame[dst] = JSValuePtr(scope);
return callFrame->scopeChain()->push(scope);
}
-static StructureIDChain* cachePrototypeChain(CallFrame* callFrame, StructureID* structureID)
+static StructureChain* cachePrototypeChain(CallFrame* callFrame, Structure* structure)
{
- JSValue* prototype = structureID->prototypeForLookup(callFrame);
- if (JSImmediate::isImmediate(prototype))
+ JSValuePtr prototype = structure->prototypeForLookup(callFrame);
+ if (!prototype.isCell())
return 0;
- RefPtr<StructureIDChain> chain = StructureIDChain::create(asObject(prototype)->structureID());
- structureID->setCachedPrototypeChain(chain.release());
- return structureID->cachedPrototypeChain();
+ RefPtr<StructureChain> chain = StructureChain::create(asObject(prototype)->structure());
+ structure->setCachedPrototypeChain(chain.release());
+ return structure->cachedPrototypeChain();
}
-NEVER_INLINE void Machine::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue* baseValue, const PutPropertySlot& slot)
+NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValuePtr baseValue, const PutPropertySlot& slot)
{
// Recursive invocation may already have specialized this instruction.
if (vPC[0].u.opcode != getOpcode(op_put_by_id))
return;
- if (JSImmediate::isImmediate(baseValue))
+ if (!baseValue.isCell())
return;
// Uncacheable: give up.
@@ -1254,19 +1190,19 @@ NEVER_INLINE void Machine::tryCachePutByID(CallFrame* callFrame, CodeBlock* code
}
JSCell* baseCell = asCell(baseValue);
- StructureID* structureID = baseCell->structureID();
+ Structure* structure = baseCell->structure();
- if (structureID->isDictionary()) {
+ if (structure->isDictionary()) {
vPC[0] = getOpcode(op_put_by_id_generic);
return;
}
- // Cache miss: record StructureID to compare against next time.
- StructureID* lastStructureID = vPC[4].u.structureID;
- if (structureID != lastStructureID) {
- // First miss: record StructureID to compare against next time.
- if (!lastStructureID) {
- vPC[4] = structureID;
+ // Cache miss: record Structure to compare against next time.
+ Structure* lastStructure = vPC[4].u.structure;
+ if (structure != lastStructure) {
+ // First miss: record Structure to compare against next time.
+ if (!lastStructure) {
+ vPC[4] = structure;
return;
}
@@ -1275,7 +1211,7 @@ NEVER_INLINE void Machine::tryCachePutByID(CallFrame* callFrame, CodeBlock* code
return;
}
- // Cache hit: Specialize instruction and ref StructureIDs.
+ // Cache hit: Specialize instruction and ref Structures.
// If baseCell != slot.base(), then baseCell must be a proxy for another object.
if (baseCell != slot.base()) {
@@ -1283,14 +1219,14 @@ NEVER_INLINE void Machine::tryCachePutByID(CallFrame* callFrame, CodeBlock* code
return;
}
- // StructureID transition, cache transition info
+ // Structure transition, cache transition info
if (slot.type() == PutPropertySlot::NewProperty) {
vPC[0] = getOpcode(op_put_by_id_transition);
- vPC[4] = structureID->previousID();
- vPC[5] = structureID;
- StructureIDChain* chain = structureID->cachedPrototypeChain();
+ vPC[4] = structure->previousID();
+ vPC[5] = structure;
+ StructureChain* chain = structure->cachedPrototypeChain();
if (!chain) {
- chain = cachePrototypeChain(callFrame, structureID);
+ chain = cachePrototypeChain(callFrame, structure);
if (!chain) {
// This happens if someone has manually inserted null into the prototype chain
vPC[0] = getOpcode(op_put_by_id_generic);
@@ -1299,30 +1235,61 @@ NEVER_INLINE void Machine::tryCachePutByID(CallFrame* callFrame, CodeBlock* code
}
vPC[6] = chain;
vPC[7] = slot.cachedOffset();
- codeBlock->refStructureIDs(vPC);
+ codeBlock->refStructures(vPC);
return;
}
vPC[0] = getOpcode(op_put_by_id_replace);
vPC[5] = slot.cachedOffset();
- codeBlock->refStructureIDs(vPC);
+ codeBlock->refStructures(vPC);
}
-NEVER_INLINE void Machine::uncachePutByID(CodeBlock* codeBlock, Instruction* vPC)
+NEVER_INLINE void Interpreter::uncachePutByID(CodeBlock* codeBlock, Instruction* vPC)
{
- codeBlock->derefStructureIDs(vPC);
+ codeBlock->derefStructures(vPC);
vPC[0] = getOpcode(op_put_by_id);
vPC[4] = 0;
}
-NEVER_INLINE void Machine::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue* baseValue, const Identifier& propertyName, const PropertySlot& slot)
+static size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValuePtr baseValue, const PropertySlot& slot)
+{
+ JSCell* cell = asCell(baseValue);
+ size_t count = 0;
+
+ while (slot.slotBase() != cell) {
+ JSValuePtr v = cell->structure()->prototypeForLookup(callFrame);
+
+ // If we didn't find slotBase in baseValue's prototype chain, then baseValue
+ // must be a proxy for another object.
+
+ if (v.isNull())
+ return 0;
+
+ cell = asCell(v);
+
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (cell->structure()->isDictionary()) {
+ RefPtr<Structure> transition = Structure::fromDictionaryTransition(cell->structure());
+ asObject(cell)->setStructure(transition.release());
+ cell->structure()->setCachedPrototypeChain(0);
+ }
+
+ ++count;
+ }
+
+ ASSERT(count);
+ return count;
+}
+
+NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot& slot)
{
// Recursive invocation may already have specialized this instruction.
if (vPC[0].u.opcode != getOpcode(op_get_by_id))
return;
// FIXME: Cache property access for immediates.
- if (JSImmediate::isImmediate(baseValue)) {
+ if (!baseValue.isCell()) {
vPC[0] = getOpcode(op_get_by_id_generic);
return;
}
@@ -1343,19 +1310,19 @@ NEVER_INLINE void Machine::tryCacheGetByID(CallFrame* callFrame, CodeBlock* code
return;
}
- StructureID* structureID = asCell(baseValue)->structureID();
+ Structure* structure = asCell(baseValue)->structure();
- if (structureID->isDictionary()) {
+ if (structure->isDictionary()) {
vPC[0] = getOpcode(op_get_by_id_generic);
return;
}
// Cache miss
- StructureID* lastStructureID = vPC[4].u.structureID;
- if (structureID != lastStructureID) {
- // First miss: record StructureID to compare against next time.
- if (!lastStructureID) {
- vPC[4] = structureID;
+ Structure* lastStructure = vPC[4].u.structure;
+ if (structure != lastStructure) {
+ // First miss: record Structure to compare against next time.
+ if (!lastStructure) {
+ vPC[4] = structure;
return;
}
@@ -1364,116 +1331,95 @@ NEVER_INLINE void Machine::tryCacheGetByID(CallFrame* callFrame, CodeBlock* code
return;
}
- // Cache hit: Specialize instruction and ref StructureIDs.
+ // Cache hit: Specialize instruction and ref Structures.
if (slot.slotBase() == baseValue) {
vPC[0] = getOpcode(op_get_by_id_self);
vPC[5] = slot.cachedOffset();
- codeBlock->refStructureIDs(vPC);
+ codeBlock->refStructures(vPC);
return;
}
- if (slot.slotBase() == structureID->prototypeForLookup(callFrame)) {
- ASSERT(slot.slotBase()->isObject());
+ if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
+ ASSERT(slot.slotBase().isObject());
JSObject* baseObject = asObject(slot.slotBase());
- // Heavy access to a prototype is a good indication that it's not being
- // used as a dictionary.
- if (baseObject->structureID()->isDictionary()) {
- RefPtr<StructureID> transition = StructureID::fromDictionaryTransition(baseObject->structureID());
- baseObject->setStructureID(transition.release());
- asCell(baseValue)->structureID()->setCachedPrototypeChain(0);
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (baseObject->structure()->isDictionary()) {
+ RefPtr<Structure> transition = Structure::fromDictionaryTransition(baseObject->structure());
+ baseObject->setStructure(transition.release());
+ asCell(baseValue)->structure()->setCachedPrototypeChain(0);
}
vPC[0] = getOpcode(op_get_by_id_proto);
- vPC[5] = baseObject->structureID();
+ vPC[5] = baseObject->structure();
vPC[6] = slot.cachedOffset();
- codeBlock->refStructureIDs(vPC);
+ codeBlock->refStructures(vPC);
return;
}
- size_t count = 0;
- JSObject* o = asObject(baseValue);
- while (slot.slotBase() != o) {
- JSValue* v = o->structureID()->prototypeForLookup(callFrame);
-
- // If we didn't find base in baseValue's prototype chain, then baseValue
- // must be a proxy for another object.
- if (v->isNull()) {
- vPC[0] = getOpcode(op_get_by_id_generic);
- return;
- }
-
- o = asObject(v);
-
- // Heavy access to a prototype is a good indication that it's not being
- // used as a dictionary.
- if (o->structureID()->isDictionary()) {
- RefPtr<StructureID> transition = StructureID::fromDictionaryTransition(o->structureID());
- o->setStructureID(transition.release());
- asObject(baseValue)->structureID()->setCachedPrototypeChain(0);
- }
-
- ++count;
+ size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot);
+ if (!count) {
+ vPC[0] = getOpcode(op_get_by_id_generic);
+ return;
}
- StructureIDChain* chain = structureID->cachedPrototypeChain();
+ StructureChain* chain = structure->cachedPrototypeChain();
if (!chain)
- chain = cachePrototypeChain(callFrame, structureID);
+ chain = cachePrototypeChain(callFrame, structure);
ASSERT(chain);
vPC[0] = getOpcode(op_get_by_id_chain);
- vPC[4] = structureID;
+ vPC[4] = structure;
vPC[5] = chain;
vPC[6] = count;
vPC[7] = slot.cachedOffset();
- codeBlock->refStructureIDs(vPC);
+ codeBlock->refStructures(vPC);
}
-NEVER_INLINE void Machine::uncacheGetByID(CodeBlock* codeBlock, Instruction* vPC)
+NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock* codeBlock, Instruction* vPC)
{
- codeBlock->derefStructureIDs(vPC);
+ codeBlock->derefStructures(vPC);
vPC[0] = getOpcode(op_get_by_id);
vPC[4] = 0;
}
-JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame, JSValue** exception)
+JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame, JSValuePtr* exception)
{
// One-time initialization of our address tables. We have to put this code
// here because our labels are only in scope inside this function.
if (flag == InitializeAndReturn) {
#if HAVE(COMPUTED_GOTO)
- #define ADD_OPCODE(id) m_opcodeTable[id] = &&id;
- FOR_EACH_OPCODE_ID(ADD_OPCODE);
- #undef ADD_OPCODE
+ #define ADD_BYTECODE(id, length) m_opcodeTable[id] = &&id;
+ FOR_EACH_OPCODE_ID(ADD_BYTECODE);
+ #undef ADD_BYTECODE
- #define ADD_OPCODE_ID(id) m_opcodeIDTable.add(&&id, id);
+ #define ADD_OPCODE_ID(id, length) m_opcodeIDTable.add(&&id, id);
FOR_EACH_OPCODE_ID(ADD_OPCODE_ID);
#undef ADD_OPCODE_ID
ASSERT(m_opcodeIDTable.size() == numOpcodeIDs);
- op_throw_end_indirect = &&op_throw_end;
- op_call_indirect = &&op_call;
#endif // HAVE(COMPUTED_GOTO)
return noValue();
}
-#if ENABLE(CTI)
+#if ENABLE(JIT)
// Currently with CTI enabled we never interpret functions
ASSERT_NOT_REACHED();
#endif
JSGlobalData* globalData = &callFrame->globalData();
- JSValue* exceptionValue = noValue();
- Instruction* handlerVPC = 0;
+ JSValuePtr exceptionValue = noValue();
+ HandlerInfo* handler = 0;
- Instruction* vPC = callFrame->codeBlock()->instructions.begin();
+ Instruction* vPC = callFrame->codeBlock()->instructions().begin();
Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();
unsigned tickCount = m_ticksUntilNextTimeoutCheck + 1;
-#define VM_CHECK_EXCEPTION() \
+#define CHECK_FOR_EXCEPTION() \
do { \
if (UNLIKELY(globalData->exception != noValue())) { \
exceptionValue = globalData->exception; \
@@ -1487,52 +1433,54 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
#define CHECK_FOR_TIMEOUT() \
if (!--tickCount) { \
- if ((exceptionValue = checkTimeout(callFrame->dynamicGlobalObject()))) \
+ if (checkTimeout(callFrame->dynamicGlobalObject())) { \
+ exceptionValue = jsNull(); \
goto vm_throw; \
+ } \
tickCount = m_ticksUntilNextTimeoutCheck; \
}
#if ENABLE(OPCODE_SAMPLING)
#define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)
- #define CTI_SAMPLER ARG_globalData->machine->sampler()
+ #define CTI_SAMPLER ARG_globalData->interpreter->sampler()
#else
#define SAMPLE(codeBlock, vPC)
#define CTI_SAMPLER 0
#endif
#if HAVE(COMPUTED_GOTO)
- #define NEXT_OPCODE SAMPLE(callFrame->codeBlock(), vPC); goto *vPC->u.opcode
+ #define NEXT_INSTRUCTION() SAMPLE(callFrame->codeBlock(), vPC); goto *vPC->u.opcode
#if ENABLE(OPCODE_STATS)
- #define BEGIN_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode);
+ #define DEFINE_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode);
#else
- #define BEGIN_OPCODE(opcode) opcode:
+ #define DEFINE_OPCODE(opcode) opcode:
#endif
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
#else
- #define NEXT_OPCODE SAMPLE(callFrame->codeBlock(), vPC); goto interpreterLoopStart
+ #define NEXT_INSTRUCTION() SAMPLE(callFrame->codeBlock(), vPC); goto interpreterLoopStart
#if ENABLE(OPCODE_STATS)
- #define BEGIN_OPCODE(opcode) case opcode: OpcodeStats::recordInstruction(opcode);
+ #define DEFINE_OPCODE(opcode) case opcode: OpcodeStats::recordInstruction(opcode);
#else
- #define BEGIN_OPCODE(opcode) case opcode:
+ #define DEFINE_OPCODE(opcode) case opcode:
#endif
while (1) { // iterator loop begins
interpreterLoopStart:;
switch (vPC->u.opcode)
#endif
{
- BEGIN_OPCODE(op_new_object) {
+ DEFINE_OPCODE(op_new_object) {
/* new_object dst(r)
Constructs a new empty Object instance using the original
constructor, and puts the result in register dst.
*/
int dst = (++vPC)->u.operand;
- callFrame[dst] = constructEmptyObject(callFrame);
+ callFrame[dst] = JSValuePtr(constructEmptyObject(callFrame));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_new_array) {
+ DEFINE_OPCODE(op_new_array) {
/* new_array dst(r) firstArg(r) argCount(n)
Constructs a new Array instance using the original
@@ -1544,12 +1492,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int firstArg = (++vPC)->u.operand;
int argCount = (++vPC)->u.operand;
ArgList args(callFrame->registers() + firstArg, argCount);
- callFrame[dst] = constructArray(callFrame, args);
+ callFrame[dst] = JSValuePtr(constructArray(callFrame, args));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_new_regexp) {
+ DEFINE_OPCODE(op_new_regexp) {
/* new_regexp dst(r) regExp(re)
Constructs a new RegExp instance using the original
@@ -1558,12 +1506,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int regExp = (++vPC)->u.operand;
- callFrame[dst] = new (globalData) RegExpObject(callFrame->scopeChain()->globalObject()->regExpStructure(), callFrame->codeBlock()->regexps[regExp]);
+ callFrame[dst] = JSValuePtr(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject()->regExpStructure(), callFrame->codeBlock()->regexp(regExp)));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_mov) {
+ DEFINE_OPCODE(op_mov) {
/* mov dst(r) src(r)
Copies register src to register dst.
@@ -1573,9 +1521,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
callFrame[dst] = callFrame[src];
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_eq) {
+ DEFINE_OPCODE(op_eq) {
/* eq dst(r) src1(r) src2(r)
Checks whether register src1 and register src2 are equal,
@@ -1583,39 +1531,39 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
as a boolean in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- if (JSImmediate::areBothImmediateNumbers(src1, src2))
- callFrame[dst] = jsBoolean(src1 == src2);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
+ callFrame[dst] = JSFastMath::equal(src1, src2);
else {
- JSValue* result = jsBoolean(equalSlowCase(callFrame, src1, src2));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsBoolean(JSValuePtr::equalSlowCase(callFrame, src1, src2));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_eq_null) {
+ DEFINE_OPCODE(op_eq_null) {
/* eq_null dst(r) src(r)
Checks whether register src is null, as with the ECMAScript '!='
operator, and puts the result as a boolean in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- if (src->isUndefinedOrNull()) {
+ if (src.isUndefinedOrNull()) {
callFrame[dst] = jsBoolean(true);
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- callFrame[dst] = jsBoolean(!JSImmediate::isImmediate(src) && src->asCell()->structureID()->typeInfo().masqueradesAsUndefined());
+ callFrame[dst] = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_neq) {
+ DEFINE_OPCODE(op_neq) {
/* neq dst(r) src1(r) src2(r)
Checks whether register src1 and register src2 are not
@@ -1623,39 +1571,39 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
result as a boolean in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- if (JSImmediate::areBothImmediateNumbers(src1, src2))
- callFrame[dst] = jsBoolean(src1 != src2);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
+ callFrame[dst] = JSFastMath::notEqual(src1, src2);
else {
- JSValue* result = jsBoolean(!equalSlowCase(callFrame, src1, src2));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsBoolean(!JSValuePtr::equalSlowCase(callFrame, src1, src2));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_neq_null) {
+ DEFINE_OPCODE(op_neq_null) {
/* neq_null dst(r) src(r)
Checks whether register src is not null, as with the ECMAScript '!='
operator, and puts the result as a boolean in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- if (src->isUndefinedOrNull()) {
+ if (src.isUndefinedOrNull()) {
callFrame[dst] = jsBoolean(false);
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- callFrame[dst] = jsBoolean(JSImmediate::isImmediate(src) || !asCell(src)->structureID()->typeInfo().masqueradesAsUndefined());
+ callFrame[dst] = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined());
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_stricteq) {
+ DEFINE_OPCODE(op_stricteq) {
/* stricteq dst(r) src1(r) src2(r)
Checks whether register src1 and register src2 are strictly
@@ -1663,19 +1611,14 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
result as a boolean in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- if (JSImmediate::areBothImmediate(src1, src2))
- callFrame[dst] = jsBoolean(src1 == src2);
- else if (JSImmediate::isEitherImmediate(src1, src2) & (src1 != JSImmediate::zeroImmediate()) & (src2 != JSImmediate::zeroImmediate()))
- callFrame[dst] = jsBoolean(false);
- else
- callFrame[dst] = jsBoolean(strictEqualSlowCase(src1, src2));
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ callFrame[dst] = jsBoolean(JSValuePtr::strictEqual(src1, src2));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_nstricteq) {
+ DEFINE_OPCODE(op_nstricteq) {
/* nstricteq dst(r) src1(r) src2(r)
Checks whether register src1 and register src2 are not
@@ -1683,20 +1626,14 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
puts the result as a boolean in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-
- if (JSImmediate::areBothImmediate(src1, src2))
- callFrame[dst] = jsBoolean(src1 != src2);
- else if (JSImmediate::isEitherImmediate(src1, src2) & (src1 != JSImmediate::zeroImmediate()) & (src2 != JSImmediate::zeroImmediate()))
- callFrame[dst] = jsBoolean(true);
- else
- callFrame[dst] = jsBoolean(!strictEqualSlowCase(src1, src2));
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ callFrame[dst] = jsBoolean(!JSValuePtr::strictEqual(src1, src2));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_less) {
+ DEFINE_OPCODE(op_less) {
/* less dst(r) src1(r) src2(r)
Checks whether register src1 is less than register src2, as
@@ -1704,16 +1641,16 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
a boolean in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* result = jsBoolean(jsLess(callFrame, src1, src2));
- VM_CHECK_EXCEPTION();
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr result = jsBoolean(jsLess(callFrame, src1, src2));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_lesseq) {
+ DEFINE_OPCODE(op_lesseq) {
/* lesseq dst(r) src1(r) src2(r)
Checks whether register src1 is less than or equal to
@@ -1721,54 +1658,54 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
puts the result as a boolean in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* result = jsBoolean(jsLessEq(callFrame, src1, src2));
- VM_CHECK_EXCEPTION();
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr result = jsBoolean(jsLessEq(callFrame, src1, src2));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_pre_inc) {
+ DEFINE_OPCODE(op_pre_inc) {
/* pre_inc srcDst(r)
Converts register srcDst to number, adds one, and puts the result
back in register srcDst.
*/
int srcDst = (++vPC)->u.operand;
- JSValue* v = callFrame[srcDst].jsValue(callFrame);
- if (JSImmediate::canDoFastAdditiveOperations(v))
- callFrame[srcDst] = JSImmediate::incImmediateNumber(v);
+ JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
+ if (JSFastMath::canDoFastAdditiveOperations(v))
+ callFrame[srcDst] = JSValuePtr(JSFastMath::incImmediateNumber(v));
else {
- JSValue* result = jsNumber(callFrame, v->toNumber(callFrame) + 1);
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, v.toNumber(callFrame) + 1);
+ CHECK_FOR_EXCEPTION();
callFrame[srcDst] = result;
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_pre_dec) {
+ DEFINE_OPCODE(op_pre_dec) {
/* pre_dec srcDst(r)
Converts register srcDst to number, subtracts one, and puts the result
back in register srcDst.
*/
int srcDst = (++vPC)->u.operand;
- JSValue* v = callFrame[srcDst].jsValue(callFrame);
- if (JSImmediate::canDoFastAdditiveOperations(v))
- callFrame[srcDst] = JSImmediate::decImmediateNumber(v);
+ JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
+ if (JSFastMath::canDoFastAdditiveOperations(v))
+ callFrame[srcDst] = JSValuePtr(JSFastMath::decImmediateNumber(v));
else {
- JSValue* result = jsNumber(callFrame, v->toNumber(callFrame) - 1);
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, v.toNumber(callFrame) - 1);
+ CHECK_FOR_EXCEPTION();
callFrame[srcDst] = result;
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_post_inc) {
+ DEFINE_OPCODE(op_post_inc) {
/* post_inc dst(r) srcDst(r)
Converts register srcDst to number. The number itself is
@@ -1777,21 +1714,21 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int srcDst = (++vPC)->u.operand;
- JSValue* v = callFrame[srcDst].jsValue(callFrame);
- if (JSImmediate::canDoFastAdditiveOperations(v)) {
+ JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
+ if (JSFastMath::canDoFastAdditiveOperations(v)) {
callFrame[dst] = v;
- callFrame[srcDst] = JSImmediate::incImmediateNumber(v);
+ callFrame[srcDst] = JSValuePtr(JSFastMath::incImmediateNumber(v));
} else {
- JSValue* number = callFrame[srcDst].jsValue(callFrame)->toJSNumber(callFrame);
- VM_CHECK_EXCEPTION();
+ JSValuePtr number = callFrame[srcDst].jsValue(callFrame).toJSNumber(callFrame);
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = number;
- callFrame[srcDst] = jsNumber(callFrame, number->uncheckedGetNumber() + 1);
+ callFrame[srcDst] = JSValuePtr(jsNumber(callFrame, number.uncheckedGetNumber() + 1));
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_post_dec) {
+ DEFINE_OPCODE(op_post_dec) {
/* post_dec dst(r) srcDst(r)
Converts register srcDst to number. The number itself is
@@ -1800,21 +1737,21 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int srcDst = (++vPC)->u.operand;
- JSValue* v = callFrame[srcDst].jsValue(callFrame);
- if (JSImmediate::canDoFastAdditiveOperations(v)) {
+ JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
+ if (JSFastMath::canDoFastAdditiveOperations(v)) {
callFrame[dst] = v;
- callFrame[srcDst] = JSImmediate::decImmediateNumber(v);
+ callFrame[srcDst] = JSValuePtr(JSFastMath::decImmediateNumber(v));
} else {
- JSValue* number = callFrame[srcDst].jsValue(callFrame)->toJSNumber(callFrame);
- VM_CHECK_EXCEPTION();
+ JSValuePtr number = callFrame[srcDst].jsValue(callFrame).toJSNumber(callFrame);
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = number;
- callFrame[srcDst] = jsNumber(callFrame, number->uncheckedGetNumber() - 1);
+ callFrame[srcDst] = JSValuePtr(jsNumber(callFrame, number.uncheckedGetNumber() - 1));
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_to_jsnumber) {
+ DEFINE_OPCODE(op_to_jsnumber) {
/* to_jsnumber dst(r) src(r)
Converts register src to number, and puts the result
@@ -1823,41 +1760,40 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- JSValue* srcVal = callFrame[src].jsValue(callFrame);
+ JSValuePtr srcVal = callFrame[src].jsValue(callFrame);
- if (LIKELY(srcVal->isNumber()))
+ if (LIKELY(srcVal.isNumber()))
callFrame[dst] = callFrame[src];
else {
- JSValue* result = srcVal->toJSNumber(callFrame);
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = srcVal.toJSNumber(callFrame);
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_negate) {
+ DEFINE_OPCODE(op_negate) {
/* negate dst(r) src(r)
Converts register src to number, negates it, and puts the
result in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
++vPC;
double v;
- if (fastIsNumber(src, v))
- callFrame[dst] = jsNumber(callFrame, -v);
+ if (src.getNumber(v))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, -v));
else {
- JSValue* result = jsNumber(callFrame, -src->toNumber(callFrame));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, -src.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
- ++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_add) {
+ DEFINE_OPCODE(op_add) {
/* add dst(r) src1(r) src2(r)
Adds register src1 and register src2, and puts the result
@@ -1865,48 +1801,48 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
numeric add, depending on the types of the operands.)
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
- callFrame[dst] = JSImmediate::addImmediateNumbers(src1, src2);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ if (JSFastMath::canDoFastAdditiveOperations(src1, src2))
+ callFrame[dst] = JSValuePtr(JSFastMath::addImmediateNumbers(src1, src2));
else {
- JSValue* result = jsAdd(callFrame, src1, src2);
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsAdd(callFrame, src1, src2);
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
vPC += 2;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_mul) {
+ DEFINE_OPCODE(op_mul) {
/* mul dst(r) src1(r) src2(r)
Multiplies register src1 and register src2 (converted to
numbers), and puts the product in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
double left;
double right;
- if (JSImmediate::areBothImmediateNumbers(src1, src2)) {
- int32_t left = JSImmediate::getTruncatedInt32(src1);
- int32_t right = JSImmediate::getTruncatedInt32(src2);
+ if (JSValuePtr::areBothInt32Fast(src1, src2)) {
+ int32_t left = src1.getInt32Fast();
+ int32_t right = src2.getInt32Fast();
if ((left | right) >> 15 == 0)
- callFrame[dst] = jsNumber(callFrame, left * right);
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, left * right));
else
- callFrame[dst] = jsNumber(callFrame, static_cast<double>(left) * static_cast<double>(right));
- } else if (fastIsNumber(src1, left) && fastIsNumber(src2, right))
- callFrame[dst] = jsNumber(callFrame, left * right);
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, static_cast<double>(left) * static_cast<double>(right)));
+ } else if (src1.getNumber(left) && src2.getNumber(right))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, left * right));
else {
- JSValue* result = jsNumber(callFrame, src1->toNumber(callFrame) * src2->toNumber(callFrame));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, src1.toNumber(callFrame) * src2.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
vPC += 2;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_div) {
+ DEFINE_OPCODE(op_div) {
/* div dst(r) dividend(r) divisor(r)
Divides register dividend (converted to number) by the
@@ -1914,21 +1850,21 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
quotient in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* dividend = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* divisor = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr dividend = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr divisor = callFrame[(++vPC)->u.operand].jsValue(callFrame);
double left;
double right;
- if (fastIsNumber(dividend, left) && fastIsNumber(divisor, right))
- callFrame[dst] = jsNumber(callFrame, left / right);
+ if (dividend.getNumber(left) && divisor.getNumber(right))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, left / right));
else {
- JSValue* result = jsNumber(callFrame, dividend->toNumber(callFrame) / divisor->toNumber(callFrame));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_mod) {
+ DEFINE_OPCODE(op_mod) {
/* mod dst(r) dividend(r) divisor(r)
Divides register dividend (converted to number) by
@@ -1939,23 +1875,27 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int dividend = (++vPC)->u.operand;
int divisor = (++vPC)->u.operand;
- JSValue* dividendValue = callFrame[dividend].jsValue(callFrame);
- JSValue* divisorValue = callFrame[divisor].jsValue(callFrame);
+ JSValuePtr dividendValue = callFrame[dividend].jsValue(callFrame);
+ JSValuePtr divisorValue = callFrame[divisor].jsValue(callFrame);
- if (JSImmediate::areBothImmediateNumbers(dividendValue, divisorValue) && divisorValue != JSImmediate::from(0)) {
- callFrame[dst] = JSImmediate::from(JSImmediate::getTruncatedInt32(dividendValue) % JSImmediate::getTruncatedInt32(divisorValue));
+ if (JSValuePtr::areBothInt32Fast(dividendValue, divisorValue) && divisorValue != js0()) {
+ // We expect the result of the modulus of a number that was representable as an int32 to also be representable
+ // as an int32.
+ JSValuePtr result = JSValuePtr::makeInt32Fast(dividendValue.getInt32Fast() % divisorValue.getInt32Fast());
+ ASSERT(result);
+ callFrame[dst] = result;
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- double d = dividendValue->toNumber(callFrame);
- JSValue* result = jsNumber(callFrame, fmod(d, divisorValue->toNumber(callFrame)));
- VM_CHECK_EXCEPTION();
+ double d = dividendValue.toNumber(callFrame);
+ JSValuePtr result = jsNumber(callFrame, fmod(d, divisorValue.toNumber(callFrame)));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_sub) {
+ DEFINE_OPCODE(op_sub) {
/* sub dst(r) src1(r) src2(r)
Subtracts register src2 (converted to number) from register
@@ -1963,23 +1903,23 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
double left;
double right;
- if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
- callFrame[dst] = JSImmediate::subImmediateNumbers(src1, src2);
- else if (fastIsNumber(src1, left) && fastIsNumber(src2, right))
- callFrame[dst] = jsNumber(callFrame, left - right);
+ if (JSFastMath::canDoFastAdditiveOperations(src1, src2))
+ callFrame[dst] = JSValuePtr(JSFastMath::subImmediateNumbers(src1, src2));
+ else if (src1.getNumber(left) && src2.getNumber(right))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, left - right));
else {
- JSValue* result = jsNumber(callFrame, src1->toNumber(callFrame) - src2->toNumber(callFrame));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, src1.toNumber(callFrame) - src2.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
vPC += 2;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_lshift) {
+ DEFINE_OPCODE(op_lshift) {
/* lshift dst(r) val(r) shift(r)
Performs left shift of register val (converted to int32) by
@@ -1987,24 +1927,24 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
int32_t left;
uint32_t right;
- if (JSImmediate::areBothImmediateNumbers(val, shift))
- callFrame[dst] = jsNumber(callFrame, JSImmediate::getTruncatedInt32(val) << (JSImmediate::getTruncatedUInt32(shift) & 0x1f));
- else if (fastToInt32(val, left) && fastToUInt32(shift, right))
- callFrame[dst] = jsNumber(callFrame, left << (right & 0x1f));
+ if (JSValuePtr::areBothInt32Fast(val, shift))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, val.getInt32Fast() << (shift.getInt32Fast() & 0x1f)));
+ else if (val.numberToInt32(left) && shift.numberToUInt32(right))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, left << (right & 0x1f)));
else {
- JSValue* result = jsNumber(callFrame, (val->toInt32(callFrame)) << (shift->toUInt32(callFrame) & 0x1f));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_rshift) {
+ DEFINE_OPCODE(op_rshift) {
/* rshift dst(r) val(r) shift(r)
Performs arithmetic right shift of register val (converted
@@ -2012,24 +1952,24 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
uint32), and puts the result in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
int32_t left;
uint32_t right;
- if (JSImmediate::areBothImmediateNumbers(val, shift))
- callFrame[dst] = JSImmediate::rightShiftImmediateNumbers(val, shift);
- else if (fastToInt32(val, left) && fastToUInt32(shift, right))
- callFrame[dst] = jsNumber(callFrame, left >> (right & 0x1f));
+ if (JSFastMath::canDoFastRshift(val, shift))
+ callFrame[dst] = JSValuePtr(JSFastMath::rightShiftImmediateNumbers(val, shift));
+ else if (val.numberToInt32(left) && shift.numberToUInt32(right))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, left >> (right & 0x1f)));
else {
- JSValue* result = jsNumber(callFrame, (val->toInt32(callFrame)) >> (shift->toUInt32(callFrame) & 0x1f));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_urshift) {
+ DEFINE_OPCODE(op_urshift) {
/* rshift dst(r) val(r) shift(r)
Performs logical right shift of register val (converted
@@ -2037,20 +1977,20 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
uint32), and puts the result in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- if (JSImmediate::areBothImmediateNumbers(val, shift) && !JSImmediate::isNegative(val))
- callFrame[dst] = JSImmediate::rightShiftImmediateNumbers(val, shift);
+ JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ if (JSFastMath::canDoFastUrshift(val, shift))
+ callFrame[dst] = JSValuePtr(JSFastMath::rightShiftImmediateNumbers(val, shift));
else {
- JSValue* result = jsNumber(callFrame, (val->toUInt32(callFrame)) >> (shift->toUInt32(callFrame) & 0x1f));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_bitand) {
+ DEFINE_OPCODE(op_bitand) {
/* bitand dst(r) src1(r) src2(r)
Computes bitwise AND of register src1 (converted to int32)
@@ -2058,24 +1998,24 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
int32_t left;
int32_t right;
- if (JSImmediate::areBothImmediateNumbers(src1, src2))
- callFrame[dst] = JSImmediate::andImmediateNumbers(src1, src2);
- else if (fastToInt32(src1, left) && fastToInt32(src2, right))
- callFrame[dst] = jsNumber(callFrame, left & right);
+ if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
+ callFrame[dst] = JSValuePtr(JSFastMath::andImmediateNumbers(src1, src2));
+ else if (src1.numberToInt32(left) && src2.numberToInt32(right))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, left & right));
else {
- JSValue* result = jsNumber(callFrame, src1->toInt32(callFrame) & src2->toInt32(callFrame));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, src1.toInt32(callFrame) & src2.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
vPC += 2;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_bitxor) {
+ DEFINE_OPCODE(op_bitxor) {
/* bitxor dst(r) src1(r) src2(r)
Computes bitwise XOR of register src1 (converted to int32)
@@ -2083,24 +2023,24 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
int32_t left;
int32_t right;
- if (JSImmediate::areBothImmediateNumbers(src1, src2))
- callFrame[dst] = JSImmediate::xorImmediateNumbers(src1, src2);
- else if (fastToInt32(src1, left) && fastToInt32(src2, right))
- callFrame[dst] = jsNumber(callFrame, left ^ right);
+ if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
+ callFrame[dst] = JSValuePtr(JSFastMath::xorImmediateNumbers(src1, src2));
+ else if (src1.numberToInt32(left) && src2.numberToInt32(right))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, left ^ right));
else {
- JSValue* result = jsNumber(callFrame, src1->toInt32(callFrame) ^ src2->toInt32(callFrame));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
vPC += 2;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_bitor) {
+ DEFINE_OPCODE(op_bitor) {
/* bitor dst(r) src1(r) src2(r)
Computes bitwise OR of register src1 (converted to int32)
@@ -2108,43 +2048,43 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
result in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
int32_t left;
int32_t right;
- if (JSImmediate::areBothImmediateNumbers(src1, src2))
- callFrame[dst] = JSImmediate::orImmediateNumbers(src1, src2);
- else if (fastToInt32(src1, left) && fastToInt32(src2, right))
- callFrame[dst] = jsNumber(callFrame, left | right);
+ if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
+ callFrame[dst] = JSValuePtr(JSFastMath::orImmediateNumbers(src1, src2));
+ else if (src1.numberToInt32(left) && src2.numberToInt32(right))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, left | right));
else {
- JSValue* result = jsNumber(callFrame, src1->toInt32(callFrame) | src2->toInt32(callFrame));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, src1.toInt32(callFrame) | src2.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
vPC += 2;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_bitnot) {
+ DEFINE_OPCODE(op_bitnot) {
/* bitnot dst(r) src(r)
Computes bitwise NOT of register src1 (converted to int32),
and puts the result in register dst.
*/
int dst = (++vPC)->u.operand;
- JSValue* src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
int32_t value;
- if (fastToInt32(src, value))
- callFrame[dst] = jsNumber(callFrame, ~value);
+ if (src.numberToInt32(value))
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, ~value));
else {
- JSValue* result = jsNumber(callFrame, ~src->toInt32(callFrame));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsNumber(callFrame, ~src.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_not) {
+ DEFINE_OPCODE(op_not) {
/* not dst(r) src(r)
Computes logical NOT of register src (converted to
@@ -2152,14 +2092,14 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- JSValue* result = jsBoolean(!callFrame[src].jsValue(callFrame)->toBoolean(callFrame));
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = jsBoolean(!callFrame[src].jsValue(callFrame).toBoolean(callFrame));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_instanceof) {
+ DEFINE_OPCODE(op_instanceof) {
/* instanceof dst(r) value(r) constructor(r) constructorProto(r)
Tests whether register value is an instance of register
@@ -2177,18 +2117,18 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int base = vPC[3].u.operand;
int baseProto = vPC[4].u.operand;
- JSValue* baseVal = callFrame[base].jsValue(callFrame);
+ JSValuePtr baseVal = callFrame[base].jsValue(callFrame);
if (isNotObject(callFrame, true, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
goto vm_throw;
JSObject* baseObj = asObject(baseVal);
- callFrame[dst] = jsBoolean(baseObj->structureID()->typeInfo().implementsHasInstance() ? baseObj->hasInstance(callFrame, callFrame[value].jsValue(callFrame), callFrame[baseProto].jsValue(callFrame)) : false);
+ callFrame[dst] = jsBoolean(baseObj->structure()->typeInfo().implementsHasInstance() ? baseObj->hasInstance(callFrame, callFrame[value].jsValue(callFrame), callFrame[baseProto].jsValue(callFrame)) : false);
vPC += 5;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_typeof) {
+ DEFINE_OPCODE(op_typeof) {
/* typeof dst(r) src(r)
Determines the type string for src according to ECMAScript
@@ -2196,12 +2136,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- callFrame[dst] = jsTypeStringForValue(callFrame, callFrame[src].jsValue(callFrame));
+ callFrame[dst] = JSValuePtr(jsTypeStringForValue(callFrame, callFrame[src].jsValue(callFrame)));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_is_undefined) {
+ DEFINE_OPCODE(op_is_undefined) {
/* is_undefined dst(r) src(r)
Determines whether the type string for src according to
@@ -2210,13 +2150,13 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- JSValue* v = callFrame[src].jsValue(callFrame);
- callFrame[dst] = jsBoolean(JSImmediate::isImmediate(v) ? v->isUndefined() : v->asCell()->structureID()->typeInfo().masqueradesAsUndefined());
+ JSValuePtr v = callFrame[src].jsValue(callFrame);
+ callFrame[dst] = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined());
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_is_boolean) {
+ DEFINE_OPCODE(op_is_boolean) {
/* is_boolean dst(r) src(r)
Determines whether the type string for src according to
@@ -2225,12 +2165,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame)->isBoolean());
+ callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame).isBoolean());
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_is_number) {
+ DEFINE_OPCODE(op_is_number) {
/* is_number dst(r) src(r)
Determines whether the type string for src according to
@@ -2239,12 +2179,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame)->isNumber());
+ callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame).isNumber());
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_is_string) {
+ DEFINE_OPCODE(op_is_string) {
/* is_string dst(r) src(r)
Determines whether the type string for src according to
@@ -2253,12 +2193,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame)->isString());
+ callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame).isString());
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_is_object) {
+ DEFINE_OPCODE(op_is_object) {
/* is_object dst(r) src(r)
Determines whether the type string for src according to
@@ -2270,9 +2210,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
callFrame[dst] = jsBoolean(jsIsObjectType(callFrame[src].jsValue(callFrame)));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_is_function) {
+ DEFINE_OPCODE(op_is_function) {
/* is_function dst(r) src(r)
Determines whether the type string for src according to
@@ -2284,9 +2224,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
callFrame[dst] = jsBoolean(jsIsFunctionType(callFrame[src].jsValue(callFrame)));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_in) {
+ DEFINE_OPCODE(op_in) {
/* in dst(r) property(r) base(r)
Tests whether register base has a property named register
@@ -2299,27 +2239,27 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int property = (++vPC)->u.operand;
int base = (++vPC)->u.operand;
- JSValue* baseVal = callFrame[base].jsValue(callFrame);
+ JSValuePtr baseVal = callFrame[base].jsValue(callFrame);
if (isNotObject(callFrame, false, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
goto vm_throw;
JSObject* baseObj = asObject(baseVal);
- JSValue* propName = callFrame[property].jsValue(callFrame);
+ JSValuePtr propName = callFrame[property].jsValue(callFrame);
uint32_t i;
- if (propName->getUInt32(i))
+ if (propName.getUInt32(i))
callFrame[dst] = jsBoolean(baseObj->hasProperty(callFrame, i));
else {
- Identifier property(callFrame, propName->toString(callFrame));
- VM_CHECK_EXCEPTION();
+ Identifier property(callFrame, propName.toString(callFrame));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = jsBoolean(baseObj->hasProperty(callFrame, property));
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_resolve) {
+ DEFINE_OPCODE(op_resolve) {
/* resolve dst(r) property(id)
Looks up the property named by identifier property in the
@@ -2330,9 +2270,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
goto vm_throw;
vPC += 3;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_resolve_skip) {
+ DEFINE_OPCODE(op_resolve_skip) {
/* resolve_skip dst(r) property(id) skip(n)
Looks up the property named by identifier property in the
@@ -2344,24 +2284,24 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
vPC += 4;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_resolve_global) {
- /* resolve_skip dst(r) globalObject(c) property(id) structureID(sID) offset(n)
+ DEFINE_OPCODE(op_resolve_global) {
+ /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n)
Performs a dynamic property lookup for the given property, on the provided
- global object. If structureID matches the StructureID of the global then perform
+ global object. If structure matches the Structure of the global then perform
a fast lookup using the case offset, otherwise fall back to a full resolve and
- cache the new structureID and offset
+ cache the new structure and offset
*/
if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue)))
goto vm_throw;
vPC += 6;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_global_var) {
+ DEFINE_OPCODE(op_get_global_var) {
/* get_global_var dst(r) globalObject(c) index(n)
Gets the global var at global slot index and places it in register dst.
@@ -2373,9 +2313,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
callFrame[dst] = scope->registerAt(index);
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_put_global_var) {
+ DEFINE_OPCODE(op_put_global_var) {
/* put_global_var globalObject(c) index(n) value(r)
Puts value into global slot index.
@@ -2385,11 +2325,11 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int index = (++vPC)->u.operand;
int value = (++vPC)->u.operand;
- scope->registerAt(index) = callFrame[value].jsValue(callFrame);
+ scope->registerAt(index) = JSValuePtr(callFrame[value].jsValue(callFrame));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_scoped_var) {
+ DEFINE_OPCODE(op_get_scoped_var) {
/* get_scoped_var dst(r) index(n) skip(n)
Loads the contents of the index-th local from the scope skip nodes from
@@ -2397,7 +2337,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int index = (++vPC)->u.operand;
- int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain;
+ int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain();
ScopeChainNode* scopeChain = callFrame->scopeChain();
ScopeChainIterator iter = scopeChain->begin();
@@ -2412,14 +2352,14 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
callFrame[dst] = scope->registerAt(index);
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_put_scoped_var) {
+ DEFINE_OPCODE(op_put_scoped_var) {
/* put_scoped_var index(n) skip(n) value(r)
*/
int index = (++vPC)->u.operand;
- int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain;
+ int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain();
int value = (++vPC)->u.operand;
ScopeChainNode* scopeChain = callFrame->scopeChain();
@@ -2433,11 +2373,11 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
ASSERT((*iter)->isVariableObject());
JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
- scope->registerAt(index) = callFrame[value].jsValue(callFrame);
+ scope->registerAt(index) = JSValuePtr(callFrame[value].jsValue(callFrame));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_resolve_base) {
+ DEFINE_OPCODE(op_resolve_base) {
/* resolve_base dst(r) property(id)
Searches the scope chain for an object containing
@@ -2448,9 +2388,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
resolveBase(callFrame, vPC);
vPC += 3;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_resolve_with_base) {
+ DEFINE_OPCODE(op_resolve_with_base) {
/* resolve_with_base baseDst(r) propDst(r) property(id)
Searches the scope chain for an object containing
@@ -2466,9 +2406,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
goto vm_throw;
vPC += 4;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_resolve_func) {
+ DEFINE_OPCODE(op_resolve_func) {
/* resolve_func baseDst(r) funcDst(r) property(id)
Searches the scope chain for an object containing
@@ -2487,10 +2427,10 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
goto vm_throw;
vPC += 4;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_by_id) {
- /* get_by_id dst(r) base(r) property(id) structureID(sID) nop(n) nop(n) nop(n)
+ DEFINE_OPCODE(op_get_by_id) {
+ /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n)
Generic property access: Gets the property named by identifier
property from the value base, and puts the result in register dst.
@@ -2500,127 +2440,144 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int property = vPC[3].u.operand;
CodeBlock* codeBlock = callFrame->codeBlock();
- Identifier& ident = codeBlock->identifiers[property];
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
+ Identifier& ident = codeBlock->identifier(property);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
PropertySlot slot(baseValue);
- JSValue* result = baseValue->get(callFrame, ident, slot);
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = baseValue.get(callFrame, ident, slot);
+ CHECK_FOR_EXCEPTION();
tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot);
callFrame[dst] = result;
vPC += 8;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_by_id_self) {
- /* op_get_by_id_self dst(r) base(r) property(id) structureID(sID) offset(n) nop(n) nop(n)
+ DEFINE_OPCODE(op_get_by_id_self) {
+ /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
Cached property access: Attempts to get a cached property from the
value base. If the cache misses, op_get_by_id_self reverts to
op_get_by_id.
*/
int base = vPC[2].u.operand;
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
- if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
+ if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = asCell(baseValue);
- StructureID* structureID = vPC[4].u.structureID;
+ Structure* structure = vPC[4].u.structure;
- if (LIKELY(baseCell->structureID() == structureID)) {
+ if (LIKELY(baseCell->structure() == structure)) {
ASSERT(baseCell->isObject());
JSObject* baseObject = asObject(baseCell);
int dst = vPC[1].u.operand;
int offset = vPC[5].u.operand;
- ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifiers[vPC[3].u.operand]) == baseObject->getDirectOffset(offset));
- callFrame[dst] = baseObject->getDirectOffset(offset);
+ ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
+ callFrame[dst] = JSValuePtr(baseObject->getDirectOffset(offset));
vPC += 8;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
}
uncacheGetByID(callFrame->codeBlock(), vPC);
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_by_id_proto) {
- /* op_get_by_id_proto dst(r) base(r) property(id) structureID(sID) protoStructureID(sID) offset(n) nop(n)
+ DEFINE_OPCODE(op_get_by_id_proto) {
+ /* op_get_by_id_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
Cached property access: Attempts to get a cached property from the
value base's prototype. If the cache misses, op_get_by_id_proto
reverts to op_get_by_id.
*/
int base = vPC[2].u.operand;
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
- if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
+ if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = asCell(baseValue);
- StructureID* structureID = vPC[4].u.structureID;
+ Structure* structure = vPC[4].u.structure;
- if (LIKELY(baseCell->structureID() == structureID)) {
- ASSERT(structureID->prototypeForLookup(callFrame)->isObject());
- JSObject* protoObject = asObject(structureID->prototypeForLookup(callFrame));
- StructureID* protoStructureID = vPC[5].u.structureID;
+ 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->structureID() == protoStructureID)) {
+ if (LIKELY(protoObject->structure() == prototypeStructure)) {
int dst = vPC[1].u.operand;
int offset = vPC[6].u.operand;
- ASSERT(protoObject->get(callFrame, callFrame->codeBlock()->identifiers[vPC[3].u.operand]) == protoObject->getDirectOffset(offset));
- callFrame[dst] = protoObject->getDirectOffset(offset);
+ ASSERT(protoObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
+ callFrame[dst] = JSValuePtr(protoObject->getDirectOffset(offset));
vPC += 8;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
}
}
uncacheGetByID(callFrame->codeBlock(), vPC);
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_by_id_chain) {
- /* op_get_by_id_chain dst(r) base(r) property(id) structureID(sID) structureIDChain(sIDc) count(n) offset(n)
+ DEFINE_OPCODE(op_get_by_id_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 += 8;
+ NEXT_INSTRUCTION();
+ }
+ DEFINE_OPCODE(op_get_by_id_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 += 8;
+ 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)
Cached property access: Attempts to get a cached property from the
value base's prototype chain. If the cache misses, op_get_by_id_chain
reverts to op_get_by_id.
*/
int base = vPC[2].u.operand;
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
- if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
+ if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = asCell(baseValue);
- StructureID* structureID = vPC[4].u.structureID;
+ Structure* structure = vPC[4].u.structure;
- if (LIKELY(baseCell->structureID() == structureID)) {
- RefPtr<StructureID>* it = vPC[5].u.structureIDChain->head();
+ if (LIKELY(baseCell->structure() == structure)) {
+ RefPtr<Structure>* it = vPC[5].u.structureChain->head();
size_t count = vPC[6].u.operand;
- RefPtr<StructureID>* end = it + count;
+ RefPtr<Structure>* end = it + count;
- JSObject* baseObject = asObject(baseCell);
- while (1) {
- baseObject = asObject(baseObject->structureID()->prototypeForLookup(callFrame));
- if (UNLIKELY(baseObject->structureID() != (*it).get()))
+ while (true) {
+ JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
+
+ if (UNLIKELY(baseObject->structure() != (*it).get()))
break;
if (++it == end) {
int dst = vPC[1].u.operand;
int offset = vPC[7].u.operand;
- ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifiers[vPC[3].u.operand]) == baseObject->getDirectOffset(offset));
- callFrame[dst] = baseObject->getDirectOffset(offset);
+ ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
+ callFrame[dst] = JSValuePtr(baseObject->getDirectOffset(offset));
vPC += 8;
- NEXT_OPCODE;
+ 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_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_by_id_generic) {
+ 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)
Generic property access: Gets the property named by identifier
@@ -2630,17 +2587,17 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int base = vPC[2].u.operand;
int property = vPC[3].u.operand;
- Identifier& ident = callFrame->codeBlock()->identifiers[property];
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
+ Identifier& ident = callFrame->codeBlock()->identifier(property);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
PropertySlot slot(baseValue);
- JSValue* result = baseValue->get(callFrame, ident, slot);
- VM_CHECK_EXCEPTION();
+ JSValuePtr result = baseValue.get(callFrame, ident, slot);
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
vPC += 8;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_array_length) {
+ DEFINE_OPCODE(op_get_array_length) {
/* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
Cached property access: Gets the length of the array in register base,
@@ -2649,18 +2606,18 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int base = vPC[2].u.operand;
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
if (LIKELY(isJSArray(baseValue))) {
int dst = vPC[1].u.operand;
- callFrame[dst] = jsNumber(callFrame, asArray(baseValue)->length());
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, asArray(baseValue)->length()));
vPC += 8;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
uncacheGetByID(callFrame->codeBlock(), vPC);
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_string_length) {
+ DEFINE_OPCODE(op_get_string_length) {
/* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
Cached property access: Gets the length of the string in register base,
@@ -2669,18 +2626,18 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int base = vPC[2].u.operand;
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
if (LIKELY(isJSString(baseValue))) {
int dst = vPC[1].u.operand;
- callFrame[dst] = jsNumber(callFrame, asString(baseValue)->value().size());
+ callFrame[dst] = JSValuePtr(jsNumber(callFrame, asString(baseValue)->value().size()));
vPC += 8;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
uncacheGetByID(callFrame->codeBlock(), vPC);
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_put_by_id) {
+ DEFINE_OPCODE(op_put_by_id) {
/* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n)
Generic property access: Sets the property named by identifier
@@ -2695,19 +2652,19 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int value = vPC[3].u.operand;
CodeBlock* codeBlock = callFrame->codeBlock();
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
- Identifier& ident = codeBlock->identifiers[property];
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+ Identifier& ident = codeBlock->identifier(property);
PutPropertySlot slot;
- baseValue->put(callFrame, ident, callFrame[value].jsValue(callFrame), slot);
- VM_CHECK_EXCEPTION();
+ baseValue.put(callFrame, ident, callFrame[value].jsValue(callFrame), slot);
+ CHECK_FOR_EXCEPTION();
tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);
vPC += 8;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_put_by_id_transition) {
- /* op_put_by_id_transition base(r) property(id) value(r) oldStructureID(sID) newStructureID(sID) structureIDChain(sIDc) offset(n)
+ DEFINE_OPCODE(op_put_by_id_transition) {
+ /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n)
Cached property access: Attempts to set a new property with a cached transition
property named by identifier property, belonging to register base,
@@ -2718,46 +2675,46 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
the register file.
*/
int base = vPC[1].u.operand;
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
- if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
+ if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = asCell(baseValue);
- StructureID* oldStructureID = vPC[4].u.structureID;
- StructureID* newStructureID = vPC[5].u.structureID;
+ Structure* oldStructure = vPC[4].u.structure;
+ Structure* newStructure = vPC[5].u.structure;
- if (LIKELY(baseCell->structureID() == oldStructureID)) {
+ if (LIKELY(baseCell->structure() == oldStructure)) {
ASSERT(baseCell->isObject());
JSObject* baseObject = asObject(baseCell);
- RefPtr<StructureID>* it = vPC[6].u.structureIDChain->head();
+ RefPtr<Structure>* it = vPC[6].u.structureChain->head();
- JSValue* proto = baseObject->structureID()->prototypeForLookup(callFrame);
- while (!proto->isNull()) {
- if (UNLIKELY(asObject(proto)->structureID() != (*it).get())) {
+ JSValuePtr proto = baseObject->structure()->prototypeForLookup(callFrame);
+ while (!proto.isNull()) {
+ if (UNLIKELY(asObject(proto)->structure() != (*it).get())) {
uncachePutByID(callFrame->codeBlock(), vPC);
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
++it;
- proto = asObject(proto)->structureID()->prototypeForLookup(callFrame);
+ proto = asObject(proto)->structure()->prototypeForLookup(callFrame);
}
- baseObject->transitionTo(newStructureID);
+ baseObject->transitionTo(newStructure);
int value = vPC[3].u.operand;
unsigned offset = vPC[7].u.operand;
- ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifiers[vPC[2].u.operand])) == offset);
+ ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset);
baseObject->putDirectOffset(offset, callFrame[value].jsValue(callFrame));
vPC += 8;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
}
uncachePutByID(callFrame->codeBlock(), vPC);
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_put_by_id_replace) {
- /* op_put_by_id_replace base(r) property(id) value(r) structureID(sID) offset(n) nop(n) nop(n)
+ DEFINE_OPCODE(op_put_by_id_replace) {
+ /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n)
Cached property access: Attempts to set a pre-existing, cached
property named by identifier property, belonging to register base,
@@ -2768,30 +2725,30 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
the register file.
*/
int base = vPC[1].u.operand;
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
- if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
+ if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = asCell(baseValue);
- StructureID* structureID = vPC[4].u.structureID;
+ Structure* structure = vPC[4].u.structure;
- if (LIKELY(baseCell->structureID() == structureID)) {
+ if (LIKELY(baseCell->structure() == structure)) {
ASSERT(baseCell->isObject());
JSObject* baseObject = asObject(baseCell);
int value = vPC[3].u.operand;
unsigned offset = vPC[5].u.operand;
- ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifiers[vPC[2].u.operand])) == offset);
+ ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset);
baseObject->putDirectOffset(offset, callFrame[value].jsValue(callFrame));
vPC += 8;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
}
uncachePutByID(callFrame->codeBlock(), vPC);
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_put_by_id_generic) {
+ DEFINE_OPCODE(op_put_by_id_generic) {
/* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n)
Generic property access: Sets the property named by identifier
@@ -2804,16 +2761,16 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int property = vPC[2].u.operand;
int value = vPC[3].u.operand;
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
- Identifier& ident = callFrame->codeBlock()->identifiers[property];
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+ Identifier& ident = callFrame->codeBlock()->identifier(property);
PutPropertySlot slot;
- baseValue->put(callFrame, ident, callFrame[value].jsValue(callFrame), slot);
- VM_CHECK_EXCEPTION();
+ baseValue.put(callFrame, ident, callFrame[value].jsValue(callFrame), slot);
+ CHECK_FOR_EXCEPTION();
vPC += 8;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_del_by_id) {
+ DEFINE_OPCODE(op_del_by_id) {
/* del_by_id dst(r) base(r) property(id)
Converts register base to Object, deletes the property
@@ -2825,15 +2782,15 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int base = (++vPC)->u.operand;
int property = (++vPC)->u.operand;
- JSObject* baseObj = callFrame[base].jsValue(callFrame)->toObject(callFrame);
- Identifier& ident = callFrame->codeBlock()->identifiers[property];
- JSValue* result = jsBoolean(baseObj->deleteProperty(callFrame, ident));
- VM_CHECK_EXCEPTION();
+ JSObject* baseObj = callFrame[base].jsValue(callFrame).toObject(callFrame);
+ Identifier& ident = callFrame->codeBlock()->identifier(property);
+ JSValuePtr result = jsBoolean(baseObj->deleteProperty(callFrame, ident));
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_by_val) {
+ DEFINE_OPCODE(op_get_by_val) {
/* get_by_val dst(r) base(r) property(r)
Converts register base to Object, gets the property named
@@ -2845,14 +2802,13 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int base = (++vPC)->u.operand;
int property = (++vPC)->u.operand;
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
- JSValue* subscript = callFrame[property].jsValue(callFrame);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+ JSValuePtr subscript = callFrame[property].jsValue(callFrame);
- JSValue* result;
- unsigned i;
+ JSValuePtr result;
- bool isUInt32 = JSImmediate::getUInt32(subscript, i);
- if (LIKELY(isUInt32)) {
+ if (LIKELY(subscript.isUInt32Fast())) {
+ uint32_t i = subscript.getUInt32Fast();
if (isJSArray(baseValue)) {
JSArray* jsArray = asArray(baseValue);
if (jsArray->canGetIndex(i))
@@ -2861,19 +2817,21 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
result = jsArray->JSArray::get(callFrame, i);
} else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
result = asString(baseValue)->getIndex(&callFrame->globalData(), i);
+ else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
+ result = asByteArray(baseValue)->getIndex(callFrame, i);
else
- result = baseValue->get(callFrame, i);
+ result = baseValue.get(callFrame, i);
} else {
- Identifier property(callFrame, subscript->toString(callFrame));
- result = baseValue->get(callFrame, property);
+ Identifier property(callFrame, subscript.toString(callFrame));
+ result = baseValue.get(callFrame, property);
}
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_put_by_val) {
+ DEFINE_OPCODE(op_put_by_val) {
/* put_by_val base(r) property(r) value(r)
Sets register value on register base as the property named
@@ -2888,34 +2846,42 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int property = (++vPC)->u.operand;
int value = (++vPC)->u.operand;
- JSValue* baseValue = callFrame[base].jsValue(callFrame);
- JSValue* subscript = callFrame[property].jsValue(callFrame);
+ JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+ JSValuePtr subscript = callFrame[property].jsValue(callFrame);
- unsigned i;
-
- bool isUInt32 = JSImmediate::getUInt32(subscript, i);
- if (LIKELY(isUInt32)) {
+ if (LIKELY(subscript.isUInt32Fast())) {
+ uint32_t i = subscript.getUInt32Fast();
if (isJSArray(baseValue)) {
JSArray* jsArray = asArray(baseValue);
if (jsArray->canSetIndex(i))
jsArray->setIndex(i, callFrame[value].jsValue(callFrame));
else
jsArray->JSArray::put(callFrame, i, callFrame[value].jsValue(callFrame));
+ } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ JSByteArray* jsByteArray = asByteArray(baseValue);
+ double dValue = 0;
+ JSValuePtr jsValue = callFrame[value].jsValue(callFrame);
+ if (jsValue.isInt32Fast())
+ jsByteArray->setIndex(i, jsValue.getInt32Fast());
+ else if (jsValue.getNumber(dValue))
+ jsByteArray->setIndex(i, dValue);
+ else
+ baseValue.put(callFrame, i, jsValue);
} else
- baseValue->put(callFrame, i, callFrame[value].jsValue(callFrame));
+ baseValue.put(callFrame, i, callFrame[value].jsValue(callFrame));
} else {
- Identifier property(callFrame, subscript->toString(callFrame));
+ Identifier property(callFrame, subscript.toString(callFrame));
if (!globalData->exception) { // Don't put to an object if toString threw an exception.
PutPropertySlot slot;
- baseValue->put(callFrame, property, callFrame[value].jsValue(callFrame), slot);
+ baseValue.put(callFrame, property, callFrame[value].jsValue(callFrame), slot);
}
}
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_del_by_val) {
+ DEFINE_OPCODE(op_del_by_val) {
/* del_by_val dst(r) base(r) property(r)
Converts register base to Object, deletes the property
@@ -2927,26 +2893,26 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int base = (++vPC)->u.operand;
int property = (++vPC)->u.operand;
- JSObject* baseObj = callFrame[base].jsValue(callFrame)->toObject(callFrame); // may throw
+ JSObject* baseObj = callFrame[base].jsValue(callFrame).toObject(callFrame); // may throw
- JSValue* subscript = callFrame[property].jsValue(callFrame);
- JSValue* result;
+ JSValuePtr subscript = callFrame[property].jsValue(callFrame);
+ JSValuePtr result;
uint32_t i;
- if (subscript->getUInt32(i))
+ if (subscript.getUInt32(i))
result = jsBoolean(baseObj->deleteProperty(callFrame, i));
else {
- VM_CHECK_EXCEPTION();
- Identifier property(callFrame, subscript->toString(callFrame));
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
+ Identifier property(callFrame, subscript.toString(callFrame));
+ CHECK_FOR_EXCEPTION();
result = jsBoolean(baseObj->deleteProperty(callFrame, property));
}
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
callFrame[dst] = result;
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_put_by_index) {
+ DEFINE_OPCODE(op_put_by_index) {
/* put_by_index base(r) property(n) value(r)
Sets register value on register base as the property named
@@ -2962,12 +2928,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
unsigned property = (++vPC)->u.operand;
int value = (++vPC)->u.operand;
- callFrame[base].jsValue(callFrame)->put(callFrame, property, callFrame[value].jsValue(callFrame));
+ callFrame[base].jsValue(callFrame).put(callFrame, property, callFrame[value].jsValue(callFrame));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_loop) {
+ DEFINE_OPCODE(op_loop) {
/* loop target(offset)
Jumps unconditionally to offset target from the current
@@ -2982,9 +2948,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int target = (++vPC)->u.operand;
CHECK_FOR_TIMEOUT();
vPC += target;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_jmp) {
+ DEFINE_OPCODE(op_jmp) {
/* jmp target(offset)
Jumps unconditionally to offset target from the current
@@ -2996,9 +2962,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int target = (++vPC)->u.operand;
vPC += target;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_loop_if_true) {
+ DEFINE_OPCODE(op_loop_if_true) {
/* loop_if_true cond(r) target(offset)
Jumps to offset target from the current instruction, if and
@@ -3009,16 +2975,16 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int cond = (++vPC)->u.operand;
int target = (++vPC)->u.operand;
- if (callFrame[cond].jsValue(callFrame)->toBoolean(callFrame)) {
+ if (callFrame[cond].jsValue(callFrame).toBoolean(callFrame)) {
vPC += target;
CHECK_FOR_TIMEOUT();
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_jtrue) {
+ DEFINE_OPCODE(op_jtrue) {
/* jtrue cond(r) target(offset)
Jumps to offset target from the current instruction, if and
@@ -3026,15 +2992,15 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int cond = (++vPC)->u.operand;
int target = (++vPC)->u.operand;
- if (callFrame[cond].jsValue(callFrame)->toBoolean(callFrame)) {
+ if (callFrame[cond].jsValue(callFrame).toBoolean(callFrame)) {
vPC += target;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_jfalse) {
+ DEFINE_OPCODE(op_jfalse) {
/* jfalse cond(r) target(offset)
Jumps to offset target from the current instruction, if and
@@ -3042,15 +3008,15 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int cond = (++vPC)->u.operand;
int target = (++vPC)->u.operand;
- if (!callFrame[cond].jsValue(callFrame)->toBoolean(callFrame)) {
+ if (!callFrame[cond].jsValue(callFrame).toBoolean(callFrame)) {
vPC += target;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_jeq_null) {
+ DEFINE_OPCODE(op_jeq_null) {
/* jeq_null src(r) target(offset)
Jumps to offset target from the current instruction, if and
@@ -3058,17 +3024,17 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int src = (++vPC)->u.operand;
int target = (++vPC)->u.operand;
- JSValue* srcValue = callFrame[src].jsValue(callFrame);
+ JSValuePtr srcValue = callFrame[src].jsValue(callFrame);
- if (srcValue->isUndefinedOrNull() || (!JSImmediate::isImmediate(srcValue) && srcValue->asCell()->structureID()->typeInfo().masqueradesAsUndefined())) {
+ if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
vPC += target;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_jneq_null) {
+ DEFINE_OPCODE(op_jneq_null) {
/* jneq_null src(r) target(offset)
Jumps to offset target from the current instruction, if and
@@ -3076,17 +3042,17 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int src = (++vPC)->u.operand;
int target = (++vPC)->u.operand;
- JSValue* srcValue = callFrame[src].jsValue(callFrame);
+ JSValuePtr srcValue = callFrame[src].jsValue(callFrame);
- if (!srcValue->isUndefinedOrNull() || (!JSImmediate::isImmediate(srcValue) && !srcValue->asCell()->structureID()->typeInfo().masqueradesAsUndefined())) {
+ if (!srcValue.isUndefinedOrNull() || (srcValue.isCell() && !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
vPC += target;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_loop_if_less) {
+ DEFINE_OPCODE(op_loop_if_less) {
/* loop_if_less src1(r) src2(r) target(offset)
Checks whether register src1 is less than register src2, as
@@ -3097,23 +3063,23 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
Additionally this loop instruction may terminate JS execution is
the JS timeout is reached.
*/
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
int target = (++vPC)->u.operand;
bool result = jsLess(callFrame, src1, src2);
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
if (result) {
vPC += target;
CHECK_FOR_TIMEOUT();
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_loop_if_lesseq) {
+ DEFINE_OPCODE(op_loop_if_lesseq) {
/* loop_if_lesseq src1(r) src2(r) target(offset)
Checks whether register src1 is less than or equal to register
@@ -3124,23 +3090,23 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
Additionally this loop instruction may terminate JS execution is
the JS timeout is reached.
*/
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
int target = (++vPC)->u.operand;
bool result = jsLessEq(callFrame, src1, src2);
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
if (result) {
vPC += target;
CHECK_FOR_TIMEOUT();
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_jnless) {
+ DEFINE_OPCODE(op_jnless) {
/* jnless src1(r) src2(r) target(offset)
Checks whether register src1 is less than register src2, as
@@ -3148,22 +3114,22 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
target from the current instruction, if and only if the
result of the comparison is false.
*/
- JSValue* src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- JSValue* src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
int target = (++vPC)->u.operand;
bool result = jsLess(callFrame, src1, src2);
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
if (!result) {
vPC += target;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_switch_imm) {
+ DEFINE_OPCODE(op_switch_imm) {
/* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)
Performs a range checked switch on the scrutinee value, using
@@ -3174,16 +3140,19 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int tableIndex = (++vPC)->u.operand;
int defaultOffset = (++vPC)->u.operand;
- JSValue* scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- if (!JSImmediate::isNumber(scrutinee))
- vPC += defaultOffset;
+ JSValuePtr scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ if (scrutinee.isInt32Fast())
+ vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.getInt32Fast(), defaultOffset);
else {
- int32_t value = JSImmediate::getTruncatedInt32(scrutinee);
- vPC += callFrame->codeBlock()->immediateSwitchJumpTables[tableIndex].offsetForValue(value, defaultOffset);
+ int32_t value;
+ if (scrutinee.numberToInt32(value))
+ vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(value, defaultOffset);
+ else
+ vPC += defaultOffset;
}
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_switch_char) {
+ DEFINE_OPCODE(op_switch_char) {
/* switch_char tableIndex(n) defaultOffset(offset) scrutinee(r)
Performs a range checked switch on the scrutinee value, using
@@ -3194,19 +3163,19 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int tableIndex = (++vPC)->u.operand;
int defaultOffset = (++vPC)->u.operand;
- JSValue* scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- if (!scrutinee->isString())
+ JSValuePtr scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ if (!scrutinee.isString())
vPC += defaultOffset;
else {
UString::Rep* value = asString(scrutinee)->value().rep();
if (value->size() != 1)
vPC += defaultOffset;
else
- vPC += callFrame->codeBlock()->characterSwitchJumpTables[tableIndex].offsetForValue(value->data()[0], defaultOffset);
+ vPC += callFrame->codeBlock()->characterSwitchJumpTable(tableIndex).offsetForValue(value->data()[0], defaultOffset);
}
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_switch_string) {
+ DEFINE_OPCODE(op_switch_string) {
/* switch_string tableIndex(n) defaultOffset(offset) scrutinee(r)
Performs a sparse hashmap based switch on the value in the scrutinee
@@ -3217,14 +3186,14 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int tableIndex = (++vPC)->u.operand;
int defaultOffset = (++vPC)->u.operand;
- JSValue* scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
- if (!scrutinee->isString())
+ JSValuePtr scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+ if (!scrutinee.isString())
vPC += defaultOffset;
else
- vPC += callFrame->codeBlock()->stringSwitchJumpTables[tableIndex].offsetForValue(asString(scrutinee)->value().rep(), defaultOffset);
- NEXT_OPCODE;
+ vPC += callFrame->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value().rep(), defaultOffset);
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_new_func) {
+ DEFINE_OPCODE(op_new_func) {
/* new_func dst(r) func(f)
Constructs a new Function instance from function func and
@@ -3235,12 +3204,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int dst = (++vPC)->u.operand;
int func = (++vPC)->u.operand;
- callFrame[dst] = callFrame->codeBlock()->functions[func]->makeFunction(callFrame, callFrame->scopeChain());
+ callFrame[dst] = callFrame->codeBlock()->function(func)->makeFunction(callFrame, callFrame->scopeChain());
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_new_func_exp) {
+ DEFINE_OPCODE(op_new_func_exp) {
/* new_func_exp dst(r) func(f)
Constructs a new Function instance from function func and
@@ -3251,13 +3220,13 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int dst = (++vPC)->u.operand;
int func = (++vPC)->u.operand;
- callFrame[dst] = callFrame->codeBlock()->functionExpressions[func]->makeFunction(callFrame, callFrame->scopeChain());
+ callFrame[dst] = callFrame->codeBlock()->functionExpression(func)->makeFunction(callFrame, callFrame->scopeChain());
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_call_eval) {
- /* call_eval dst(r) func(r) thisVal(r) firstArg(r) argCount(n)
+ DEFINE_OPCODE(op_call_eval) {
+ /* call_eval dst(r) func(r) argCount(n) registerOffset(n)
Call a function named "eval" with no explicit "this" value
(which may therefore be the eval operator). If register
@@ -3270,95 +3239,56 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int dst = vPC[1].u.operand;
int func = vPC[2].u.operand;
- int thisVal = vPC[3].u.operand;
- int firstArg = vPC[4].u.operand;
- int argCount = vPC[5].u.operand;
+ int argCount = vPC[3].u.operand;
+ int registerOffset = vPC[4].u.operand;
- JSValue* funcVal = callFrame[func].jsValue(callFrame);
- JSValue* baseVal = callFrame[thisVal].jsValue(callFrame);
+ JSValuePtr funcVal = callFrame[func].jsValue(callFrame);
- ScopeChainNode* scopeChain = callFrame->scopeChain();
- if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
- JSObject* thisObject = asObject(callFrame[callFrame->codeBlock()->thisRegister].jsValue(callFrame));
- JSValue* result = callEval(callFrame, thisObject, scopeChain, registerFile, firstArg, argCount, exceptionValue);
+ Register* newCallFrame = callFrame->registers() + registerOffset;
+ Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
+ JSValuePtr thisValue = argv[0].jsValue(callFrame);
+ JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
+
+ if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
+ JSValuePtr result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
if (exceptionValue)
goto vm_throw;
-
callFrame[dst] = result;
- vPC += 7;
- NEXT_OPCODE;
+ vPC += 5;
+ NEXT_INSTRUCTION();
}
- // We didn't find the blessed version of eval, so reset vPC and process
- // this instruction as a normal function call, supplying the proper 'this'
- // value.
- callFrame[thisVal] = baseVal->toThisObject(callFrame);
-
-#if HAVE(COMPUTED_GOTO)
- // Hack around gcc performance quirk by performing an indirect goto
- // in order to set the vPC -- attempting to do so directly results in a
- // significant regression.
- goto *op_call_indirect; // indirect goto -> op_call
-#endif
+ // We didn't find the blessed version of eval, so process this
+ // instruction as a normal function call.
// fall through to op_call
}
- BEGIN_OPCODE(op_call) {
- /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n) registerOffset(n)
+ DEFINE_OPCODE(op_call) {
+ /* call dst(r) func(r) argCount(n) registerOffset(n)
- Perform a function call. Specifically, call register func
- with a "this" value of register thisVal, and put the result
- in register dst.
-
- The arguments start at register firstArg and go up to
- argCount, but the "this" value is considered an implicit
- first argument, so the argCount should be one greater than
- the number of explicit arguments passed, and the register
- after firstArg should contain the actual first
- argument. This opcode will copy from the thisVal register
- to the firstArg register, unless the register index of
- thisVal is the special missing this object marker, which is
- 2^31-1; in that case, the global object will be used as the
- "this" value.
-
- If func is a native code function, then this opcode calls
- it and returns the value immediately.
-
- But if it is a JS function, then the current scope chain
- and code block is set to the function's, and we slide the
- register window so that the arguments would form the first
- few local registers of the called function's register
- window. In addition, a call frame header is written
- immediately before the arguments; see the call frame
- documentation for an explanation of how many registers a
- call frame takes and what they contain. That many registers
- before the firstArg register will be overwritten by the
- call. In addition, any registers higher than firstArg +
- argCount may be overwritten. Once this setup is complete,
- execution continues from the called function's first
- argument, and does not return until a "ret" opcode is
- encountered.
+ Perform a function call.
+
+ registerOffset is the distance the callFrame pointer should move
+ before the VM initializes the new call frame's header.
+
+ dst is where op_ret should store its result.
*/
int dst = vPC[1].u.operand;
int func = vPC[2].u.operand;
- int thisVal = vPC[3].u.operand;
- int firstArg = vPC[4].u.operand;
- int argCount = vPC[5].u.operand;
- int registerOffset = vPC[6].u.operand;
+ int argCount = vPC[3].u.operand;
+ int registerOffset = vPC[4].u.operand;
- JSValue* v = callFrame[func].jsValue(callFrame);
+ JSValuePtr v = callFrame[func].jsValue(callFrame);
CallData callData;
- CallType callType = v->getCallData(callData);
+ CallType callType = v.getCallData(callData);
if (callType == CallTypeJS) {
ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
FunctionBodyNode* functionBodyNode = callData.js.functionBody;
- CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
+ CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
- callFrame[firstArg] = thisVal == missingThisObjectMarker() ? callFrame->globalThisValue() : callFrame[thisVal].jsValue(callFrame);
-
CallFrame* previousCallFrame = callFrame;
callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
@@ -3368,43 +3298,48 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
goto vm_throw;
}
- callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
- vPC = newCodeBlock->instructions.begin();
+ callFrame->init(newCodeBlock, vPC + 5, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
+ vPC = newCodeBlock->instructions().begin();
#if ENABLE(OPCODE_STATS)
OpcodeStats::resetLastInstruction();
#endif
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
if (callType == CallTypeHost) {
- JSValue* thisValue = thisVal == missingThisObjectMarker() ? callFrame->globalThisValue() : callFrame[thisVal].jsValue(callFrame);
- ArgList args(callFrame->registers() + firstArg + 1, argCount - 1);
-
ScopeChainNode* scopeChain = callFrame->scopeChain();
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
- newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
+ newCallFrame->init(0, vPC + 5, scopeChain, callFrame, dst, argCount, 0);
- JSValue* returnValue;
+ Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
+ ArgList args(thisRegister + 1, argCount - 1);
+
+ // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
+ JSValuePtr thisValue = thisRegister->jsValue(callFrame);
+ if (thisValue == jsNull())
+ thisValue = callFrame->globalThisValue();
+
+ JSValuePtr returnValue;
{
SamplingTool::HostCallRecord callRecord(m_sampler);
returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
}
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
- callFrame[dst] = returnValue;
+ callFrame[dst] = JSValuePtr(returnValue);
- vPC += 7;
- NEXT_OPCODE;
+ vPC += 5;
+ NEXT_INSTRUCTION();
}
ASSERT(callType == CallTypeNone);
- exceptionValue = createNotAFunctionError(callFrame, v, vPC, callFrame->codeBlock());
+ exceptionValue = createNotAFunctionError(callFrame, v, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock());
goto vm_throw;
}
- BEGIN_OPCODE(op_tear_off_activation) {
+ DEFINE_OPCODE(op_tear_off_activation) {
/* tear_off_activation activation(r)
Copy all locals and parameters to new memory allocated on
@@ -3418,14 +3353,14 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int src = (++vPC)->u.operand;
- ASSERT(callFrame->codeBlock()->needsFullScopeChain);
+ ASSERT(callFrame->codeBlock()->needsFullScopeChain());
asActivation(callFrame[src].getJSValue())->copyRegisters(callFrame->optionalCalleeArguments());
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_tear_off_arguments) {
+ DEFINE_OPCODE(op_tear_off_arguments) {
/* tear_off_arguments
Copy all arguments to new memory allocated on the heap,
@@ -3438,14 +3373,14 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
This opcode should only be used immediately before op_ret.
*/
- ASSERT(callFrame->codeBlock()->usesArguments && !callFrame->codeBlock()->needsFullScopeChain);
+ ASSERT(callFrame->codeBlock()->usesArguments() && !callFrame->codeBlock()->needsFullScopeChain());
callFrame->optionalCalleeArguments()->copyRegisters();
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_ret) {
+ DEFINE_OPCODE(op_ret) {
/* ret result(r)
Return register result as the return value of the current
@@ -3457,10 +3392,10 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int result = (++vPC)->u.operand;
- if (callFrame->codeBlock()->needsFullScopeChain)
+ if (callFrame->codeBlock()->needsFullScopeChain())
callFrame->scopeChain()->deref();
- JSValue* returnValue = callFrame[result].jsValue(callFrame);
+ JSValuePtr returnValue = callFrame[result].jsValue(callFrame);
vPC = callFrame->returnPC();
int dst = callFrame->returnValueRegister();
@@ -3469,11 +3404,11 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
if (callFrame->hasHostCallFrameFlag())
return returnValue;
- callFrame[dst] = returnValue;
+ callFrame[dst] = JSValuePtr(returnValue);
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_enter) {
+ DEFINE_OPCODE(op_enter) {
/* enter
Initializes local variables to undefined and fills constant
@@ -3487,16 +3422,16 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
size_t i = 0;
CodeBlock* codeBlock = callFrame->codeBlock();
- for (size_t count = codeBlock->numVars; i < count; ++i)
+ for (size_t count = codeBlock->m_numVars; i < count; ++i)
callFrame[i] = jsUndefined();
- for (size_t count = codeBlock->constantRegisters.size(), j = 0; j < count; ++i, ++j)
- callFrame[i] = codeBlock->constantRegisters[j];
+ for (size_t count = codeBlock->numberOfConstantRegisters(), j = 0; j < count; ++i, ++j)
+ callFrame[i] = codeBlock->constantRegister(j);
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_enter_with_activation) {
+ DEFINE_OPCODE(op_enter_with_activation) {
/* enter_with_activation dst(r)
Initializes local variables to undefined, fills constant
@@ -3512,21 +3447,21 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
size_t i = 0;
CodeBlock* codeBlock = callFrame->codeBlock();
- for (size_t count = codeBlock->numVars; i < count; ++i)
+ for (size_t count = codeBlock->m_numVars; i < count; ++i)
callFrame[i] = jsUndefined();
- for (size_t count = codeBlock->constantRegisters.size(), j = 0; j < count; ++i, ++j)
- callFrame[i] = codeBlock->constantRegisters[j];
+ for (size_t count = codeBlock->numberOfConstantRegisters(), j = 0; j < count; ++i, ++j)
+ callFrame[i] = codeBlock->constantRegister(j);
int dst = (++vPC)->u.operand;
- JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionBodyNode*>(codeBlock->ownerNode));
+ JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionBodyNode*>(codeBlock->ownerNode()));
callFrame[dst] = activation;
callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_convert_this) {
+ DEFINE_OPCODE(op_convert_this) {
/* convert_this this(r)
Takes the value in the 'this' register, converts it to a
@@ -3539,14 +3474,14 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int thisRegister = (++vPC)->u.operand;
- JSValue* thisVal = callFrame[thisRegister].getJSValue();
- if (thisVal->needsThisConversion())
- callFrame[thisRegister] = thisVal->toThisObject(callFrame);
+ JSValuePtr thisVal = callFrame[thisRegister].getJSValue();
+ if (thisVal.needsThisConversion())
+ callFrame[thisRegister] = JSValuePtr(thisVal.toThisObject(callFrame));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_create_arguments) {
+ DEFINE_OPCODE(op_create_arguments) {
/* create_arguments
Creates the 'arguments' object and places it in both the
@@ -3562,49 +3497,49 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
callFrame[RegisterFile::ArgumentsRegister] = arguments;
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_construct) {
- /* construct dst(r) constr(r) constrProto(r) firstArg(r) argCount(n) registerOffset(n)
+ DEFINE_OPCODE(op_construct) {
+ /* construct dst(r) func(r) argCount(n) registerOffset(n) proto(r) thisRegister(r)
- Invoke register "constr" as a constructor. For JS
+ Invoke register "func" as a constructor. For JS
functions, the calling convention is exactly as for the
"call" opcode, except that the "this" value is a newly
- created Object. For native constructors, a null "this"
- value is passed. In either case, the firstArg and argCount
+ created Object. For native constructors, no "this"
+ value is passed. In either case, the argCount and registerOffset
registers are interpreted as for the "call" opcode.
- Register constrProto must contain the prototype property of
- register constsr. This is to enable polymorphic inline
+ Register proto must contain the prototype property of
+ register func. This is to enable polymorphic inline
caching of this lookup.
*/
int dst = vPC[1].u.operand;
- int constr = vPC[2].u.operand;
- int constrProto = vPC[3].u.operand;
- int firstArg = vPC[4].u.operand;
- int argCount = vPC[5].u.operand;
- int registerOffset = vPC[6].u.operand;
+ int func = vPC[2].u.operand;
+ int argCount = vPC[3].u.operand;
+ int registerOffset = vPC[4].u.operand;
+ int proto = vPC[5].u.operand;
+ int thisRegister = vPC[6].u.operand;
- JSValue* v = callFrame[constr].jsValue(callFrame);
+ JSValuePtr v = callFrame[func].jsValue(callFrame);
ConstructData constructData;
- ConstructType constructType = v->getConstructData(constructData);
+ ConstructType constructType = v.getConstructData(constructData);
if (constructType == ConstructTypeJS) {
ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
- CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
+ CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
- StructureID* structure;
- JSValue* prototype = callFrame[constrProto].jsValue(callFrame);
- if (prototype->isObject())
+ Structure* structure;
+ JSValuePtr prototype = callFrame[proto].jsValue(callFrame);
+ if (prototype.isObject())
structure = asObject(prototype)->inheritorID();
else
structure = callDataScopeChain->globalObject()->emptyObjectStructure();
JSObject* newObject = new (globalData) JSObject(structure);
- callFrame[firstArg] = newObject; // "this" value
+ callFrame[thisRegister] = JSValuePtr(newObject); // "this" value
CallFrame* previousCallFrame = callFrame;
@@ -3616,40 +3551,40 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
}
callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
- vPC = newCodeBlock->instructions.begin();
+ vPC = newCodeBlock->instructions().begin();
#if ENABLE(OPCODE_STATS)
OpcodeStats::resetLastInstruction();
#endif
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
if (constructType == ConstructTypeHost) {
- ArgList args(callFrame->registers() + firstArg + 1, argCount - 1);
+ ArgList args(callFrame->registers() + thisRegister + 1, argCount - 1);
ScopeChainNode* scopeChain = callFrame->scopeChain();
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
- JSValue* returnValue;
+ JSValuePtr returnValue;
{
SamplingTool::HostCallRecord callRecord(m_sampler);
returnValue = constructData.native.function(newCallFrame, asObject(v), args);
}
- VM_CHECK_EXCEPTION();
- callFrame[dst] = returnValue;
+ CHECK_FOR_EXCEPTION();
+ callFrame[dst] = JSValuePtr(returnValue);
vPC += 7;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
ASSERT(constructType == ConstructTypeNone);
- exceptionValue = createNotAConstructorError(callFrame, v, vPC, callFrame->codeBlock());
+ exceptionValue = createNotAConstructorError(callFrame, v, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock());
goto vm_throw;
}
- BEGIN_OPCODE(op_construct_verify) {
+ DEFINE_OPCODE(op_construct_verify) {
/* construct_verify dst(r) override(r)
Verifies that register dst holds an object. If not, moves
@@ -3657,34 +3592,36 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = vPC[1].u.operand;;
- if (LIKELY(callFrame[dst].jsValue(callFrame)->isObject())) {
+ if (LIKELY(callFrame[dst].jsValue(callFrame).isObject())) {
vPC += 3;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
int override = vPC[2].u.operand;
callFrame[dst] = callFrame[override];
vPC += 3;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_push_scope) {
+ DEFINE_OPCODE(op_push_scope) {
/* push_scope scope(r)
Converts register scope to object, and pushes it onto the top
- of the current scope chain.
+ of the current scope chain. The contents of the register scope
+ are replaced by the result of toObject conversion of the scope.
*/
int scope = (++vPC)->u.operand;
- JSValue* v = callFrame[scope].jsValue(callFrame);
- JSObject* o = v->toObject(callFrame);
- VM_CHECK_EXCEPTION();
+ JSValuePtr v = callFrame[scope].jsValue(callFrame);
+ JSObject* o = v.toObject(callFrame);
+ CHECK_FOR_EXCEPTION();
+ callFrame[scope] = JSValuePtr(o);
callFrame->setScopeChain(callFrame->scopeChain()->push(o));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_pop_scope) {
+ DEFINE_OPCODE(op_pop_scope) {
/* pop_scope
Removes the top item from the current scope chain.
@@ -3692,9 +3629,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
callFrame->setScopeChain(callFrame->scopeChain()->pop());
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_get_pnames) {
+ DEFINE_OPCODE(op_get_pnames) {
/* get_pnames dst(r) base(r)
Creates a property name list for register base and puts it
@@ -3707,9 +3644,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
callFrame[dst] = JSPropertyNameIterator::create(callFrame, callFrame[base].jsValue(callFrame));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_next_pname) {
+ DEFINE_OPCODE(op_next_pname) {
/* next_pname dst(r) iter(r) target(offset)
Tries to copies the next name from property name list in
@@ -3723,18 +3660,18 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int target = (++vPC)->u.operand;
JSPropertyNameIterator* it = callFrame[iter].propertyNameIterator();
- if (JSValue* temp = it->next(callFrame)) {
+ if (JSValuePtr temp = it->next(callFrame)) {
CHECK_FOR_TIMEOUT();
- callFrame[dst] = temp;
+ callFrame[dst] = JSValuePtr(temp);
vPC += target;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
it->invalidate();
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_jmp_scopes) {
+ DEFINE_OPCODE(op_jmp_scopes) {
/* jmp_scopes count(n) target(offset)
Removes the a number of items from the current scope chain
@@ -3750,13 +3687,13 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
callFrame->setScopeChain(tmp);
vPC += target;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
#if HAVE(COMPUTED_GOTO)
// Appease GCC
goto *(&&skip_new_scope);
#endif
- BEGIN_OPCODE(op_push_new_scope) {
+ DEFINE_OPCODE(op_push_new_scope) {
/* new_scope dst(r) property(id) value(r)
Constructs a new StaticScopeObject with property set to value. That scope
@@ -3766,12 +3703,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
callFrame->setScopeChain(createExceptionScope(callFrame, vPC));
vPC += 4;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
#if HAVE(COMPUTED_GOTO)
skip_new_scope:
#endif
- BEGIN_OPCODE(op_catch) {
+ DEFINE_OPCODE(op_catch) {
/* catch ex(r)
Retrieves the VMs current exception and puts it in register
@@ -3785,9 +3722,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
exceptionValue = noValue();
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_throw) {
+ DEFINE_OPCODE(op_throw) {
/* throw ex(r)
Throws register ex as an exception. This involves three
@@ -3801,37 +3738,28 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int ex = (++vPC)->u.operand;
exceptionValue = callFrame[ex].jsValue(callFrame);
- handlerVPC = throwException(callFrame, exceptionValue, vPC, true);
- if (!handlerVPC) {
+ handler = throwException(callFrame, exceptionValue, vPC - callFrame->codeBlock()->instructions().begin(), true);
+ if (!handler) {
*exception = exceptionValue;
return jsNull();
}
-#if HAVE(COMPUTED_GOTO)
- // Hack around gcc performance quirk by performing an indirect goto
- // in order to set the vPC -- attempting to do so directly results in a
- // significant regression.
- goto *op_throw_end_indirect; // indirect goto -> op_throw_end
+ vPC = callFrame->codeBlock()->instructions().begin() + handler->target;
+ NEXT_INSTRUCTION();
}
- op_throw_end: {
-#endif
-
- vPC = handlerVPC;
- NEXT_OPCODE;
- }
- BEGIN_OPCODE(op_unexpected_load) {
+ DEFINE_OPCODE(op_unexpected_load) {
/* unexpected_load load dst(r) src(k)
Copies constant src to register dst.
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- callFrame[dst] = callFrame->codeBlock()->unexpectedConstants[src];
+ callFrame[dst] = JSValuePtr(callFrame->codeBlock()->unexpectedConstant(src));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_new_error) {
+ DEFINE_OPCODE(op_new_error) {
/* new_error dst(r) type(n) message(k)
Constructs a new Error instance using the original
@@ -3844,19 +3772,19 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int message = (++vPC)->u.operand;
CodeBlock* codeBlock = callFrame->codeBlock();
- callFrame[dst] = Error::create(callFrame, (ErrorType)type, codeBlock->unexpectedConstants[message]->toString(callFrame), codeBlock->lineNumberForVPC(vPC), codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->sourceURL());
+ callFrame[dst] = JSValuePtr(Error::create(callFrame, (ErrorType)type, codeBlock->unexpectedConstant(message).toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_end) {
+ DEFINE_OPCODE(op_end) {
/* end result(r)
Return register result as the value of a global or eval
program. Return control to the calling native code.
*/
- if (callFrame->codeBlock()->needsFullScopeChain) {
+ if (callFrame->codeBlock()->needsFullScopeChain()) {
ScopeChainNode* scopeChain = callFrame->scopeChain();
ASSERT(scopeChain->refCount > 1);
scopeChain->deref();
@@ -3864,7 +3792,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int result = (++vPC)->u.operand;
return callFrame[result].jsValue(callFrame);
}
- BEGIN_OPCODE(op_put_getter) {
+ DEFINE_OPCODE(op_put_getter) {
/* put_getter base(r) property(id) function(r)
Sets register function on register base as the getter named
@@ -3879,16 +3807,16 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int property = (++vPC)->u.operand;
int function = (++vPC)->u.operand;
- ASSERT(callFrame[base].jsValue(callFrame)->isObject());
+ ASSERT(callFrame[base].jsValue(callFrame).isObject());
JSObject* baseObj = asObject(callFrame[base].jsValue(callFrame));
- Identifier& ident = callFrame->codeBlock()->identifiers[property];
- ASSERT(callFrame[function].jsValue(callFrame)->isObject());
+ Identifier& ident = callFrame->codeBlock()->identifier(property);
+ ASSERT(callFrame[function].jsValue(callFrame).isObject());
baseObj->defineGetter(callFrame, ident, asObject(callFrame[function].jsValue(callFrame)));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_put_setter) {
+ DEFINE_OPCODE(op_put_setter) {
/* put_setter base(r) property(id) function(r)
Sets register function on register base as the setter named
@@ -3903,16 +3831,16 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
int property = (++vPC)->u.operand;
int function = (++vPC)->u.operand;
- ASSERT(callFrame[base].jsValue(callFrame)->isObject());
+ ASSERT(callFrame[base].jsValue(callFrame).isObject());
JSObject* baseObj = asObject(callFrame[base].jsValue(callFrame));
- Identifier& ident = callFrame->codeBlock()->identifiers[property];
- ASSERT(callFrame[function].jsValue(callFrame)->isObject());
+ Identifier& ident = callFrame->codeBlock()->identifier(property);
+ ASSERT(callFrame[function].jsValue(callFrame).isObject());
baseObj->defineSetter(callFrame, ident, asObject(callFrame[function].jsValue(callFrame)));
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_jsr) {
+ DEFINE_OPCODE(op_jsr) {
/* jsr retAddrDst(r) target(offset)
Places the address of the next instruction into the retAddrDst
@@ -3923,9 +3851,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
callFrame[retAddrDst] = vPC + 1;
vPC += target;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_sret) {
+ DEFINE_OPCODE(op_sret) {
/* sret retAddrSrc(r)
Jumps to the address stored in the retAddrSrc register. This
@@ -3934,9 +3862,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int retAddrSrc = (++vPC)->u.operand;
vPC = callFrame[retAddrSrc].vPC();
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_debug) {
+ DEFINE_OPCODE(op_debug) {
/* debug debugHookID(n) firstLine(n) lastLine(n)
Notifies the debugger of the current state of execution. This opcode
@@ -3949,9 +3877,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
++vPC;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_profile_will_call) {
+ DEFINE_OPCODE(op_profile_will_call) {
/* op_profile_will_call function(r)
Notifies the profiler of the beginning of a function call. This opcode
@@ -3963,9 +3891,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
(*enabledProfilerReference)->willExecute(callFrame, callFrame[function].jsValue(callFrame));
vPC += 2;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
- BEGIN_OPCODE(op_profile_did_call) {
+ DEFINE_OPCODE(op_profile_did_call) {
/* op_profile_did_call function(r)
Notifies the profiler of the end of a function call. This opcode
@@ -3977,7 +3905,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
(*enabledProfilerReference)->didExecute(callFrame, callFrame[function].jsValue(callFrame));
vPC += 2;
- NEXT_OPCODE;
+ NEXT_INSTRUCTION();
}
vm_throw: {
globalData->exception = noValue();
@@ -3986,34 +3914,35 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
// cannot fathom if we don't assign to the exceptionValue before branching)
exceptionValue = createInterruptedExecutionException(globalData);
}
- handlerVPC = throwException(callFrame, exceptionValue, vPC, false);
- if (!handlerVPC) {
+ handler = throwException(callFrame, exceptionValue, vPC - callFrame->codeBlock()->instructions().begin(), false);
+ if (!handler) {
*exception = exceptionValue;
return jsNull();
}
- vPC = handlerVPC;
- NEXT_OPCODE;
+
+ vPC = callFrame->codeBlock()->instructions().begin() + handler->target;
+ NEXT_INSTRUCTION();
}
}
#if !HAVE(COMPUTED_GOTO)
} // iterator loop ends
#endif
- #undef NEXT_OPCODE
- #undef BEGIN_OPCODE
- #undef VM_CHECK_EXCEPTION
+ #undef NEXT_INSTRUCTION
+ #undef DEFINE_OPCODE
+ #undef CHECK_FOR_EXCEPTION
#undef CHECK_FOR_TIMEOUT
}
-JSValue* Machine::retrieveArguments(CallFrame* callFrame, JSFunction* function) const
+JSValuePtr Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* function) const
{
CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function);
if (!functionCallFrame)
return jsNull();
CodeBlock* codeBlock = functionCallFrame->codeBlock();
- if (codeBlock->usesArguments) {
- ASSERT(codeBlock->codeType == FunctionCode);
- SymbolTable& symbolTable = static_cast<FunctionBodyNode*>(codeBlock->ownerNode)->symbolTable();
+ if (codeBlock->usesArguments()) {
+ ASSERT(codeBlock->codeType() == FunctionCode);
+ SymbolTable& symbolTable = codeBlock->symbolTable();
int argumentsIndex = symbolTable.get(functionCallFrame->propertyNames().arguments.ustring().rep()).getIndex();
return functionCallFrame[argumentsIndex].jsValue(callFrame);
}
@@ -4028,7 +3957,7 @@ JSValue* Machine::retrieveArguments(CallFrame* callFrame, JSFunction* function)
return arguments;
}
-JSValue* Machine::retrieveCaller(CallFrame* callFrame, InternalFunction* function) const
+JSValuePtr Interpreter::retrieveCaller(CallFrame* callFrame, InternalFunction* function) const
{
CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function);
if (!functionCallFrame)
@@ -4038,14 +3967,14 @@ JSValue* Machine::retrieveCaller(CallFrame* callFrame, InternalFunction* functio
if (callerFrame->hasHostCallFrameFlag())
return jsNull();
- JSValue* caller = callerFrame->callee();
+ JSValuePtr caller = callerFrame->callee();
if (!caller)
return jsNull();
return caller;
}
-void Machine::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue*& function) const
+void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValuePtr& function) const
{
function = noValue();
lineNumber = -1;
@@ -4059,14 +3988,14 @@ void Machine::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t
if (!callerCodeBlock)
return;
- Instruction* vPC = vPCForPC(callerCodeBlock, callFrame->returnPC());
- lineNumber = callerCodeBlock->lineNumberForVPC(vPC - 1);
- sourceID = callerCodeBlock->ownerNode->sourceID();
- sourceURL = callerCodeBlock->ownerNode->sourceURL();
+ unsigned bytecodeOffset = bytecodeOffsetForPC(callerFrame, callerCodeBlock, callFrame->returnPC());
+ lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(callerFrame, bytecodeOffset - 1);
+ sourceID = callerCodeBlock->ownerNode()->sourceID();
+ sourceURL = callerCodeBlock->ownerNode()->sourceURL();
function = callerFrame->callee();
}
-CallFrame* Machine::findFunctionCallFrame(CallFrame* callFrame, InternalFunction* function)
+CallFrame* Interpreter::findFunctionCallFrame(CallFrame* callFrame, InternalFunction* function)
{
for (CallFrame* candidate = callFrame; candidate; candidate = candidate->callerFrame()->removeHostCallFrameFlag()) {
if (candidate->callee() == function)
@@ -4075,220 +4004,169 @@ CallFrame* Machine::findFunctionCallFrame(CallFrame* callFrame, InternalFunction
return 0;
}
-#if ENABLE(CTI)
+#if ENABLE(JIT)
-NEVER_INLINE void Machine::tryCTICachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, void* returnAddress, JSValue* baseValue, const PutPropertySlot& slot)
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+NEVER_INLINE void Interpreter::tryCTICachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, void* returnAddress, JSValuePtr baseValue, const PutPropertySlot& slot)
{
// The interpreter checks for recursion here; I do not believe this can occur in CTI.
- if (JSImmediate::isImmediate(baseValue))
+ if (!baseValue.isCell())
return;
// Uncacheable: give up.
if (!slot.isCacheable()) {
- ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_put_by_id_generic));
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_put_by_id_generic));
return;
}
JSCell* baseCell = asCell(baseValue);
- StructureID* structureID = baseCell->structureID();
+ Structure* structure = baseCell->structure();
- if (structureID->isDictionary()) {
- ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_put_by_id_generic));
+ if (structure->isDictionary()) {
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_put_by_id_generic));
return;
}
- // In the interpreter the last structure is trapped here; in CTI we use the
- // *_second method to achieve a similar (but not quite the same) effect.
-
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(returnAddress);
- Instruction* vPC = codeBlock->instructions.begin() + vPCIndex;
-
- // Cache hit: Specialize instruction and ref StructureIDs.
-
// If baseCell != base, then baseCell must be a proxy for another object.
if (baseCell != slot.base()) {
- ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_put_by_id_generic));
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_put_by_id_generic));
return;
}
- // StructureID transition, cache transition info
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
+
+ // Cache hit: Specialize instruction and ref Structures.
+
+ // Structure transition, cache transition info
if (slot.type() == PutPropertySlot::NewProperty) {
- vPC[0] = getOpcode(op_put_by_id_transition);
- vPC[4] = structureID->previousID();
- vPC[5] = structureID;
- StructureIDChain* chain = structureID->cachedPrototypeChain();
+ StructureChain* chain = structure->cachedPrototypeChain();
if (!chain) {
- chain = cachePrototypeChain(callFrame, structureID);
+ chain = cachePrototypeChain(callFrame, structure);
if (!chain) {
- // This happens if someone has manually inserted null into the prototype chain
- vPC[0] = getOpcode(op_put_by_id_generic);
+ // This happens if someone has manually inserted null into the prototype chain
+ stubInfo->opcodeID = op_put_by_id_generic;
return;
}
}
- vPC[6] = chain;
- vPC[7] = slot.cachedOffset();
- codeBlock->refStructureIDs(vPC);
- CTI::compilePutByIdTransition(this, callFrame, codeBlock, structureID->previousID(), structureID, slot.cachedOffset(), chain, returnAddress);
+ stubInfo->initPutByIdTransition(structure->previousID(), structure, chain);
+ JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), chain, returnAddress);
return;
}
- vPC[0] = getOpcode(op_put_by_id_replace);
- vPC[4] = structureID;
- vPC[5] = slot.cachedOffset();
- codeBlock->refStructureIDs(vPC);
+ stubInfo->initPutByIdReplace(structure);
#if USE(CTI_REPATCH_PIC)
UNUSED_PARAM(callFrame);
- CTI::patchPutByIdReplace(codeBlock, structureID, slot.cachedOffset(), returnAddress);
+ JIT::patchPutByIdReplace(stubInfo, structure, slot.cachedOffset(), returnAddress);
#else
- CTI::compilePutByIdReplace(this, callFrame, codeBlock, structureID, slot.cachedOffset(), returnAddress);
+ JIT::compilePutByIdReplace(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
#endif
}
-void* Machine::getCTIArrayLengthTrampoline(CallFrame* callFrame, CodeBlock* codeBlock)
-{
- if (!m_ctiArrayLengthTrampoline)
- m_ctiArrayLengthTrampoline = CTI::compileArrayLengthTrampoline(this, callFrame, codeBlock);
-
- return m_ctiArrayLengthTrampoline;
-}
-
-void* Machine::getCTIStringLengthTrampoline(CallFrame* callFrame, CodeBlock* codeBlock)
-{
- if (!m_ctiStringLengthTrampoline)
- m_ctiStringLengthTrampoline = CTI::compileStringLengthTrampoline(this, callFrame, codeBlock);
-
- return m_ctiStringLengthTrampoline;
-}
-
-NEVER_INLINE void Machine::tryCTICacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, void* returnAddress, JSValue* baseValue, const Identifier& propertyName, const PropertySlot& slot)
+NEVER_INLINE void Interpreter::tryCTICacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, void* returnAddress, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot& slot)
{
// FIXME: Write a test that proves we need to check for recursion here just
// like the interpreter does, then add a check for recursion.
// FIXME: Cache property access for immediates.
- if (JSImmediate::isImmediate(baseValue)) {
- ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_get_by_id_generic));
+ if (!baseValue.isCell()) {
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_get_by_id_generic));
return;
}
if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
#if USE(CTI_REPATCH_PIC)
- CTI::compilePatchGetArrayLength(this, callFrame, codeBlock, returnAddress);
+ JIT::compilePatchGetArrayLength(callFrame->scopeChain()->globalData, codeBlock, returnAddress);
#else
- ctiRepatchCallByReturnAddress(returnAddress, getCTIArrayLengthTrampoline(callFrame, codeBlock));
+ ctiPatchCallByReturnAddress(returnAddress, m_ctiArrayLengthTrampoline);
#endif
return;
}
if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
- // The tradeoff of compiling an repatched inline string length access routine does not seem
+ // The tradeoff of compiling an patched inline string length access routine does not seem
// to pay off, so we currently only do this for arrays.
- ctiRepatchCallByReturnAddress(returnAddress, getCTIStringLengthTrampoline(callFrame, codeBlock));
+ ctiPatchCallByReturnAddress(returnAddress, m_ctiStringLengthTrampoline);
return;
}
// Uncacheable: give up.
if (!slot.isCacheable()) {
- ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_get_by_id_generic));
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_get_by_id_generic));
return;
}
JSCell* baseCell = asCell(baseValue);
- StructureID* structureID = baseCell->structureID();
+ Structure* structure = baseCell->structure();
- if (structureID->isDictionary()) {
- ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_get_by_id_generic));
+ if (structure->isDictionary()) {
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_get_by_id_generic));
return;
}
// In the interpreter the last structure is trapped here; in CTI we use the
// *_second method to achieve a similar (but not quite the same) effect.
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(returnAddress);
- Instruction* vPC = codeBlock->instructions.begin() + vPCIndex;
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
- // Cache hit: Specialize instruction and ref StructureIDs.
+ // Cache hit: Specialize instruction and ref Structures.
if (slot.slotBase() == baseValue) {
- // set this up, so derefStructureIDs can do it's job.
- vPC[0] = getOpcode(op_get_by_id_self);
- vPC[4] = structureID;
- vPC[5] = slot.cachedOffset();
- codeBlock->refStructureIDs(vPC);
+ // set this up, so derefStructures can do it's job.
+ stubInfo->initGetByIdSelf(structure);
#if USE(CTI_REPATCH_PIC)
- CTI::patchGetByIdSelf(codeBlock, structureID, slot.cachedOffset(), returnAddress);
+ JIT::patchGetByIdSelf(stubInfo, structure, slot.cachedOffset(), returnAddress);
#else
- CTI::compileGetByIdSelf(this, callFrame, codeBlock, structureID, slot.cachedOffset(), returnAddress);
+ JIT::compileGetByIdSelf(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
#endif
return;
}
- if (slot.slotBase() == structureID->prototypeForLookup(callFrame)) {
- ASSERT(slot.slotBase()->isObject());
+ if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
+ ASSERT(slot.slotBase().isObject());
JSObject* slotBaseObject = asObject(slot.slotBase());
- // Heavy access to a prototype is a good indication that it's not being
- // used as a dictionary.
- if (slotBaseObject->structureID()->isDictionary()) {
- RefPtr<StructureID> transition = StructureID::fromDictionaryTransition(slotBaseObject->structureID());
- slotBaseObject->setStructureID(transition.release());
- asObject(baseValue)->structureID()->setCachedPrototypeChain(0);
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (slotBaseObject->structure()->isDictionary()) {
+ RefPtr<Structure> transition = Structure::fromDictionaryTransition(slotBaseObject->structure());
+ slotBaseObject->setStructure(transition.release());
+ asCell(baseValue)->structure()->setCachedPrototypeChain(0);
}
+
+ stubInfo->initGetByIdProto(structure, slotBaseObject->structure());
- vPC[0] = getOpcode(op_get_by_id_proto);
- vPC[4] = structureID;
- vPC[5] = slotBaseObject->structureID();
- vPC[6] = slot.cachedOffset();
- codeBlock->refStructureIDs(vPC);
-
- CTI::compileGetByIdProto(this, callFrame, codeBlock, structureID, slotBaseObject->structureID(), slot.cachedOffset(), returnAddress);
+ JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), slot.cachedOffset(), returnAddress);
return;
}
- size_t count = 0;
- JSObject* o = asObject(baseValue);
- while (slot.slotBase() != o) {
- JSValue* v = o->structureID()->prototypeForLookup(callFrame);
-
- // If we didn't find slotBase in baseValue's prototype chain, then baseValue
- // must be a proxy for another object.
-
- if (v->isNull()) {
- vPC[0] = getOpcode(op_get_by_id_generic);
- return;
- }
-
- o = asObject(v);
-
- // Heavy access to a prototype is a good indication that it's not being
- // used as a dictionary.
- if (o->structureID()->isDictionary()) {
- RefPtr<StructureID> transition = StructureID::fromDictionaryTransition(o->structureID());
- o->setStructureID(transition.release());
- asObject(baseValue)->structureID()->setCachedPrototypeChain(0);
- }
-
- ++count;
+ size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot);
+ if (!count) {
+ stubInfo->opcodeID = op_get_by_id_generic;
+ return;
}
- StructureIDChain* chain = structureID->cachedPrototypeChain();
+ StructureChain* chain = structure->cachedPrototypeChain();
if (!chain)
- chain = cachePrototypeChain(callFrame, structureID);
-
+ chain = cachePrototypeChain(callFrame, structure);
ASSERT(chain);
- vPC[0] = getOpcode(op_get_by_id_chain);
- vPC[4] = structureID;
- vPC[5] = chain;
- vPC[6] = count;
- vPC[7] = slot.cachedOffset();
- codeBlock->refStructureIDs(vPC);
- CTI::compileGetByIdChain(this, callFrame, codeBlock, structureID, chain, count, slot.cachedOffset(), returnAddress);
+ stubInfo->initGetByIdChain(structure, chain);
+
+ JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, chain, count, slot.cachedOffset(), returnAddress);
}
+#endif
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+#define SETUP_VA_LISTL_ARGS va_list vl_args; va_start(vl_args, args)
+#else // JIT_STUB_ARGUMENT_REGISTER or JIT_STUB_ARGUMENT_STACK
+#define SETUP_VA_LISTL_ARGS
+#endif
+
#ifndef NDEBUG
extern "C" {
@@ -4318,15 +4196,15 @@ struct StackHack {
void* savedReturnAddress;
};
-#define CTI_STACK_HACK() StackHack stackHack(&CTI_RETURN_ADDRESS_SLOT)
-#define CTI_SET_RETURN_ADDRESS(address) stackHack.savedReturnAddress = address
-#define CTI_RETURN_ADDRESS stackHack.savedReturnAddress
+#define BEGIN_STUB_FUNCTION() SETUP_VA_LISTL_ARGS; StackHack stackHack(&STUB_RETURN_ADDRESS_SLOT)
+#define STUB_SET_RETURN_ADDRESS(address) stackHack.savedReturnAddress = address
+#define STUB_RETURN_ADDRESS stackHack.savedReturnAddress
#else
-#define CTI_STACK_HACK() (void)0
-#define CTI_SET_RETURN_ADDRESS(address) ctiSetReturnAddress(&CTI_RETURN_ADDRESS_SLOT, address);
-#define CTI_RETURN_ADDRESS CTI_RETURN_ADDRESS_SLOT
+#define BEGIN_STUB_FUNCTION() SETUP_VA_LISTL_ARGS
+#define STUB_SET_RETURN_ADDRESS(address) ctiSetReturnAddress(&STUB_RETURN_ADDRESS_SLOT, address);
+#define STUB_RETURN_ADDRESS STUB_RETURN_ADDRESS_SLOT
#endif
@@ -4334,11 +4212,17 @@ struct StackHack {
// to get the address of the ctiVMThrowTrampoline function. It's also
// good to keep the code size down by leaving as much of the exception
// handling code out of line as possible.
-static NEVER_INLINE void setUpThrowTrampolineReturnAddress(JSGlobalData* globalData, void*& returnAddress)
+static NEVER_INLINE void returnToThrowTrampoline(JSGlobalData* globalData, void* exceptionLocation, void*& returnAddressSlot)
{
ASSERT(globalData->exception);
- globalData->throwReturnAddress = returnAddress;
- ctiSetReturnAddress(&returnAddress, reinterpret_cast<void*>(ctiVMThrowTrampoline));
+ globalData->exceptionLocation = exceptionLocation;
+ ctiSetReturnAddress(&returnAddressSlot, reinterpret_cast<void*>(ctiVMThrowTrampoline));
+}
+
+static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalData* globalData, void* exceptionLocation, void*& returnAddressSlot)
+{
+ globalData->exception = createStackOverflowError(callFrame);
+ returnToThrowTrampoline(globalData, exceptionLocation, returnAddressSlot);
}
#define VM_THROW_EXCEPTION() \
@@ -4349,23 +4233,22 @@ static NEVER_INLINE void setUpThrowTrampolineReturnAddress(JSGlobalData* globalD
#define VM_THROW_EXCEPTION_2() \
do { \
VM_THROW_EXCEPTION_AT_END(); \
- VoidPtrPairValue pair = {{ 0, 0 }}; \
- return pair.i; \
+ RETURN_PAIR(0, 0); \
} while (0)
#define VM_THROW_EXCEPTION_AT_END() \
- setUpThrowTrampolineReturnAddress(ARG_globalData, CTI_RETURN_ADDRESS)
+ returnToThrowTrampoline(ARG_globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS)
-#define VM_CHECK_EXCEPTION() \
+#define CHECK_FOR_EXCEPTION() \
do { \
if (UNLIKELY(ARG_globalData->exception != noValue())) \
VM_THROW_EXCEPTION(); \
} while (0)
-#define VM_CHECK_EXCEPTION_AT_END() \
+#define CHECK_FOR_EXCEPTION_AT_END() \
do { \
if (UNLIKELY(ARG_globalData->exception != noValue())) \
VM_THROW_EXCEPTION_AT_END(); \
} while (0)
-#define VM_CHECK_EXCEPTION_VOID() \
+#define CHECK_FOR_EXCEPTION_VOID() \
do { \
if (UNLIKELY(ARG_globalData->exception != noValue())) { \
VM_THROW_EXCEPTION_AT_END(); \
@@ -4373,433 +4256,614 @@ static NEVER_INLINE void setUpThrowTrampolineReturnAddress(JSGlobalData* globalD
} \
} while (0)
-JSObject* Machine::cti_op_convert_this(CTI_ARGS)
+JSObject* Interpreter::cti_op_convert_this(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* v1 = ARG_src1;
+ JSValuePtr v1 = ARG_src1;
CallFrame* callFrame = ARG_callFrame;
- JSObject* result = v1->toThisObject(callFrame);
- VM_CHECK_EXCEPTION_AT_END();
+ JSObject* result = v1.toThisObject(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
return result;
}
-void Machine::cti_op_end(CTI_ARGS)
+void Interpreter::cti_op_end(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
ScopeChainNode* scopeChain = ARG_callFrame->scopeChain();
ASSERT(scopeChain->refCount > 1);
scopeChain->deref();
}
-JSValue* Machine::cti_op_add(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_add(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* v1 = ARG_src1;
- JSValue* v2 = ARG_src2;
+ JSValuePtr v1 = ARG_src1;
+ JSValuePtr v2 = ARG_src2;
double left;
double right = 0.0;
- bool rightIsNumber = fastIsNumber(v2, right);
- if (rightIsNumber && fastIsNumber(v1, left))
- return jsNumber(ARG_globalData, left + right);
+ bool rightIsNumber = v2.getNumber(right);
+ if (rightIsNumber && v1.getNumber(left))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left + right));
CallFrame* callFrame = ARG_callFrame;
- bool leftIsString = v1->isString();
- if (leftIsString && v2->isString()) {
+ bool leftIsString = v1.isString();
+ if (leftIsString && v2.isString()) {
RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
if (UNLIKELY(!value)) {
throwOutOfMemoryError(callFrame);
VM_THROW_EXCEPTION();
}
- return jsString(ARG_globalData, value.release());
+ return JSValuePtr::encode(jsString(ARG_globalData, value.release()));
}
if (rightIsNumber & leftIsString) {
- RefPtr<UString::Rep> value = JSImmediate::isImmediate(v2) ?
- concatenate(asString(v1)->value().rep(), JSImmediate::getTruncatedInt32(v2)) :
+ RefPtr<UString::Rep> value = v2.isInt32Fast() ?
+ concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) :
concatenate(asString(v1)->value().rep(), right);
if (UNLIKELY(!value)) {
throwOutOfMemoryError(callFrame);
VM_THROW_EXCEPTION();
}
- return jsString(ARG_globalData, value.release());
+ return JSValuePtr::encode(jsString(ARG_globalData, value.release()));
}
// All other cases are pretty uncommon
- JSValue* result = jsAddSlowCase(callFrame, v1, v2);
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsAddSlowCase(callFrame, v1, v2);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_pre_inc(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_pre_inc(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* v = ARG_src1;
+ JSValuePtr v = ARG_src1;
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, v->toNumber(callFrame) + 1);
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, v.toNumber(callFrame) + 1);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-void Machine::cti_timeout_check(CTI_ARGS)
+int Interpreter::cti_timeout_check(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
+ Interpreter* interpreter = ARG_globalData->interpreter;
- if (ARG_globalData->machine->checkTimeout(ARG_callFrame->dynamicGlobalObject())) {
+ if (interpreter->checkTimeout(ARG_callFrame->dynamicGlobalObject())) {
ARG_globalData->exception = createInterruptedExecutionException(ARG_globalData);
VM_THROW_EXCEPTION_AT_END();
}
+
+ return interpreter->m_ticksUntilNextTimeoutCheck;
}
-NEVER_INLINE void Machine::throwStackOverflowPreviousFrame(CallFrame* callFrame, JSGlobalData* globalData, void*& returnAddress)
-{
- globalData->exception = createStackOverflowError(callFrame->callerFrame());
- globalData->throwReturnAddress = callFrame->returnPC();
- ctiSetReturnAddress(&returnAddress, reinterpret_cast<void*>(ctiVMThrowTrampoline));
-}
-
-void Machine::cti_register_file_check(CTI_ARGS)
+void Interpreter::cti_register_file_check(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- if (LIKELY(ARG_registerFile->grow(ARG_callFrame + ARG_callFrame->codeBlock()->numCalleeRegisters)))
+ if (LIKELY(ARG_registerFile->grow(ARG_callFrame + ARG_callFrame->codeBlock()->m_numCalleeRegisters)))
return;
- ARG_setCallFrame(ARG_callFrame->callerFrame());
- throwStackOverflowPreviousFrame(ARG_callFrame, ARG_globalData, CTI_RETURN_ADDRESS);
+ // Rewind to the previous call frame because op_call already optimistically
+ // moved the call frame forward.
+ CallFrame* oldCallFrame = ARG_callFrame->callerFrame();
+ ARG_setCallFrame(oldCallFrame);
+ throwStackOverflowError(oldCallFrame, ARG_globalData, oldCallFrame->returnPC(), STUB_RETURN_ADDRESS);
}
-int Machine::cti_op_loop_if_less(CTI_ARGS)
+int Interpreter::cti_op_loop_if_less(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
CallFrame* callFrame = ARG_callFrame;
bool result = jsLess(callFrame, src1, src2);
- VM_CHECK_EXCEPTION_AT_END();
+ CHECK_FOR_EXCEPTION_AT_END();
return result;
}
-int Machine::cti_op_loop_if_lesseq(CTI_ARGS)
+int Interpreter::cti_op_loop_if_lesseq(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
CallFrame* callFrame = ARG_callFrame;
bool result = jsLessEq(callFrame, src1, src2);
- VM_CHECK_EXCEPTION_AT_END();
+ CHECK_FOR_EXCEPTION_AT_END();
return result;
}
-JSObject* Machine::cti_op_new_object(CTI_ARGS)
+JSObject* Interpreter::cti_op_new_object(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
return constructEmptyObject(ARG_callFrame);
}
-void Machine::cti_op_put_by_id(CTI_ARGS)
+void Interpreter::cti_op_put_by_id_generic(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
+
+ PutPropertySlot slot;
+ ARG_src1.put(ARG_callFrame, *ARG_id2, ARG_src3, slot);
+ CHECK_FOR_EXCEPTION_AT_END();
+}
+
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_generic(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
Identifier& ident = *ARG_id2;
- PutPropertySlot slot;
- ARG_src1->put(callFrame, ident, ARG_src3, slot);
-
- ctiRepatchCallByReturnAddress(CTI_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_id_second));
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(callFrame, ident, slot);
- VM_CHECK_EXCEPTION_AT_END();
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-void Machine::cti_op_put_by_id_second(CTI_ARGS)
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+void Interpreter::cti_op_put_by_id(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ Identifier& ident = *ARG_id2;
PutPropertySlot slot;
- ARG_src1->put(ARG_callFrame, *ARG_id2, ARG_src3, slot);
- ARG_globalData->machine->tryCTICachePutByID(ARG_callFrame, ARG_callFrame->codeBlock(), CTI_RETURN_ADDRESS, ARG_src1, slot);
- VM_CHECK_EXCEPTION_AT_END();
+ ARG_src1.put(callFrame, ident, ARG_src3, slot);
+
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_id_second));
+
+ CHECK_FOR_EXCEPTION_AT_END();
}
-void Machine::cti_op_put_by_id_generic(CTI_ARGS)
+void Interpreter::cti_op_put_by_id_second(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
PutPropertySlot slot;
- ARG_src1->put(ARG_callFrame, *ARG_id2, ARG_src3, slot);
- VM_CHECK_EXCEPTION_AT_END();
+ ARG_src1.put(ARG_callFrame, *ARG_id2, ARG_src3, slot);
+ ARG_globalData->interpreter->tryCTICachePutByID(ARG_callFrame, ARG_callFrame->codeBlock(), STUB_RETURN_ADDRESS, ARG_src1, slot);
+ CHECK_FOR_EXCEPTION_AT_END();
}
-void Machine::cti_op_put_by_id_fail(CTI_ARGS)
+void Interpreter::cti_op_put_by_id_fail(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
Identifier& ident = *ARG_id2;
PutPropertySlot slot;
- ARG_src1->put(callFrame, ident, ARG_src3, slot);
+ ARG_src1.put(callFrame, ident, ARG_src3, slot);
- // should probably uncachePutByID() ... this would mean doing a vPC lookup - might be worth just bleeding this until the end.
- ctiRepatchCallByReturnAddress(CTI_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_id_generic));
-
- VM_CHECK_EXCEPTION_AT_END();
+ CHECK_FOR_EXCEPTION_AT_END();
}
-JSValue* Machine::cti_op_get_by_id(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
Identifier& ident = *ARG_id2;
- JSValue* baseValue = ARG_src1;
+ JSValuePtr baseValue = ARG_src1;
PropertySlot slot(baseValue);
- JSValue* result = baseValue->get(callFrame, ident, slot);
+ JSValuePtr result = baseValue.get(callFrame, ident, slot);
- ctiRepatchCallByReturnAddress(CTI_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_second));
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_second));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_get_by_id_second(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_second(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
Identifier& ident = *ARG_id2;
- JSValue* baseValue = ARG_src1;
+ JSValuePtr baseValue = ARG_src1;
PropertySlot slot(baseValue);
- JSValue* result = baseValue->get(callFrame, ident, slot);
+ JSValuePtr result = baseValue.get(callFrame, ident, slot);
- ARG_globalData->machine->tryCTICacheGetByID(callFrame, callFrame->codeBlock(), CTI_RETURN_ADDRESS, baseValue, ident, slot);
+ ARG_globalData->interpreter->tryCTICacheGetByID(callFrame, callFrame->codeBlock(), STUB_RETURN_ADDRESS, baseValue, ident, slot);
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_get_by_id_generic(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_self_fail(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
Identifier& ident = *ARG_id2;
- JSValue* baseValue = ARG_src1;
+ JSValuePtr baseValue = ARG_src1;
PropertySlot slot(baseValue);
- JSValue* result = baseValue->get(callFrame, ident, slot);
+ JSValuePtr result = baseValue.get(callFrame, ident, slot);
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ CHECK_FOR_EXCEPTION();
+
+ if (baseValue.isCell()
+ && slot.isCacheable()
+ && !asCell(baseValue)->structure()->isDictionary()
+ && slot.slotBase() == baseValue) {
+
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+
+ ASSERT(slot.slotBase().isObject());
+
+ PolymorphicAccessStructureList* polymorphicStructureList;
+ int listIndex = 1;
+
+ if (stubInfo->opcodeID == op_get_by_id_self) {
+ ASSERT(!stubInfo->stubRoutine);
+ polymorphicStructureList = new PolymorphicAccessStructureList(0, stubInfo->u.getByIdSelf.baseObjectStructure);
+ stubInfo->initGetByIdSelfList(polymorphicStructureList, 2);
+ } else {
+ polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
+ listIndex = stubInfo->u.getByIdSelfList.listSize;
+ stubInfo->u.getByIdSelfList.listSize++;
+ }
+
+ JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), slot.cachedOffset());
+
+ if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_generic));
+ } else {
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_generic));
+ }
+ return JSValuePtr::encode(result);
+}
+
+static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(StructureStubInfo* stubInfo, int& listIndex)
+{
+ PolymorphicAccessStructureList* prototypeStructureList = 0;
+ listIndex = 1;
+
+ switch (stubInfo->opcodeID) {
+ case op_get_by_id_proto:
+ prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure);
+ stubInfo->stubRoutine = 0;
+ stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
+ break;
+ case op_get_by_id_chain:
+ prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
+ stubInfo->stubRoutine = 0;
+ stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
+ break;
+ case op_get_by_id_proto_list:
+ prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
+ listIndex = stubInfo->u.getByIdProtoList.listSize;
+ stubInfo->u.getByIdProtoList.listSize++;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ ASSERT(listIndex < POLYMORPHIC_LIST_CACHE_SIZE);
+ return prototypeStructureList;
}
-JSValue* Machine::cti_op_get_by_id_fail(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_proto_list(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- Identifier& ident = *ARG_id2;
- JSValue* baseValue = ARG_src1;
+ JSValuePtr baseValue = ARG_src1;
PropertySlot slot(baseValue);
- JSValue* result = baseValue->get(callFrame, ident, slot);
+ JSValuePtr result = baseValue.get(callFrame, *ARG_id2, slot);
- // should probably uncacheGetByID() ... this would mean doing a vPC lookup - might be worth just bleeding this until the end.
- ctiRepatchCallByReturnAddress(CTI_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_generic));
+ CHECK_FOR_EXCEPTION();
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) {
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail));
+ return JSValuePtr::encode(result);
+ }
+
+ Structure* structure = asCell(baseValue)->structure();
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+
+ ASSERT(slot.slotBase().isObject());
+ JSObject* slotBaseObject = asObject(slot.slotBase());
+
+ if (slot.slotBase() == baseValue)
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail));
+ else if (slot.slotBase() == asCell(baseValue)->structure()->prototypeForLookup(callFrame)) {
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (slotBaseObject->structure()->isDictionary()) {
+ RefPtr<Structure> transition = Structure::fromDictionaryTransition(slotBaseObject->structure());
+ slotBaseObject->setStructure(transition.release());
+ asCell(baseValue)->structure()->setCachedPrototypeChain(0);
+ }
+
+ int listIndex;
+ PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
+
+ JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), slot.cachedOffset());
+
+ if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_list_full));
+ } else if (size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot)) {
+ StructureChain* chain = structure->cachedPrototypeChain();
+ if (!chain)
+ chain = cachePrototypeChain(callFrame, structure);
+ ASSERT(chain);
+
+ int listIndex;
+ PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
+
+ JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, chain, count, slot.cachedOffset());
+
+ if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_list_full));
+ } else
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail));
+
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_proto_list_full(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_instanceof(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_proto_fail(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_array_fail(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_string_fail(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+#endif
+
+JSValueEncodedAsPointer* Interpreter::cti_op_instanceof(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- JSValue* value = ARG_src1;
- JSValue* baseVal = ARG_src2;
- JSValue* proto = ARG_src3;
+ JSValuePtr value = ARG_src1;
+ JSValuePtr baseVal = ARG_src2;
+ JSValuePtr proto = ARG_src3;
// at least one of these checks must have failed to get to the slow case
- ASSERT(JSImmediate::isAnyImmediate(value, baseVal, proto)
- || !value->isObject() || !baseVal->isObject() || !proto->isObject()
- || (asObject(baseVal)->structureID()->typeInfo().flags() & (ImplementsHasInstance | OverridesHasInstance)) != ImplementsHasInstance);
+ ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()
+ || !value.isObject() || !baseVal.isObject() || !proto.isObject()
+ || (asObject(baseVal)->structure()->typeInfo().flags() & (ImplementsHasInstance | OverridesHasInstance)) != ImplementsHasInstance);
- if (!baseVal->isObject()) {
+ if (!baseVal.isObject()) {
CallFrame* callFrame = ARG_callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
- ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(CTI_RETURN_ADDRESS));
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
- ARG_globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal, codeBlock->instructions.begin() + vPCIndex, codeBlock);
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal, vPCIndex, codeBlock);
VM_THROW_EXCEPTION();
}
- if (!asObject(baseVal)->structureID()->typeInfo().implementsHasInstance())
- return jsBoolean(false);
+ if (!asObject(baseVal)->structure()->typeInfo().implementsHasInstance())
+ return JSValuePtr::encode(jsBoolean(false));
- if (!proto->isObject()) {
+ if (!proto.isObject()) {
throwError(callFrame, TypeError, "instanceof called on an object with an invalid prototype property.");
VM_THROW_EXCEPTION();
}
- if (!value->isObject())
- return jsBoolean(false);
+ if (!value.isObject())
+ return JSValuePtr::encode(jsBoolean(false));
- JSValue* result = jsBoolean(asObject(baseVal)->hasInstance(callFrame, value, proto));
- VM_CHECK_EXCEPTION_AT_END();
+ JSValuePtr result = jsBoolean(asObject(baseVal)->hasInstance(callFrame, value, proto));
+ CHECK_FOR_EXCEPTION_AT_END();
- return result;
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_del_by_id(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_del_by_id(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- Identifier& ident = *ARG_id2;
- JSObject* baseObj = ARG_src1->toObject(callFrame);
+ JSObject* baseObj = ARG_src1.toObject(callFrame);
- JSValue* result = jsBoolean(baseObj->deleteProperty(callFrame, ident));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsBoolean(baseObj->deleteProperty(callFrame, *ARG_id2));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_mul(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_mul(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
double left;
double right;
- if (fastIsNumber(src1, left) && fastIsNumber(src2, right))
- return jsNumber(ARG_globalData, left * right);
+ if (src1.getNumber(left) && src2.getNumber(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left * right));
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, src1->toNumber(callFrame) * src2->toNumber(callFrame));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toNumber(callFrame) * src2.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSObject* Machine::cti_op_new_func(CTI_ARGS)
+JSObject* Interpreter::cti_op_new_func(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
return ARG_func1->makeFunction(ARG_callFrame, ARG_callFrame->scopeChain());
}
-VoidPtrPair Machine::cti_op_call_JSFunction(CTI_ARGS)
+void* Interpreter::cti_op_call_JSFunction(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
#ifndef NDEBUG
CallData callData;
- ASSERT(ARG_src1->getCallData(callData) == CallTypeJS);
+ ASSERT(ARG_src1.getCallData(callData) == CallTypeJS);
#endif
ScopeChainNode* callDataScopeChain = asFunction(ARG_src1)->m_scopeChain.node();
- CodeBlock* newCodeBlock = &asFunction(ARG_src1)->m_body->byteCode(callDataScopeChain);
+ CodeBlock* newCodeBlock = &asFunction(ARG_src1)->body()->bytecode(callDataScopeChain);
+
+ if (!newCodeBlock->jitCode())
+ JIT::compile(ARG_globalData, newCodeBlock);
+
+ return newCodeBlock;
+}
+
+VoidPtrPair Interpreter::cti_op_call_arityCheck(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
CallFrame* callFrame = ARG_callFrame;
- size_t registerOffset = ARG_int2;
+ CodeBlock* newCodeBlock = ARG_codeBlock4;
int argCount = ARG_int3;
- if (LIKELY(argCount == newCodeBlock->numParameters)) {
- VoidPtrPairValue pair = {{ newCodeBlock, CallFrame::create(callFrame->registers() + registerOffset) }};
- return pair.i;
- }
+ ASSERT(argCount != newCodeBlock->m_numParameters);
+
+ CallFrame* oldCallFrame = callFrame->callerFrame();
- if (argCount > newCodeBlock->numParameters) {
- size_t numParameters = newCodeBlock->numParameters;
- Register* r = callFrame->registers() + registerOffset + numParameters;
+ if (argCount > newCodeBlock->m_numParameters) {
+ size_t numParameters = newCodeBlock->m_numParameters;
+ Register* r = callFrame->registers() + numParameters;
Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
for (size_t i = 0; i < numParameters; ++i)
argv[i + argCount] = argv[i];
- VoidPtrPairValue pair = {{ newCodeBlock, CallFrame::create(r) }};
- return pair.i;
- }
+ callFrame = CallFrame::create(r);
+ callFrame->setCallerFrame(oldCallFrame);
+ } else {
+ size_t omittedArgCount = newCodeBlock->m_numParameters - argCount;
+ Register* r = callFrame->registers() + omittedArgCount;
+ Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
+ if (!ARG_registerFile->grow(newEnd)) {
+ // Rewind to the previous call frame because op_call already optimistically
+ // moved the call frame forward.
+ ARG_setCallFrame(oldCallFrame);
+ throwStackOverflowError(oldCallFrame, ARG_globalData, ARG_returnAddress2, STUB_RETURN_ADDRESS);
+ RETURN_PAIR(0, 0);
+ }
- size_t omittedArgCount = newCodeBlock->numParameters - argCount;
- Register* r = callFrame->registers() + registerOffset + omittedArgCount;
- Register* newEnd = r + newCodeBlock->numCalleeRegisters;
- if (!ARG_registerFile->grow(newEnd)) {
- ARG_globalData->exception = createStackOverflowError(callFrame);
- VM_THROW_EXCEPTION_2();
- }
+ Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
+ for (size_t i = 0; i < omittedArgCount; ++i)
+ argv[i] = jsUndefined();
- Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
- for (size_t i = 0; i < omittedArgCount; ++i)
- argv[i] = jsUndefined();
+ callFrame = CallFrame::create(r);
+ callFrame->setCallerFrame(oldCallFrame);
+ }
- VoidPtrPairValue pair = {{ newCodeBlock, CallFrame::create(r) }};
- return pair.i;
+ RETURN_PAIR(newCodeBlock, callFrame);
}
-void* Machine::cti_vm_lazyLinkCall(CTI_ARGS)
+void* Interpreter::cti_vm_dontLazyLinkCall(STUB_ARGS)
{
- CTI_STACK_HACK();
-
- Machine* machine = ARG_globalData->machine;
- CallFrame* callFrame = CallFrame::create(ARG_callFrame);
+ BEGIN_STUB_FUNCTION();
JSFunction* callee = asFunction(ARG_src1);
- CodeBlock* codeBlock = &callee->m_body->byteCode(callee->m_scopeChain.node());
- if (!codeBlock->ctiCode)
- CTI::compile(machine, callFrame, codeBlock);
+ CodeBlock* codeBlock = &callee->body()->bytecode(callee->m_scopeChain.node());
+ if (!codeBlock->jitCode())
+ JIT::compile(ARG_globalData, codeBlock);
- CTI::linkCall(callee, codeBlock, codeBlock->ctiCode, ARG_linkInfo2, ARG_int3);
+ ctiPatchCallByReturnAddress(ARG_returnAddress2, ARG_globalData->interpreter->m_ctiVirtualCallLink);
- return codeBlock->ctiCode;
+ return codeBlock->jitCode();
}
-void* Machine::cti_vm_compile(CTI_ARGS)
+void* Interpreter::cti_vm_lazyLinkCall(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
+
+ JSFunction* callee = asFunction(ARG_src1);
+ CodeBlock* codeBlock = &callee->body()->bytecode(callee->m_scopeChain.node());
+ if (!codeBlock->jitCode())
+ JIT::compile(ARG_globalData, codeBlock);
+
+ CallLinkInfo* callLinkInfo = &ARG_callFrame->callerFrame()->codeBlock()->getCallLinkInfo(ARG_returnAddress2);
+ JIT::linkCall(callee, codeBlock, codeBlock->jitCode(), callLinkInfo, ARG_int3);
- CodeBlock* codeBlock = ARG_callFrame->codeBlock();
- if (!codeBlock->ctiCode)
- CTI::compile(ARG_globalData->machine, ARG_callFrame, codeBlock);
- return codeBlock->ctiCode;
+ return codeBlock->jitCode();
}
-JSObject* Machine::cti_op_push_activation(CTI_ARGS)
+JSObject* Interpreter::cti_op_push_activation(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSActivation* activation = new (ARG_globalData) JSActivation(ARG_callFrame, static_cast<FunctionBodyNode*>(ARG_callFrame->codeBlock()->ownerNode));
+ JSActivation* activation = new (ARG_globalData) JSActivation(ARG_callFrame, static_cast<FunctionBodyNode*>(ARG_callFrame->codeBlock()->ownerNode()));
ARG_callFrame->setScopeChain(ARG_callFrame->scopeChain()->copy()->push(activation));
return activation;
}
-JSValue* Machine::cti_op_call_NotJSFunction(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_call_NotJSFunction(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* funcVal = ARG_src1;
+ JSValuePtr funcVal = ARG_src1;
CallData callData;
- CallType callType = funcVal->getCallData(callData);
+ CallType callType = funcVal.getCallData(callData);
ASSERT(callType != CallTypeJS);
@@ -4809,98 +4873,107 @@ JSValue* Machine::cti_op_call_NotJSFunction(CTI_ARGS)
CallFrame* previousCallFrame = ARG_callFrame;
CallFrame* callFrame = CallFrame::create(previousCallFrame->registers() + registerOffset);
- callFrame->init(0, ARG_instr4 + 1, previousCallFrame->scopeChain(), previousCallFrame, 0, argCount, 0);
+ callFrame->init(0, static_cast<Instruction*>(STUB_RETURN_ADDRESS), previousCallFrame->scopeChain(), previousCallFrame, 0, argCount, 0);
ARG_setCallFrame(callFrame);
Register* argv = ARG_callFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
ArgList argList(argv + 1, argCount - 1);
- JSValue* returnValue;
+ JSValuePtr returnValue;
{
SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
- returnValue = callData.native.function(callFrame, asObject(funcVal), argv[0].jsValue(callFrame), argList);
+
+ // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
+ JSValuePtr thisValue = argv[0].jsValue(callFrame);
+ if (thisValue == jsNull())
+ thisValue = callFrame->globalThisValue();
+
+ returnValue = callData.native.function(callFrame, asObject(funcVal), thisValue, argList);
}
ARG_setCallFrame(previousCallFrame);
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
- return returnValue;
+ return JSValuePtr::encode(returnValue);
}
ASSERT(callType == CallTypeNone);
- ARG_globalData->exception = createNotAFunctionError(ARG_callFrame, funcVal, ARG_instr4, ARG_callFrame->codeBlock());
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createNotAFunctionError(ARG_callFrame, funcVal, vPCIndex, codeBlock);
VM_THROW_EXCEPTION();
}
-void Machine::cti_op_create_arguments(CTI_ARGS)
+void Interpreter::cti_op_create_arguments(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
Arguments* arguments = new (ARG_globalData) Arguments(ARG_callFrame);
ARG_callFrame->setCalleeArguments(arguments);
ARG_callFrame[RegisterFile::ArgumentsRegister] = arguments;
}
-void Machine::cti_op_create_arguments_no_params(CTI_ARGS)
+void Interpreter::cti_op_create_arguments_no_params(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
Arguments* arguments = new (ARG_globalData) Arguments(ARG_callFrame, Arguments::NoParameters);
ARG_callFrame->setCalleeArguments(arguments);
ARG_callFrame[RegisterFile::ArgumentsRegister] = arguments;
}
-void Machine::cti_op_tear_off_activation(CTI_ARGS)
+void Interpreter::cti_op_tear_off_activation(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain);
+ ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain());
asActivation(ARG_src1)->copyRegisters(ARG_callFrame->optionalCalleeArguments());
}
-void Machine::cti_op_tear_off_arguments(CTI_ARGS)
+void Interpreter::cti_op_tear_off_arguments(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- ASSERT(ARG_callFrame->codeBlock()->usesArguments && !ARG_callFrame->codeBlock()->needsFullScopeChain);
+ ASSERT(ARG_callFrame->codeBlock()->usesArguments() && !ARG_callFrame->codeBlock()->needsFullScopeChain());
ARG_callFrame->optionalCalleeArguments()->copyRegisters();
}
-void Machine::cti_op_profile_will_call(CTI_ARGS)
+void Interpreter::cti_op_profile_will_call(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
ASSERT(*ARG_profilerReference);
(*ARG_profilerReference)->willExecute(ARG_callFrame, ARG_src1);
}
-void Machine::cti_op_profile_did_call(CTI_ARGS)
+void Interpreter::cti_op_profile_did_call(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
ASSERT(*ARG_profilerReference);
(*ARG_profilerReference)->didExecute(ARG_callFrame, ARG_src1);
}
-void Machine::cti_op_ret_scopeChain(CTI_ARGS)
+void Interpreter::cti_op_ret_scopeChain(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain);
+ ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain());
ARG_callFrame->scopeChain()->deref();
}
-JSObject* Machine::cti_op_new_array(CTI_ARGS)
+JSObject* Interpreter::cti_op_new_array(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- ArgList argList(ARG_registers1, ARG_int2);
+ ArgList argList(&ARG_callFrame->registers()[ARG_int1], ARG_int2);
return constructArray(ARG_callFrame, argList);
}
-JSValue* Machine::cti_op_resolve(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_resolve(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
ScopeChainNode* scopeChain = callFrame->scopeChain();
@@ -4914,167 +4987,140 @@ JSValue* Machine::cti_op_resolve(CTI_ARGS)
JSObject* o = *iter;
PropertySlot slot(o);
if (o->getPropertySlot(callFrame, ident, slot)) {
- JSValue* result = slot.getValue(callFrame, ident);
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
} while (++iter != end);
CodeBlock* codeBlock = callFrame->codeBlock();
- ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(CTI_RETURN_ADDRESS));
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
- ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, codeBlock->instructions.begin() + vPCIndex, codeBlock);
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
VM_THROW_EXCEPTION();
}
-JSObject* Machine::cti_op_construct_JSConstructFast(CTI_ARGS)
+JSObject* Interpreter::cti_op_construct_JSConstruct(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
#ifndef NDEBUG
ConstructData constructData;
ASSERT(asFunction(ARG_src1)->getConstructData(constructData) == ConstructTypeJS);
#endif
- StructureID* structure;
- if (ARG_src2->isObject())
- structure = asObject(ARG_src2)->inheritorID();
+ Structure* structure;
+ if (ARG_src4.isObject())
+ structure = asObject(ARG_src4)->inheritorID();
else
structure = asFunction(ARG_src1)->m_scopeChain.node()->globalObject()->emptyObjectStructure();
return new (ARG_globalData) JSObject(structure);
}
-VoidPtrPair Machine::cti_op_construct_JSConstruct(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_construct_NotJSConstruct(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- JSFunction* constructor = asFunction(ARG_src1);
- int registerOffset = ARG_int2;
+ JSValuePtr constrVal = ARG_src1;
int argCount = ARG_int3;
- JSValue* constrProtoVal = ARG_src5;
- int firstArg = ARG_int6;
+ int thisRegister = ARG_int5;
-#ifndef NDEBUG
ConstructData constructData;
- ASSERT(constructor->getConstructData(constructData) == ConstructTypeJS);
-#endif
-
- ScopeChainNode* callDataScopeChain = constructor->m_scopeChain.node();
- FunctionBodyNode* functionBodyNode = constructor->m_body.get();
- CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
-
- StructureID* structure;
- if (constrProtoVal->isObject())
- structure = asObject(constrProtoVal)->inheritorID();
- else
- structure = callDataScopeChain->globalObject()->emptyObjectStructure();
- JSObject* newObject = new (ARG_globalData) JSObject(structure);
- callFrame[firstArg] = newObject; // "this" value
-
- if (LIKELY(argCount == newCodeBlock->numParameters)) {
- VoidPtrPairValue pair = {{ newCodeBlock, CallFrame::create(callFrame->registers() + registerOffset) }};
- return pair.i;
- }
-
- if (argCount > newCodeBlock->numParameters) {
- size_t numParameters = newCodeBlock->numParameters;
- Register* r = callFrame->registers() + registerOffset + numParameters;
-
- Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
- for (size_t i = 0; i < numParameters; ++i)
- argv[i + argCount] = argv[i];
-
- VoidPtrPairValue pair = {{ newCodeBlock, CallFrame::create(r) }};
- return pair.i;
- }
-
- size_t omittedArgCount = newCodeBlock->numParameters - argCount;
- Register* r = callFrame->registers() + registerOffset + omittedArgCount;
- Register* newEnd = r + newCodeBlock->numCalleeRegisters;
- if (!ARG_registerFile->grow(newEnd)) {
- ARG_globalData->exception = createStackOverflowError(callFrame);
- VM_THROW_EXCEPTION_2();
- }
-
- Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
- for (size_t i = 0; i < omittedArgCount; ++i)
- argv[i] = jsUndefined();
-
- VoidPtrPairValue pair = {{ newCodeBlock, CallFrame::create(r) }};
- return pair.i;
-}
-
-JSValue* Machine::cti_op_construct_NotJSConstruct(CTI_ARGS)
-{
- CTI_STACK_HACK();
-
- CallFrame* callFrame = ARG_callFrame;
-
- JSValue* constrVal = ARG_src1;
- int argCount = ARG_int3;
- int firstArg = ARG_int6;
-
- ConstructData constructData;
- ConstructType constructType = constrVal->getConstructData(constructData);
+ ConstructType constructType = constrVal.getConstructData(constructData);
if (constructType == ConstructTypeHost) {
- ArgList argList(callFrame->registers() + firstArg + 1, argCount - 1);
+ ArgList argList(callFrame->registers() + thisRegister + 1, argCount - 1);
- JSValue* returnValue;
+ JSValuePtr returnValue;
{
SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
returnValue = constructData.native.function(callFrame, asObject(constrVal), argList);
}
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
- return returnValue;
+ return JSValuePtr::encode(returnValue);
}
ASSERT(constructType == ConstructTypeNone);
- ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, ARG_instr4, callFrame->codeBlock());
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, vPCIndex, codeBlock);
VM_THROW_EXCEPTION();
}
-JSValue* Machine::cti_op_get_by_val(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_val(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- Machine* machine = ARG_globalData->machine;
+ Interpreter* interpreter = ARG_globalData->interpreter;
- JSValue* baseValue = ARG_src1;
- JSValue* subscript = ARG_src2;
+ JSValuePtr baseValue = ARG_src1;
+ JSValuePtr subscript = ARG_src2;
- JSValue* result;
- unsigned i;
+ JSValuePtr result;
- bool isUInt32 = JSImmediate::getUInt32(subscript, i);
- if (LIKELY(isUInt32)) {
- if (machine->isJSArray(baseValue)) {
+ if (LIKELY(subscript.isUInt32Fast())) {
+ uint32_t i = subscript.getUInt32Fast();
+ if (interpreter->isJSArray(baseValue)) {
JSArray* jsArray = asArray(baseValue);
if (jsArray->canGetIndex(i))
result = jsArray->getIndex(i);
else
result = jsArray->JSArray::get(callFrame, i);
- } else if (machine->isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
+ } else if (interpreter->isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
result = asString(baseValue)->getIndex(ARG_globalData, i);
- else
- result = baseValue->get(callFrame, i);
+ else if (interpreter->isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_val_byte_array));
+ return JSValuePtr::encode(asByteArray(baseValue)->getIndex(callFrame, i));
+ } else
+ result = baseValue.get(callFrame, i);
} else {
- Identifier property(callFrame, subscript->toString(callFrame));
- result = baseValue->get(callFrame, property);
+ Identifier property(callFrame, subscript.toString(callFrame));
+ result = baseValue.get(callFrame, property);
}
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-VoidPtrPair Machine::cti_op_resolve_func(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_get_by_val_byte_array(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ Interpreter* interpreter = ARG_globalData->interpreter;
+
+ JSValuePtr baseValue = ARG_src1;
+ JSValuePtr subscript = ARG_src2;
+
+ JSValuePtr result;
+
+ if (LIKELY(subscript.isUInt32Fast())) {
+ uint32_t i = subscript.getUInt32Fast();
+ if (interpreter->isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+ return JSValuePtr::encode(asByteArray(baseValue)->getIndex(callFrame, i));
+ }
+
+ result = baseValue.get(callFrame, i);
+ if (!interpreter->isJSByteArray(baseValue))
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_val));
+ } else {
+ Identifier property(callFrame, subscript.toString(callFrame));
+ result = baseValue.get(callFrame, property);
+ }
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+VoidPtrPair Interpreter::cti_op_resolve_func(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
ScopeChainNode* scopeChain = callFrame->scopeChain();
@@ -5100,149 +5146,206 @@ VoidPtrPair Machine::cti_op_resolve_func(CTI_ARGS)
// that in host objects you always get a valid object for this.
// We also handle wrapper substitution for the global object at the same time.
JSObject* thisObj = base->toThisObject(callFrame);
- JSValue* result = slot.getValue(callFrame, ident);
- VM_CHECK_EXCEPTION_AT_END();
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ CHECK_FOR_EXCEPTION_AT_END();
- VoidPtrPairValue pair = {{ thisObj, asPointer(result) }};
- return pair.i;
+ RETURN_PAIR(thisObj, JSValuePtr::encode(result));
}
++iter;
} while (iter != end);
CodeBlock* codeBlock = callFrame->codeBlock();
- ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(CTI_RETURN_ADDRESS));
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
- ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, codeBlock->instructions.begin() + vPCIndex, codeBlock);
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
VM_THROW_EXCEPTION_2();
}
-JSValue* Machine::cti_op_sub(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_sub(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
double left;
double right;
- if (fastIsNumber(src1, left) && fastIsNumber(src2, right))
- return jsNumber(ARG_globalData, left - right);
+ if (src1.getNumber(left) && src2.getNumber(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left - right));
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, src1->toNumber(callFrame) - src2->toNumber(callFrame));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toNumber(callFrame) - src2.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-void Machine::cti_op_put_by_val(CTI_ARGS)
+void Interpreter::cti_op_put_by_val(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- Machine* machine = ARG_globalData->machine;
-
- JSValue* baseValue = ARG_src1;
- JSValue* subscript = ARG_src2;
- JSValue* value = ARG_src3;
+ Interpreter* interpreter = ARG_globalData->interpreter;
- unsigned i;
+ JSValuePtr baseValue = ARG_src1;
+ JSValuePtr subscript = ARG_src2;
+ JSValuePtr value = ARG_src3;
- bool isUInt32 = JSImmediate::getUInt32(subscript, i);
- if (LIKELY(isUInt32)) {
- if (machine->isJSArray(baseValue)) {
+ if (LIKELY(subscript.isUInt32Fast())) {
+ uint32_t i = subscript.getUInt32Fast();
+ if (interpreter->isJSArray(baseValue)) {
JSArray* jsArray = asArray(baseValue);
if (jsArray->canSetIndex(i))
jsArray->setIndex(i, value);
else
jsArray->JSArray::put(callFrame, i, value);
+ } else if (interpreter->isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ JSByteArray* jsByteArray = asByteArray(baseValue);
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_val_byte_array));
+ // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+ if (value.isInt32Fast()) {
+ jsByteArray->setIndex(i, value.getInt32Fast());
+ return;
+ } else {
+ double dValue = 0;
+ if (value.getNumber(dValue)) {
+ jsByteArray->setIndex(i, dValue);
+ return;
+ }
+ }
+
+ baseValue.put(callFrame, i, value);
} else
- baseValue->put(callFrame, i, value);
+ baseValue.put(callFrame, i, value);
} else {
- Identifier property(callFrame, subscript->toString(callFrame));
+ Identifier property(callFrame, subscript.toString(callFrame));
if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
PutPropertySlot slot;
- baseValue->put(callFrame, property, value, slot);
+ baseValue.put(callFrame, property, value, slot);
}
}
- VM_CHECK_EXCEPTION_AT_END();
+ CHECK_FOR_EXCEPTION_AT_END();
}
-void Machine::cti_op_put_by_val_array(CTI_ARGS)
+void Interpreter::cti_op_put_by_val_array(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- JSValue* baseValue = ARG_src1;
+ JSValuePtr baseValue = ARG_src1;
int i = ARG_int2;
- JSValue* value = ARG_src3;
+ JSValuePtr value = ARG_src3;
- ASSERT(ARG_globalData->machine->isJSArray(baseValue));
+ ASSERT(ARG_globalData->interpreter->isJSArray(baseValue));
if (LIKELY(i >= 0))
asArray(baseValue)->JSArray::put(callFrame, i, value);
else {
- Identifier property(callFrame, JSImmediate::from(i)->toString(callFrame));
+ // This should work since we're re-boxing an immediate unboxed in JIT code.
+ ASSERT(JSValuePtr::makeInt32Fast(i));
+ Identifier property(callFrame, JSValuePtr::makeInt32Fast(i).toString(callFrame));
// FIXME: can toString throw an exception here?
if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
PutPropertySlot slot;
- baseValue->put(callFrame, property, value, slot);
+ baseValue.put(callFrame, property, value, slot);
}
}
- VM_CHECK_EXCEPTION_AT_END();
+ CHECK_FOR_EXCEPTION_AT_END();
}
-JSValue* Machine::cti_op_lesseq(CTI_ARGS)
+void Interpreter::cti_op_put_by_val_byte_array(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ Interpreter* interpreter = ARG_globalData->interpreter;
+
+ JSValuePtr baseValue = ARG_src1;
+ JSValuePtr subscript = ARG_src2;
+ JSValuePtr value = ARG_src3;
+
+ if (LIKELY(subscript.isUInt32Fast())) {
+ uint32_t i = subscript.getUInt32Fast();
+ if (interpreter->isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ JSByteArray* jsByteArray = asByteArray(baseValue);
+
+ // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+ if (value.isInt32Fast()) {
+ jsByteArray->setIndex(i, value.getInt32Fast());
+ return;
+ } else {
+ double dValue = 0;
+ if (value.getNumber(dValue)) {
+ jsByteArray->setIndex(i, dValue);
+ return;
+ }
+ }
+ }
+
+ if (!interpreter->isJSByteArray(baseValue))
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_val));
+ baseValue.put(callFrame, i, value);
+ } else {
+ Identifier property(callFrame, subscript.toString(callFrame));
+ if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
+ PutPropertySlot slot;
+ baseValue.put(callFrame, property, value, slot);
+ }
+ }
+
+ CHECK_FOR_EXCEPTION_AT_END();
+}
+
+JSValueEncodedAsPointer* Interpreter::cti_op_lesseq(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsBoolean(jsLessEq(callFrame, ARG_src1, ARG_src2));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsBoolean(jsLessEq(callFrame, ARG_src1, ARG_src2));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-int Machine::cti_op_loop_if_true(CTI_ARGS)
+int Interpreter::cti_op_loop_if_true(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
+ JSValuePtr src1 = ARG_src1;
CallFrame* callFrame = ARG_callFrame;
- bool result = src1->toBoolean(callFrame);
- VM_CHECK_EXCEPTION_AT_END();
+ bool result = src1.toBoolean(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
return result;
}
-JSValue* Machine::cti_op_negate(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_negate(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src = ARG_src1;
+ JSValuePtr src = ARG_src1;
double v;
- if (fastIsNumber(src, v))
- return jsNumber(ARG_globalData, -v);
+ if (src.getNumber(v))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, -v));
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, -src->toNumber(callFrame));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, -src.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_resolve_base(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_resolve_base(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- return inlineResolveBase(ARG_callFrame, *ARG_id1, ARG_callFrame->scopeChain());
+ return JSValuePtr::encode(inlineResolveBase(ARG_callFrame, *ARG_id1, ARG_callFrame->scopeChain()));
}
-JSValue* Machine::cti_op_resolve_skip(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_resolve_skip(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
ScopeChainNode* scopeChain = callFrame->scopeChain();
@@ -5261,225 +5364,225 @@ JSValue* Machine::cti_op_resolve_skip(CTI_ARGS)
JSObject* o = *iter;
PropertySlot slot(o);
if (o->getPropertySlot(callFrame, ident, slot)) {
- JSValue* result = slot.getValue(callFrame, ident);
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
} while (++iter != end);
CodeBlock* codeBlock = callFrame->codeBlock();
- ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(CTI_RETURN_ADDRESS));
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
- ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, codeBlock->instructions.begin() + vPCIndex, codeBlock);
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
VM_THROW_EXCEPTION();
}
-JSValue* Machine::cti_op_resolve_global(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_resolve_global(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
JSGlobalObject* globalObject = asGlobalObject(ARG_src1);
Identifier& ident = *ARG_id2;
- Instruction* vPC = ARG_instr3;
+ unsigned globalResolveInfoIndex = ARG_int3;
ASSERT(globalObject->isGlobalObject());
PropertySlot slot(globalObject);
if (globalObject->getPropertySlot(callFrame, ident, slot)) {
- JSValue* result = slot.getValue(callFrame, ident);
- if (slot.isCacheable()) {
- if (vPC[4].u.structureID)
- vPC[4].u.structureID->deref();
- globalObject->structureID()->ref();
- vPC[4] = globalObject->structureID();
- vPC[5] = slot.cachedOffset();
- return result;
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ if (slot.isCacheable() && !globalObject->structure()->isDictionary()) {
+ GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex);
+ if (globalResolveInfo.structure)
+ globalResolveInfo.structure->deref();
+ globalObject->structure()->ref();
+ globalResolveInfo.structure = globalObject->structure();
+ globalResolveInfo.offset = slot.cachedOffset();
+ return JSValuePtr::encode(result);
}
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-
- ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPC, callFrame->codeBlock());
+
+ unsigned vPCIndex = callFrame->codeBlock()->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, callFrame->codeBlock());
VM_THROW_EXCEPTION();
}
-JSValue* Machine::cti_op_div(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_div(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
double left;
double right;
- if (fastIsNumber(src1, left) && fastIsNumber(src2, right))
- return jsNumber(ARG_globalData, left / right);
+ if (src1.getNumber(left) && src2.getNumber(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left / right));
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, src1->toNumber(callFrame) / src2->toNumber(callFrame));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toNumber(callFrame) / src2.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_pre_dec(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_pre_dec(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* v = ARG_src1;
+ JSValuePtr v = ARG_src1;
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, v->toNumber(callFrame) - 1);
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, v.toNumber(callFrame) - 1);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-int Machine::cti_op_jless(CTI_ARGS)
+int Interpreter::cti_op_jless(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
CallFrame* callFrame = ARG_callFrame;
bool result = jsLess(callFrame, src1, src2);
- VM_CHECK_EXCEPTION_AT_END();
+ CHECK_FOR_EXCEPTION_AT_END();
return result;
}
-JSValue* Machine::cti_op_not(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_not(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src = ARG_src1;
+ JSValuePtr src = ARG_src1;
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsBoolean(!src->toBoolean(callFrame));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsBoolean(!src.toBoolean(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-int SFX_CALL Machine::cti_op_jtrue(CTI_ARGS)
+int Interpreter::cti_op_jtrue(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
+ JSValuePtr src1 = ARG_src1;
CallFrame* callFrame = ARG_callFrame;
- bool result = src1->toBoolean(callFrame);
- VM_CHECK_EXCEPTION_AT_END();
+ bool result = src1.toBoolean(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
return result;
}
-VoidPtrPair Machine::cti_op_post_inc(CTI_ARGS)
+VoidPtrPair Interpreter::cti_op_post_inc(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* v = ARG_src1;
+ JSValuePtr v = ARG_src1;
CallFrame* callFrame = ARG_callFrame;
- JSValue* number = v->toJSNumber(callFrame);
- VM_CHECK_EXCEPTION_AT_END();
+ JSValuePtr number = v.toJSNumber(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
- VoidPtrPairValue pair = {{ asPointer(number), asPointer(jsNumber(ARG_globalData, number->uncheckedGetNumber() + 1)) }};
- return pair.i;
+ RETURN_PAIR(JSValuePtr::encode(number), JSValuePtr::encode(jsNumber(ARG_globalData, number.uncheckedGetNumber() + 1)));
}
-JSValue* Machine::cti_op_eq(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_eq(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
CallFrame* callFrame = ARG_callFrame;
- ASSERT(!JSImmediate::areBothImmediateNumbers(src1, src2));
- JSValue* result = jsBoolean(equalSlowCaseInline(callFrame, src1, src2));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ ASSERT(!JSValuePtr::areBothInt32Fast(src1, src2));
+ JSValuePtr result = jsBoolean(JSValuePtr::equalSlowCaseInline(callFrame, src1, src2));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_lshift(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_lshift(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* val = ARG_src1;
- JSValue* shift = ARG_src2;
+ JSValuePtr val = ARG_src1;
+ JSValuePtr shift = ARG_src2;
int32_t left;
uint32_t right;
- if (JSImmediate::areBothImmediateNumbers(val, shift))
- return jsNumber(ARG_globalData, JSImmediate::getTruncatedInt32(val) << (JSImmediate::getTruncatedUInt32(shift) & 0x1f));
- if (fastToInt32(val, left) && fastToUInt32(shift, right))
- return jsNumber(ARG_globalData, left << (right & 0x1f));
+ if (JSValuePtr::areBothInt32Fast(val, shift))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, val.getInt32Fast() << (shift.getInt32Fast() & 0x1f)));
+ if (val.numberToInt32(left) && shift.numberToUInt32(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left << (right & 0x1f)));
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, (val->toInt32(callFrame)) << (shift->toUInt32(callFrame) & 0x1f));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_bitand(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_bitand(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
int32_t left;
int32_t right;
- if (fastToInt32(src1, left) && fastToInt32(src2, right))
- return jsNumber(ARG_globalData, left & right);
+ if (src1.numberToInt32(left) && src2.numberToInt32(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left & right));
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, src1->toInt32(callFrame) & src2->toInt32(callFrame));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toInt32(callFrame) & src2.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_rshift(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_rshift(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* val = ARG_src1;
- JSValue* shift = ARG_src2;
+ JSValuePtr val = ARG_src1;
+ JSValuePtr shift = ARG_src2;
int32_t left;
uint32_t right;
- if (JSImmediate::areBothImmediateNumbers(val, shift))
- return JSImmediate::rightShiftImmediateNumbers(val, shift);
- if (fastToInt32(val, left) && fastToUInt32(shift, right))
- return jsNumber(ARG_globalData, left >> (right & 0x1f));
+ if (JSFastMath::canDoFastRshift(val, shift))
+ return JSValuePtr::encode(JSFastMath::rightShiftImmediateNumbers(val, shift));
+ if (val.numberToInt32(left) && shift.numberToUInt32(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left >> (right & 0x1f)));
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, (val->toInt32(callFrame)) >> (shift->toUInt32(callFrame) & 0x1f));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_bitnot(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_bitnot(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src = ARG_src1;
+ JSValuePtr src = ARG_src1;
int value;
- if (fastToInt32(src, value))
- return jsNumber(ARG_globalData, ~value);
-
+ if (src.numberToInt32(value))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, ~value));
+
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, ~src->toInt32(callFrame));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, ~src.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-VoidPtrPair Machine::cti_op_resolve_with_base(CTI_ARGS)
+VoidPtrPair Interpreter::cti_op_resolve_with_base(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
ScopeChainNode* scopeChain = callFrame->scopeChain();
@@ -5497,348 +5600,337 @@ VoidPtrPair Machine::cti_op_resolve_with_base(CTI_ARGS)
base = *iter;
PropertySlot slot(base);
if (base->getPropertySlot(callFrame, ident, slot)) {
- JSValue* result = slot.getValue(callFrame, ident);
- VM_CHECK_EXCEPTION_AT_END();
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ CHECK_FOR_EXCEPTION_AT_END();
- VoidPtrPairValue pair = {{ base, asPointer(result) }};
- return pair.i;
+ RETURN_PAIR(base, JSValuePtr::encode(result));
}
++iter;
} while (iter != end);
CodeBlock* codeBlock = callFrame->codeBlock();
- ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(CTI_RETURN_ADDRESS));
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
- ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, codeBlock->instructions.begin() + vPCIndex, codeBlock);
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
VM_THROW_EXCEPTION_2();
}
-JSObject* Machine::cti_op_new_func_exp(CTI_ARGS)
+JSObject* Interpreter::cti_op_new_func_exp(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
return ARG_funcexp1->makeFunction(ARG_callFrame, ARG_callFrame->scopeChain());
}
-JSValue* Machine::cti_op_mod(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_mod(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* dividendValue = ARG_src1;
- JSValue* divisorValue = ARG_src2;
+ JSValuePtr dividendValue = ARG_src1;
+ JSValuePtr divisorValue = ARG_src2;
CallFrame* callFrame = ARG_callFrame;
- double d = dividendValue->toNumber(callFrame);
- JSValue* result = jsNumber(ARG_globalData, fmod(d, divisorValue->toNumber(callFrame)));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ double d = dividendValue.toNumber(callFrame);
+ JSValuePtr result = jsNumber(ARG_globalData, fmod(d, divisorValue.toNumber(callFrame)));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_less(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_less(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsBoolean(jsLess(callFrame, ARG_src1, ARG_src2));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsBoolean(jsLess(callFrame, ARG_src1, ARG_src2));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_neq(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_neq(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
- ASSERT(!JSImmediate::areBothImmediateNumbers(src1, src2));
+ ASSERT(!JSValuePtr::areBothInt32Fast(src1, src2));
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsBoolean(!equalSlowCaseInline(callFrame, src1, src2));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsBoolean(!JSValuePtr::equalSlowCaseInline(callFrame, src1, src2));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-VoidPtrPair Machine::cti_op_post_dec(CTI_ARGS)
+VoidPtrPair Interpreter::cti_op_post_dec(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* v = ARG_src1;
+ JSValuePtr v = ARG_src1;
CallFrame* callFrame = ARG_callFrame;
- JSValue* number = v->toJSNumber(callFrame);
- VM_CHECK_EXCEPTION_AT_END();
+ JSValuePtr number = v.toJSNumber(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
- VoidPtrPairValue pair = {{ asPointer(number), asPointer(jsNumber(ARG_globalData, number->uncheckedGetNumber() - 1)) }};
- return pair.i;
+ RETURN_PAIR(JSValuePtr::encode(number), JSValuePtr::encode(jsNumber(ARG_globalData, number.uncheckedGetNumber() - 1)));
}
-JSValue* Machine::cti_op_urshift(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_urshift(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* val = ARG_src1;
- JSValue* shift = ARG_src2;
+ JSValuePtr val = ARG_src1;
+ JSValuePtr shift = ARG_src2;
CallFrame* callFrame = ARG_callFrame;
- if (JSImmediate::areBothImmediateNumbers(val, shift) && !JSImmediate::isNegative(val))
- return JSImmediate::rightShiftImmediateNumbers(val, shift);
+ if (JSFastMath::canDoFastUrshift(val, shift))
+ return JSValuePtr::encode(JSFastMath::rightShiftImmediateNumbers(val, shift));
else {
- JSValue* result = jsNumber(ARG_globalData, (val->toUInt32(callFrame)) >> (shift->toUInt32(callFrame) & 0x1f));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
}
-JSValue* Machine::cti_op_bitxor(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_bitxor(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, src1->toInt32(callFrame) ^ src2->toInt32(callFrame));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSObject* Machine::cti_op_new_regexp(CTI_ARGS)
+JSObject* Interpreter::cti_op_new_regexp(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
return new (ARG_globalData) RegExpObject(ARG_callFrame->lexicalGlobalObject()->regExpStructure(), ARG_regexp1);
}
-JSValue* Machine::cti_op_bitor(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_bitor(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = jsNumber(ARG_globalData, src1->toInt32(callFrame) | src2->toInt32(callFrame));
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toInt32(callFrame) | src2.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_call_eval(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_call_eval(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
RegisterFile* registerFile = ARG_registerFile;
- CodeBlock* codeBlock = callFrame->codeBlock();
- ScopeChainNode* scopeChain = callFrame->scopeChain();
- Machine* machine = ARG_globalData->machine;
+ Interpreter* interpreter = ARG_globalData->interpreter;
- JSValue* funcVal = ARG_src1;
+ JSValuePtr funcVal = ARG_src1;
int registerOffset = ARG_int2;
int argCount = ARG_int3;
- JSValue* baseVal = ARG_src5;
- if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
- JSObject* thisObject = asObject(callFrame[codeBlock->thisRegister].jsValue(callFrame));
- JSValue* exceptionValue = noValue();
- JSValue* result = machine->callEval(callFrame, thisObject, scopeChain, registerFile, registerOffset - RegisterFile::CallFrameHeaderSize - argCount, argCount, exceptionValue);
+ Register* newCallFrame = callFrame->registers() + registerOffset;
+ Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
+ JSValuePtr thisValue = argv[0].jsValue(callFrame);
+ JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
+
+ if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
+ JSValuePtr exceptionValue = noValue();
+ JSValuePtr result = interpreter->callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
if (UNLIKELY(exceptionValue != noValue())) {
ARG_globalData->exception = exceptionValue;
VM_THROW_EXCEPTION_AT_END();
}
- return result;
+ return JSValuePtr::encode(result);
}
- return JSImmediate::impossibleValue();
+ return JSValuePtr::encode(jsImpossibleValue());
}
-JSValue* Machine::cti_op_throw(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_throw(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
- ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(CTI_RETURN_ADDRESS));
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
- JSValue* exceptionValue = ARG_src1;
+ JSValuePtr exceptionValue = ARG_src1;
ASSERT(exceptionValue);
- Instruction* handlerVPC = ARG_globalData->machine->throwException(callFrame, exceptionValue, codeBlock->instructions.begin() + vPCIndex, true);
+ HandlerInfo* handler = ARG_globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, true);
- if (!handlerVPC) {
+ if (!handler) {
*ARG_exception = exceptionValue;
- return JSImmediate::nullImmediate();
+ return JSValuePtr::encode(jsNull());
}
ARG_setCallFrame(callFrame);
- void* catchRoutine = callFrame->codeBlock()->nativeExceptionCodeForHandlerVPC(handlerVPC);
+ void* catchRoutine = handler->nativeCode;
ASSERT(catchRoutine);
- CTI_SET_RETURN_ADDRESS(catchRoutine);
- return exceptionValue;
+ STUB_SET_RETURN_ADDRESS(catchRoutine);
+ return JSValuePtr::encode(exceptionValue);
}
-JSPropertyNameIterator* Machine::cti_op_get_pnames(CTI_ARGS)
+JSPropertyNameIterator* Interpreter::cti_op_get_pnames(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
return JSPropertyNameIterator::create(ARG_callFrame, ARG_src1);
}
-JSValue* Machine::cti_op_next_pname(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_next_pname(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
JSPropertyNameIterator* it = ARG_pni1;
- JSValue* temp = it->next(ARG_callFrame);
+ JSValuePtr temp = it->next(ARG_callFrame);
if (!temp)
it->invalidate();
- return temp;
+ return JSValuePtr::encode(temp);
}
-void Machine::cti_op_push_scope(CTI_ARGS)
+JSObject* Interpreter::cti_op_push_scope(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSObject* o = ARG_src1->toObject(ARG_callFrame);
- VM_CHECK_EXCEPTION_VOID();
+ JSObject* o = ARG_src1.toObject(ARG_callFrame);
+ CHECK_FOR_EXCEPTION();
ARG_callFrame->setScopeChain(ARG_callFrame->scopeChain()->push(o));
+ return o;
}
-void Machine::cti_op_pop_scope(CTI_ARGS)
+void Interpreter::cti_op_pop_scope(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
ARG_callFrame->setScopeChain(ARG_callFrame->scopeChain()->pop());
}
-JSValue* Machine::cti_op_typeof(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_typeof(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- return jsTypeStringForValue(ARG_callFrame, ARG_src1);
+ return JSValuePtr::encode(jsTypeStringForValue(ARG_callFrame, ARG_src1));
}
-JSValue* Machine::cti_op_is_undefined(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_is_undefined(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* v = ARG_src1;
- return jsBoolean(JSImmediate::isImmediate(v) ? v->isUndefined() : v->asCell()->structureID()->typeInfo().masqueradesAsUndefined());
+ JSValuePtr v = ARG_src1;
+ return JSValuePtr::encode(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
}
-JSValue* Machine::cti_op_is_boolean(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_is_boolean(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- return jsBoolean(ARG_src1->isBoolean());
+ return JSValuePtr::encode(jsBoolean(ARG_src1.isBoolean()));
}
-JSValue* Machine::cti_op_is_number(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_is_number(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- return jsBoolean(ARG_src1->isNumber());
+ return JSValuePtr::encode(jsBoolean(ARG_src1.isNumber()));
}
-JSValue* Machine::cti_op_is_string(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_is_string(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- return jsBoolean(ARG_globalData->machine->isJSString(ARG_src1));
+ return JSValuePtr::encode(jsBoolean(ARG_globalData->interpreter->isJSString(ARG_src1)));
}
-JSValue* Machine::cti_op_is_object(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_is_object(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- return jsBoolean(jsIsObjectType(ARG_src1));
+ return JSValuePtr::encode(jsBoolean(jsIsObjectType(ARG_src1)));
}
-JSValue* Machine::cti_op_is_function(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_is_function(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- return jsBoolean(jsIsFunctionType(ARG_src1));
+ return JSValuePtr::encode(jsBoolean(jsIsFunctionType(ARG_src1)));
}
-JSValue* Machine::cti_op_stricteq(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_stricteq(STUB_ARGS)
{
- CTI_STACK_HACK();
-
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ BEGIN_STUB_FUNCTION();
- // handled inline as fast cases
- ASSERT(!JSImmediate::areBothImmediate(src1, src2));
- ASSERT(!(JSImmediate::isEitherImmediate(src1, src2) & (src1 != JSImmediate::zeroImmediate()) & (src2 != JSImmediate::zeroImmediate())));
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
- return jsBoolean(strictEqualSlowCaseInline(src1, src2));
+ return JSValuePtr::encode(jsBoolean(JSValuePtr::strictEqual(src1, src2)));
}
-JSValue* Machine::cti_op_nstricteq(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_nstricteq(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src1 = ARG_src1;
- JSValue* src2 = ARG_src2;
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
- // handled inline as fast cases
- ASSERT(!JSImmediate::areBothImmediate(src1, src2));
- ASSERT(!(JSImmediate::isEitherImmediate(src1, src2) & (src1 != JSImmediate::zeroImmediate()) & (src2 != JSImmediate::zeroImmediate())));
-
- return jsBoolean(!strictEqualSlowCaseInline(src1, src2));
+ return JSValuePtr::encode(jsBoolean(!JSValuePtr::strictEqual(src1, src2)));
}
-JSValue* Machine::cti_op_to_jsnumber(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_to_jsnumber(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* src = ARG_src1;
+ JSValuePtr src = ARG_src1;
CallFrame* callFrame = ARG_callFrame;
- JSValue* result = src->toJSNumber(callFrame);
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ JSValuePtr result = src.toJSNumber(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-JSValue* Machine::cti_op_in(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_in(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- JSValue* baseVal = ARG_src2;
+ JSValuePtr baseVal = ARG_src2;
- if (!baseVal->isObject()) {
+ if (!baseVal.isObject()) {
CallFrame* callFrame = ARG_callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
- ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(CTI_RETURN_ADDRESS));
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(CTI_RETURN_ADDRESS);
- ARG_globalData->exception = createInvalidParamError(callFrame, "in", baseVal, codeBlock->instructions.begin() + vPCIndex, codeBlock);
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createInvalidParamError(callFrame, "in", baseVal, vPCIndex, codeBlock);
VM_THROW_EXCEPTION();
}
- JSValue* propName = ARG_src1;
+ JSValuePtr propName = ARG_src1;
JSObject* baseObj = asObject(baseVal);
uint32_t i;
- if (propName->getUInt32(i))
- return jsBoolean(baseObj->hasProperty(callFrame, i));
+ if (propName.getUInt32(i))
+ return JSValuePtr::encode(jsBoolean(baseObj->hasProperty(callFrame, i)));
- Identifier property(callFrame, propName->toString(callFrame));
- VM_CHECK_EXCEPTION();
- return jsBoolean(baseObj->hasProperty(callFrame, property));
+ Identifier property(callFrame, propName.toString(callFrame));
+ CHECK_FOR_EXCEPTION();
+ return JSValuePtr::encode(jsBoolean(baseObj->hasProperty(callFrame, property)));
}
-JSObject* Machine::cti_op_push_new_scope(CTI_ARGS)
+JSObject* Interpreter::cti_op_push_new_scope(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
JSObject* scope = new (ARG_globalData) JSStaticScopeObject(ARG_callFrame, *ARG_id1, ARG_src2, DontDelete);
@@ -5847,9 +5939,9 @@ JSObject* Machine::cti_op_push_new_scope(CTI_ARGS)
return scope;
}
-void Machine::cti_op_jmp_scopes(CTI_ARGS)
+void Interpreter::cti_op_jmp_scopes(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
unsigned count = ARG_int1;
CallFrame* callFrame = ARG_callFrame;
@@ -5860,139 +5952,141 @@ void Machine::cti_op_jmp_scopes(CTI_ARGS)
callFrame->setScopeChain(tmp);
}
-void Machine::cti_op_put_by_index(CTI_ARGS)
+void Interpreter::cti_op_put_by_index(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
unsigned property = ARG_int2;
- ARG_src1->put(callFrame, property, ARG_src3);
+ ARG_src1.put(callFrame, property, ARG_src3);
}
-void* Machine::cti_op_switch_imm(CTI_ARGS)
+void* Interpreter::cti_op_switch_imm(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* scrutinee = ARG_src1;
+ JSValuePtr scrutinee = ARG_src1;
unsigned tableIndex = ARG_int2;
CallFrame* callFrame = ARG_callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
- if (JSImmediate::isNumber(scrutinee)) {
- int32_t value = JSImmediate::getTruncatedInt32(scrutinee);
- return codeBlock->immediateSwitchJumpTables[tableIndex].ctiForValue(value);
+ if (scrutinee.isInt32Fast())
+ return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.getInt32Fast());
+ else {
+ int32_t value;
+ if (scrutinee.numberToInt32(value))
+ return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(value);
+ else
+ return codeBlock->immediateSwitchJumpTable(tableIndex).ctiDefault;
}
-
- return codeBlock->immediateSwitchJumpTables[tableIndex].ctiDefault;
}
-void* Machine::cti_op_switch_char(CTI_ARGS)
+void* Interpreter::cti_op_switch_char(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* scrutinee = ARG_src1;
+ JSValuePtr scrutinee = ARG_src1;
unsigned tableIndex = ARG_int2;
CallFrame* callFrame = ARG_callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
- void* result = codeBlock->characterSwitchJumpTables[tableIndex].ctiDefault;
+ void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault;
- if (scrutinee->isString()) {
+ if (scrutinee.isString()) {
UString::Rep* value = asString(scrutinee)->value().rep();
if (value->size() == 1)
- result = codeBlock->characterSwitchJumpTables[tableIndex].ctiForValue(value->data()[0]);
+ result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->data()[0]);
}
return result;
}
-void* Machine::cti_op_switch_string(CTI_ARGS)
+void* Interpreter::cti_op_switch_string(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
- JSValue* scrutinee = ARG_src1;
+ JSValuePtr scrutinee = ARG_src1;
unsigned tableIndex = ARG_int2;
CallFrame* callFrame = ARG_callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
- void* result = codeBlock->stringSwitchJumpTables[tableIndex].ctiDefault;
+ void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault;
- if (scrutinee->isString()) {
+ if (scrutinee.isString()) {
UString::Rep* value = asString(scrutinee)->value().rep();
- result = codeBlock->stringSwitchJumpTables[tableIndex].ctiForValue(value);
+ result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value);
}
return result;
}
-JSValue* Machine::cti_op_del_by_val(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_op_del_by_val(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- JSValue* baseValue = ARG_src1;
- JSObject* baseObj = baseValue->toObject(callFrame); // may throw
+ JSValuePtr baseValue = ARG_src1;
+ JSObject* baseObj = baseValue.toObject(callFrame); // may throw
- JSValue* subscript = ARG_src2;
- JSValue* result;
+ JSValuePtr subscript = ARG_src2;
+ JSValuePtr result;
uint32_t i;
- if (subscript->getUInt32(i))
+ if (subscript.getUInt32(i))
result = jsBoolean(baseObj->deleteProperty(callFrame, i));
else {
- VM_CHECK_EXCEPTION();
- Identifier property(callFrame, subscript->toString(callFrame));
- VM_CHECK_EXCEPTION();
+ CHECK_FOR_EXCEPTION();
+ Identifier property(callFrame, subscript.toString(callFrame));
+ CHECK_FOR_EXCEPTION();
result = jsBoolean(baseObj->deleteProperty(callFrame, property));
}
- VM_CHECK_EXCEPTION_AT_END();
- return result;
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
}
-void Machine::cti_op_put_getter(CTI_ARGS)
+void Interpreter::cti_op_put_getter(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- ASSERT(ARG_src1->isObject());
+ ASSERT(ARG_src1.isObject());
JSObject* baseObj = asObject(ARG_src1);
- Identifier& ident = *ARG_id2;
- ASSERT(ARG_src3->isObject());
- baseObj->defineGetter(callFrame, ident, asObject(ARG_src3));
+ ASSERT(ARG_src3.isObject());
+ baseObj->defineGetter(callFrame, *ARG_id2, asObject(ARG_src3));
}
-void Machine::cti_op_put_setter(CTI_ARGS)
+void Interpreter::cti_op_put_setter(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
- ASSERT(ARG_src1->isObject());
+ ASSERT(ARG_src1.isObject());
JSObject* baseObj = asObject(ARG_src1);
- Identifier& ident = *ARG_id2;
- ASSERT(ARG_src3->isObject());
- baseObj->defineSetter(callFrame, ident, asObject(ARG_src3));
+ ASSERT(ARG_src3.isObject());
+ baseObj->defineSetter(callFrame, *ARG_id2, asObject(ARG_src3));
}
-JSObject* Machine::cti_op_new_error(CTI_ARGS)
+JSObject* Interpreter::cti_op_new_error(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
unsigned type = ARG_int1;
- JSValue* message = ARG_src2;
- unsigned lineNumber = ARG_int3;
+ JSValuePtr message = ARG_src2;
+ unsigned bytecodeOffset = ARG_int3;
- return Error::create(callFrame, static_cast<ErrorType>(type), message->toString(callFrame), lineNumber, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->sourceURL());
+ unsigned lineNumber = codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset);
+ return Error::create(callFrame, static_cast<ErrorType>(type), message.toString(callFrame), lineNumber, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
}
-void Machine::cti_op_debug(CTI_ARGS)
+void Interpreter::cti_op_debug(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
@@ -6000,47 +6094,47 @@ void Machine::cti_op_debug(CTI_ARGS)
int firstLine = ARG_int2;
int lastLine = ARG_int3;
- ARG_globalData->machine->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
+ ARG_globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
}
-JSValue* Machine::cti_vm_throw(CTI_ARGS)
+JSValueEncodedAsPointer* Interpreter::cti_vm_throw(STUB_ARGS)
{
- CTI_STACK_HACK();
+ BEGIN_STUB_FUNCTION();
CallFrame* callFrame = ARG_callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
+ JSGlobalData* globalData = ARG_globalData;
- ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(ARG_globalData->throwReturnAddress));
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(ARG_globalData->throwReturnAddress);
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, globalData->exceptionLocation);
- JSValue* exceptionValue = ARG_globalData->exception;
+ JSValuePtr exceptionValue = globalData->exception;
ASSERT(exceptionValue);
- ARG_globalData->exception = noValue();
+ globalData->exception = noValue();
- Instruction* handlerVPC = ARG_globalData->machine->throwException(callFrame, exceptionValue, codeBlock->instructions.begin() + vPCIndex, false);
+ HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, false);
- if (!handlerVPC) {
+ if (!handler) {
*ARG_exception = exceptionValue;
- return JSImmediate::nullImmediate();
+ return JSValuePtr::encode(jsNull());
}
ARG_setCallFrame(callFrame);
- void* catchRoutine = callFrame->codeBlock()->nativeExceptionCodeForHandlerVPC(handlerVPC);
+ void* catchRoutine = handler->nativeCode;
ASSERT(catchRoutine);
- CTI_SET_RETURN_ADDRESS(catchRoutine);
- return exceptionValue;
+ STUB_SET_RETURN_ADDRESS(catchRoutine);
+ return JSValuePtr::encode(exceptionValue);
}
-#undef CTI_RETURN_ADDRESS
-#undef CTI_SET_RETURN_ADDRESS
-#undef CTI_STACK_HACK
-#undef VM_CHECK_EXCEPTION
-#undef VM_CHECK_EXCEPTION_AT_END
-#undef VM_CHECK_EXCEPTION_VOID
+#undef STUB_RETURN_ADDRESS
+#undef STUB_SET_RETURN_ADDRESS
+#undef BEGIN_STUB_FUNCTION
+#undef CHECK_FOR_EXCEPTION
+#undef CHECK_FOR_EXCEPTION_AT_END
+#undef CHECK_FOR_EXCEPTION_VOID
#undef VM_THROW_EXCEPTION
#undef VM_THROW_EXCEPTION_2
#undef VM_THROW_EXCEPTION_AT_END
-#endif // ENABLE(CTI)
+#endif // ENABLE(JIT)
} // namespace JSC
diff --git a/JavaScriptCore/interpreter/Interpreter.h b/JavaScriptCore/interpreter/Interpreter.h
new file mode 100644
index 0000000..18c2185
--- /dev/null
+++ b/JavaScriptCore/interpreter/Interpreter.h
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Interpreter_h
+#define Interpreter_h
+
+#include "ArgList.h"
+#include "JSCell.h"
+#include "JSValue.h"
+#include "Opcode.h"
+#include "RegisterFile.h"
+#include <wtf/HashMap.h>
+
+#ifdef ANDROID_INSTRUMENT
+#include "TimeCounter.h"
+#endif
+
+namespace JSC {
+
+ class CodeBlock;
+ class EvalNode;
+ class FunctionBodyNode;
+ class Instruction;
+ class InternalFunction;
+ class AssemblerBuffer;
+ class JSFunction;
+ class JSGlobalObject;
+ class ProgramNode;
+ class Register;
+ class ScopeChainNode;
+ class SamplingTool;
+ struct HandlerInfo;
+
+#if ENABLE(JIT)
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+ #define STUB_ARGS void* args, ...
+ #define ARGS (reinterpret_cast<void**>(vl_args) - 1)
+#else // JIT_STUB_ARGUMENT_REGISTER or JIT_STUB_ARGUMENT_STACK
+ #define STUB_ARGS void** args
+ #define ARGS (args)
+#endif
+
+#if USE(JIT_STUB_ARGUMENT_REGISTER)
+ #if PLATFORM(X86_64)
+ #define JIT_STUB
+ #elif COMPILER(MSVC)
+ #define JIT_STUB __fastcall
+ #elif COMPILER(GCC)
+ #define JIT_STUB __attribute__ ((fastcall))
+ #else
+ #error Need to support register calling convention in this compiler
+ #endif
+#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
+ #if COMPILER(MSVC)
+ #define JIT_STUB __cdecl
+ #else
+ #define JIT_STUB
+ #endif
+#endif
+
+// The Mac compilers are fine with this,
+#if PLATFORM(MAC)
+ struct VoidPtrPair {
+ void* first;
+ void* second;
+ };
+#define RETURN_PAIR(a,b) VoidPtrPair pair = { a, b }; return pair
+#else
+ typedef uint64_t VoidPtrPair;
+ union VoidPtrPairValue {
+ struct { void* first; void* second; } s;
+ VoidPtrPair i;
+ };
+#define RETURN_PAIR(a,b) VoidPtrPairValue pair = {{ a, b }}; return pair.i
+#endif
+
+#endif // ENABLE(JIT)
+
+ enum DebugHookID {
+ WillExecuteProgram,
+ DidExecuteProgram,
+ DidEnterCallFrame,
+ DidReachBreakpoint,
+ WillLeaveCallFrame,
+ WillExecuteStatement
+ };
+
+ enum { MaxReentryDepth = 128 };
+
+ class Interpreter {
+ friend class JIT;
+ public:
+ Interpreter();
+ ~Interpreter();
+
+ void initialize(JSGlobalData*);
+
+ RegisterFile& registerFile() { return m_registerFile; }
+
+ Opcode getOpcode(OpcodeID id)
+ {
+ #if HAVE(COMPUTED_GOTO)
+ return m_opcodeTable[id];
+ #else
+ return id;
+ #endif
+ }
+
+ OpcodeID getOpcodeID(Opcode opcode)
+ {
+ #if HAVE(COMPUTED_GOTO)
+ ASSERT(isOpcode(opcode));
+ return m_opcodeIDTable.get(opcode);
+ #else
+ return opcode;
+ #endif
+ }
+
+ bool isOpcode(Opcode);
+
+ JSValuePtr execute(ProgramNode*, CallFrame*, ScopeChainNode*, JSObject* thisObj, JSValuePtr* exception);
+ JSValuePtr execute(FunctionBodyNode*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValuePtr* exception);
+ JSValuePtr execute(EvalNode* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValuePtr* exception);
+
+ JSValuePtr retrieveArguments(CallFrame*, JSFunction*) const;
+ JSValuePtr retrieveCaller(CallFrame*, InternalFunction*) const;
+ void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValuePtr& function) const;
+
+ void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
+ void setTimeoutTime(unsigned timeoutTime) { m_timeoutTime = timeoutTime; }
+
+ void startTimeoutCheck()
+ {
+ if (!m_timeoutCheckCount)
+ resetTimeoutCheck();
+#ifdef ANDROID_INSTRUMENT
+ if (!m_timeoutCheckCount)
+ android::TimeCounter::start(android::TimeCounter::JavaScriptTimeCounter);
+#endif
+
+ ++m_timeoutCheckCount;
+ }
+
+ void stopTimeoutCheck()
+ {
+ ASSERT(m_timeoutCheckCount);
+ --m_timeoutCheckCount;
+#ifdef ANDROID_INSTRUMENT
+ if (!m_timeoutCheckCount)
+ android::TimeCounter::record(android::TimeCounter::JavaScriptTimeCounter, __FUNCTION__);
+#endif
+ }
+
+ inline void initTimeout()
+ {
+ ASSERT(!m_timeoutCheckCount);
+ resetTimeoutCheck();
+ m_timeoutTime = 0;
+ m_timeoutCheckCount = 0;
+ }
+
+ void setSampler(SamplingTool* sampler) { m_sampler = sampler; }
+ SamplingTool* sampler() { return m_sampler; }
+
+#if ENABLE(JIT)
+
+ static int JIT_STUB cti_timeout_check(STUB_ARGS);
+ static void JIT_STUB cti_register_file_check(STUB_ARGS);
+
+ static JSObject* JIT_STUB cti_op_convert_this(STUB_ARGS);
+ static void JIT_STUB cti_op_end(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_add(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_pre_inc(STUB_ARGS);
+ static int JIT_STUB cti_op_loop_if_less(STUB_ARGS);
+ static int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_object(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_id(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_id_second(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_second(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_generic(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_del_by_id(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_instanceof(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_mul(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_func(STUB_ARGS);
+ static void* JIT_STUB cti_op_call_JSFunction(STUB_ARGS);
+ static VoidPtrPair JIT_STUB cti_op_call_arityCheck(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS);
+ static void JIT_STUB cti_op_create_arguments(STUB_ARGS);
+ static void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS);
+ static void JIT_STUB cti_op_tear_off_activation(STUB_ARGS);
+ static void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS);
+ static void JIT_STUB cti_op_profile_will_call(STUB_ARGS);
+ static void JIT_STUB cti_op_profile_did_call(STUB_ARGS);
+ static void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_array(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_global(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_val(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_val_byte_array(STUB_ARGS);
+ static VoidPtrPair JIT_STUB cti_op_resolve_func(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_sub(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_val(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_val_array(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_lesseq(STUB_ARGS);
+ static int JIT_STUB cti_op_loop_if_true(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_base(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_negate(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_skip(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_div(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_pre_dec(STUB_ARGS);
+ static int JIT_STUB cti_op_jless(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_not(STUB_ARGS);
+ static int JIT_STUB cti_op_jtrue(STUB_ARGS);
+ static VoidPtrPair JIT_STUB cti_op_post_inc(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_eq(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_lshift(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_bitand(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_rshift(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_bitnot(STUB_ARGS);
+ static VoidPtrPair JIT_STUB cti_op_resolve_with_base(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_mod(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_less(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_neq(STUB_ARGS);
+ static VoidPtrPair JIT_STUB cti_op_post_dec(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_urshift(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_bitxor(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_bitor(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_call_eval(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_throw(STUB_ARGS);
+ static JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_next_pname(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS);
+ static void JIT_STUB cti_op_pop_scope(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_typeof(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_undefined(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_boolean(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_number(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_string(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_object(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_function(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_stricteq(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_nstricteq(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_to_jsnumber(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_in(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS);
+ static void JIT_STUB cti_op_jmp_scopes(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_index(STUB_ARGS);
+ static void* JIT_STUB cti_op_switch_imm(STUB_ARGS);
+ static void* JIT_STUB cti_op_switch_char(STUB_ARGS);
+ static void* JIT_STUB cti_op_switch_string(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_del_by_val(STUB_ARGS);
+ static void JIT_STUB cti_op_put_getter(STUB_ARGS);
+ static void JIT_STUB cti_op_put_setter(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_error(STUB_ARGS);
+ static void JIT_STUB cti_op_debug(STUB_ARGS);
+
+ static JSValueEncodedAsPointer* JIT_STUB cti_vm_throw(STUB_ARGS);
+ static void* JIT_STUB cti_vm_dontLazyLinkCall(STUB_ARGS);
+ static void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS);
+
+#endif // ENABLE(JIT)
+
+ // Default number of ticks before a timeout check should be done.
+ static const int initialTickCountThreshold = 1024;
+
+ bool isJSArray(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsArrayVptr; }
+ bool isJSString(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsStringVptr; }
+ bool isJSByteArray(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsByteArrayVptr; }
+
+ private:
+ enum ExecutionFlag { Normal, InitializeAndReturn };
+
+ NEVER_INLINE JSValuePtr callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset, JSValuePtr& exceptionValue);
+ JSValuePtr execute(EvalNode*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValuePtr* exception);
+
+ NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
+
+ NEVER_INLINE bool resolve(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+ NEVER_INLINE bool resolveSkip(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+ NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+ NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC);
+ NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+ NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
+
+ NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValuePtr, unsigned& bytecodeOffset, CodeBlock*&);
+ NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValuePtr&, unsigned bytecodeOffset, bool);
+ NEVER_INLINE bool resolveBaseAndFunc(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+
+ static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
+
+ static CallFrame* findFunctionCallFrame(CallFrame*, InternalFunction*);
+
+ JSValuePtr privateExecute(ExecutionFlag, RegisterFile*, CallFrame*, JSValuePtr* exception);
+
+ void dumpCallFrame(CallFrame*);
+ void dumpRegisters(CallFrame*);
+
+ bool checkTimeout(JSGlobalObject*);
+ void resetTimeoutCheck();
+
+ void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot&);
+ void uncacheGetByID(CodeBlock*, Instruction* vPC);
+ void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValuePtr baseValue, const PutPropertySlot&);
+ void uncachePutByID(CodeBlock*, Instruction* vPC);
+
+ bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
+
+#if ENABLE(JIT)
+ static void throwStackOverflowPreviousFrame(CallFrame**, JSGlobalData*, void*& returnAddress);
+
+ void tryCTICacheGetByID(CallFrame*, CodeBlock*, void* returnAddress, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot&);
+ void tryCTICachePutByID(CallFrame*, CodeBlock*, void* returnAddress, JSValuePtr baseValue, const PutPropertySlot&);
+#endif
+
+ SamplingTool* m_sampler;
+
+#if ENABLE(JIT)
+ RefPtr<ExecutablePool> m_executablePool;
+ void* m_ctiArrayLengthTrampoline;
+ void* m_ctiStringLengthTrampoline;
+ void* m_ctiVirtualCallPreLink;
+ void* m_ctiVirtualCallLink;
+ void* m_ctiVirtualCall;
+#endif
+
+ int m_reentryDepth;
+ unsigned m_timeoutTime;
+ unsigned m_timeAtLastCheckTimeout;
+ unsigned m_timeExecuting;
+ unsigned m_timeoutCheckCount;
+ unsigned m_ticksUntilNextTimeoutCheck;
+
+ RegisterFile m_registerFile;
+
+ void* m_jsArrayVptr;
+ void* m_jsByteArrayVptr;
+ void* m_jsStringVptr;
+ void* m_jsFunctionVptr;
+
+#if HAVE(COMPUTED_GOTO)
+ Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
+ HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
+#endif
+ };
+
+} // namespace JSC
+
+#endif // Interpreter_h
diff --git a/JavaScriptCore/VM/Register.h b/JavaScriptCore/interpreter/Register.h
index c1fee3a..ff36bbc 100644
--- a/JavaScriptCore/VM/Register.h
+++ b/JavaScriptCore/interpreter/Register.h
@@ -49,19 +49,19 @@ namespace JSC {
class Register {
public:
Register();
- Register(JSValue*);
+ Register(JSValuePtr);
- JSValue* jsValue(CallFrame*) const;
- JSValue* getJSValue() const;
+ JSValuePtr jsValue(CallFrame*) const;
+ JSValuePtr getJSValue() const;
bool marked() const;
void mark();
private:
friend class ExecState;
- friend class Machine;
+ friend class Interpreter;
- // Only CallFrame and Machine should use these functions.
+ // Only CallFrame and Interpreter should use these functions.
Register(intptr_t);
@@ -89,7 +89,7 @@ namespace JSC {
union {
intptr_t i;
void* v;
- JSValue* value;
+ JSValueEncodedAsPointer* value;
JSActivation* activation;
Arguments* arguments;
@@ -135,42 +135,42 @@ namespace JSC {
{
#ifndef NDEBUG
SET_TYPE(EmptyType);
- *this = noValue();
+ u.value = JSValuePtr::encode(noValue());
#endif
}
- ALWAYS_INLINE Register::Register(JSValue* v)
+ ALWAYS_INLINE Register::Register(JSValuePtr v)
{
SET_TYPE(ValueType);
- u.value = v;
+ u.value = JSValuePtr::encode(v);
}
// This function is scaffolding for legacy clients. It will eventually go away.
- ALWAYS_INLINE JSValue* Register::jsValue(CallFrame*) const
+ ALWAYS_INLINE JSValuePtr Register::jsValue(CallFrame*) const
{
// Once registers hold doubles, this function will allocate a JSValue*
// if the register doesn't hold one already.
ASSERT_TYPE(ValueType);
- return u.value;
+ return JSValuePtr::decode(u.value);
}
- ALWAYS_INLINE JSValue* Register::getJSValue() const
+ ALWAYS_INLINE JSValuePtr Register::getJSValue() const
{
ASSERT_TYPE(JSValueType);
- return u.value;
+ return JSValuePtr::decode(u.value);
}
ALWAYS_INLINE bool Register::marked() const
{
- return getJSValue()->marked();
+ return getJSValue().marked();
}
ALWAYS_INLINE void Register::mark()
{
- getJSValue()->mark();
+ getJSValue().mark();
}
- // Machine functions
+ // Interpreter functions
ALWAYS_INLINE Register::Register(Arguments* arguments)
{
diff --git a/JavaScriptCore/VM/RegisterFile.cpp b/JavaScriptCore/interpreter/RegisterFile.cpp
index 05d717f..50698f5 100644
--- a/JavaScriptCore/VM/RegisterFile.cpp
+++ b/JavaScriptCore/interpreter/RegisterFile.cpp
@@ -36,8 +36,7 @@ RegisterFile::~RegisterFile()
#if HAVE(MMAP)
munmap(m_buffer, ((m_max - m_start) + m_maxGlobals) * sizeof(Register));
#elif HAVE(VIRTUALALLOC)
- // FIXME: Use VirtualFree.
- fastFree(m_buffer);
+ VirtualFree(m_buffer, 0, MEM_RELEASE);
#else
#error "Don't know how to release virtual memory on this platform."
#endif
diff --git a/JavaScriptCore/VM/RegisterFile.h b/JavaScriptCore/interpreter/RegisterFile.h
index 0955ccb..ec190d6 100644
--- a/JavaScriptCore/VM/RegisterFile.h
+++ b/JavaScriptCore/interpreter/RegisterFile.h
@@ -30,11 +30,14 @@
#define RegisterFile_h
#include "Register.h"
-#include "collector.h"
+#include "Collector.h"
+#include <wtf/Noncopyable.h>
+
#if HAVE(MMAP)
+#include <errno.h>
+#include <stdio.h>
#include <sys/mman.h>
#endif
-#include <wtf/Noncopyable.h>
namespace JSC {
@@ -88,7 +91,7 @@ namespace JSC {
class JSGlobalObject;
class RegisterFile : Noncopyable {
- friend class CTI;
+ friend class JIT;
public:
enum CallFrameHeaderEntry {
CallFrameHeaderSize = 8,
@@ -96,7 +99,7 @@ namespace JSC {
CodeBlock = -8,
ScopeChain = -7,
CallerFrame = -6,
- ReturnPC = -5,
+ ReturnPC = -5, // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*.
ReturnValueRegister = -4,
ArgumentCount = -3,
Callee = -2,
@@ -108,6 +111,8 @@ namespace JSC {
static const size_t defaultCapacity = 524288;
static const size_t defaultMaxGlobals = 8192;
+ static const size_t allocationSize = 1 << 14;
+ static const size_t allocationSizeMask = allocationSize - 1;
RegisterFile(size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals)
: m_numGlobals(0)
@@ -121,10 +126,25 @@ namespace JSC {
size_t bufferLength = (capacity + maxGlobals) * sizeof(Register);
#if HAVE(MMAP)
m_buffer = static_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0));
- ASSERT(reinterpret_cast<intptr_t>(m_buffer) != -1);
+ if (m_buffer == MAP_FAILED) {
+ fprintf(stderr, "Could not allocate register file: %d\n", errno);
+ CRASH();
+ }
#elif HAVE(VIRTUALALLOC)
- // FIXME: Use VirtualAlloc, and commit pages as we go.
- m_buffer = static_cast<Register*>(fastMalloc(bufferLength));
+ // Ensure bufferLength is a multiple of allocation size
+ bufferLength = (bufferLength + allocationSizeMask) & ~allocationSizeMask;
+ m_buffer = static_cast<Register*>(VirtualAlloc(0, bufferLength, MEM_RESERVE, PAGE_READWRITE));
+ if (!m_buffer) {
+ fprintf(stderr, "Could not allocate register file: %d\n", errno);
+ CRASH();
+ }
+ int initialAllocation = (maxGlobals * sizeof(Register) + allocationSizeMask) & ~allocationSizeMask;
+ void* commitCheck = VirtualAlloc(m_buffer, initialAllocation, MEM_COMMIT, PAGE_READWRITE);
+ if (commitCheck != m_buffer) {
+ fprintf(stderr, "Could not allocate register file: %d\n", errno);
+ CRASH();
+ }
+ m_maxCommitted = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_buffer) + initialAllocation);
#else
#error "Don't know how to reserve virtual memory on this platform."
#endif
@@ -154,7 +174,14 @@ namespace JSC {
if (newEnd > m_max)
return false;
#if !HAVE(MMAP) && HAVE(VIRTUALALLOC)
- // FIXME: Use VirtualAlloc, and commit pages as we go.
+ if (newEnd > m_maxCommitted) {
+ ptrdiff_t additionalAllocation = ((reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_maxCommitted)) + allocationSizeMask) & ~allocationSizeMask;
+ if (!VirtualAlloc(m_maxCommitted, additionalAllocation, MEM_COMMIT, PAGE_READWRITE)) {
+ fprintf(stderr, "Could not allocate register file: %d\n", errno);
+ CRASH();
+ }
+ m_maxCommitted = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_maxCommitted) + additionalAllocation);
+ }
#endif
m_end = newEnd;
}
@@ -177,6 +204,10 @@ namespace JSC {
Register* m_end;
Register* m_max;
Register* m_buffer;
+#if HAVE(VIRTUALALLOC)
+ Register* m_maxCommitted;
+#endif
+
JSGlobalObject* m_globalObject; // The global object whose vars are currently stored in the register file.
};
diff --git a/JavaScriptCore/jit/ExecutableAllocator.cpp b/JavaScriptCore/jit/ExecutableAllocator.cpp
new file mode 100644
index 0000000..f6b27ec
--- /dev/null
+++ b/JavaScriptCore/jit/ExecutableAllocator.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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 "ExecutableAllocator.h"
+
+#if ENABLE(ASSEMBLER)
+
+namespace JSC {
+
+size_t ExecutableAllocator::pageSize = 0;
+
+}
+
+#endif // HAVE(ASSEMBLER)
diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h
new file mode 100644
index 0000000..1541256
--- /dev/null
+++ b/JavaScriptCore/jit/ExecutableAllocator.h
@@ -0,0 +1,179 @@
+/*
+ * 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 ExecutableAllocator_h
+#define ExecutableAllocator_h
+
+#if ENABLE(ASSEMBLER)
+
+#include <wtf/Assertions.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+#include <limits>
+
+#define JIT_ALLOCATOR_PAGE_SIZE (ExecutableAllocator::pageSize)
+#define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (ExecutableAllocator::pageSize * 4)
+
+namespace JSC {
+
+class ExecutablePool : public RefCounted<ExecutablePool> {
+private:
+ struct Allocation {
+ char* pages;
+ size_t size;
+ };
+ typedef Vector<Allocation, 2> AllocationList;
+
+public:
+ static PassRefPtr<ExecutablePool> create(size_t n)
+ {
+ return adoptRef(new ExecutablePool(n));
+ }
+
+ void* alloc(size_t n)
+ {
+ ASSERT(m_freePtr <= m_end);
+
+ // Round 'n' up to a multiple of word size; if all allocations are of
+ // word sized quantities, then all subsequent allocations will be aligned.
+ n = roundUpAllocationSize(n, sizeof(void*));
+
+ if (static_cast<ptrdiff_t>(n) < (m_end - m_freePtr)) {
+ void* result = m_freePtr;
+ m_freePtr += n;
+ return result;
+ }
+
+ // Insufficient space to allocate in the existing pool
+ // so we need allocate into a new pool
+ return poolAllocate(n);
+ }
+
+ ~ExecutablePool()
+ {
+ AllocationList::const_iterator end = m_pools.end();
+ for (AllocationList::const_iterator ptr = m_pools.begin(); ptr != end; ++ptr)
+ ExecutablePool::systemRelease(*ptr);
+ }
+
+ size_t available() const { return (m_pools.size() > 1) ? 0 : m_end - m_freePtr; }
+
+private:
+ static Allocation systemAlloc(size_t n);
+ static void systemRelease(const Allocation& alloc);
+
+ inline size_t roundUpAllocationSize(size_t request, size_t granularity)
+ {
+ if ((std::numeric_limits<size_t>::max() - granularity) <= request)
+ CRASH(); // Allocation is too large
+
+ // Round up to next page boundary
+ size_t size = request + (granularity - 1);
+ size = size & ~(granularity - 1);
+ ASSERT(size >= request);
+ return size;
+ }
+
+ ExecutablePool(size_t n);
+
+ void* poolAllocate(size_t n);
+
+ char* m_freePtr;
+ char* m_end;
+ AllocationList m_pools;
+};
+
+class ExecutableAllocator {
+public:
+ static size_t pageSize;
+ ExecutableAllocator()
+ {
+ if (!pageSize)
+ intializePageSize();
+ m_smallAllocationPool = ExecutablePool::create(JIT_ALLOCATOR_LARGE_ALLOC_SIZE);
+ }
+
+ PassRefPtr<ExecutablePool> poolForSize(size_t n)
+ {
+ // Try to fit in the existing small allocator
+ if (n < m_smallAllocationPool->available())
+ return m_smallAllocationPool;
+
+ // If the request is large, we just provide a unshared allocator
+ if (n > JIT_ALLOCATOR_LARGE_ALLOC_SIZE)
+ return ExecutablePool::create(n);
+
+ // Create a new allocator
+ RefPtr<ExecutablePool> pool = ExecutablePool::create(JIT_ALLOCATOR_LARGE_ALLOC_SIZE);
+
+ // If the new allocator will result in more free space than in
+ // the current small allocator, then we will use it instead
+ if ((pool->available() - n) > m_smallAllocationPool->available())
+ m_smallAllocationPool = pool;
+ return pool.release();
+ }
+
+private:
+ RefPtr<ExecutablePool> m_smallAllocationPool;
+ static void intializePageSize();
+};
+
+inline ExecutablePool::ExecutablePool(size_t n)
+{
+ size_t allocSize = roundUpAllocationSize(n, JIT_ALLOCATOR_PAGE_SIZE);
+ Allocation mem = systemAlloc(allocSize);
+ m_pools.append(mem);
+ m_freePtr = mem.pages;
+ if (!m_freePtr)
+ CRASH(); // Failed to allocate
+ m_end = m_freePtr + allocSize;
+}
+
+inline void* ExecutablePool::poolAllocate(size_t n)
+{
+ size_t allocSize = roundUpAllocationSize(n, JIT_ALLOCATOR_PAGE_SIZE);
+
+ Allocation result = systemAlloc(allocSize);
+ if (!result.pages)
+ CRASH(); // Failed to allocate
+
+ ASSERT(m_end >= m_freePtr);
+ if ((allocSize - n) > static_cast<size_t>(m_end - m_freePtr)) {
+ // Replace allocation pool
+ m_freePtr = result.pages + n;
+ m_end = result.pages + allocSize;
+ }
+
+ m_pools.append(result);
+ return result.pages;
+}
+
+}
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // !defined(ExecutableAllocator)
diff --git a/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp b/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp
new file mode 100644
index 0000000..21955d7
--- /dev/null
+++ b/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 "ExecutableAllocator.h"
+
+#if ENABLE(ASSEMBLER)
+
+#include <sys/mman.h>
+#include <unistd.h>
+
+namespace JSC {
+
+void ExecutableAllocator::intializePageSize()
+{
+ ExecutableAllocator::pageSize = getpagesize();
+}
+
+ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n)
+{
+ ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(mmap(NULL, n, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0)), n};
+ return alloc;
+}
+
+void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc)
+{
+ int result = munmap(alloc.pages, alloc.size);
+ ASSERT_UNUSED(result, !result);
+}
+
+}
+
+#endif // HAVE(ASSEMBLER)
diff --git a/JavaScriptCore/jit/ExecutableAllocatorWin.cpp b/JavaScriptCore/jit/ExecutableAllocatorWin.cpp
new file mode 100644
index 0000000..7467f81
--- /dev/null
+++ b/JavaScriptCore/jit/ExecutableAllocatorWin.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 "ExecutableAllocator.h"
+
+#if ENABLE(ASSEMBLER)
+
+#include "windows.h"
+
+namespace JSC {
+
+void ExecutableAllocator::intializePageSize()
+{
+ SYSTEM_INFO system_info;
+ GetSystemInfo(&system_info);
+ ExecutableAllocator::pageSize = system_info.dwPageSize;
+}
+
+ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n)
+{
+ ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(VirtualAlloc(0, n, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)), n};
+ return alloc;
+}
+
+void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc)
+{
+ VirtualFree(alloc.pages, 0, MEM_RELEASE);
+}
+
+}
+
+#endif // HAVE(ASSEMBLER)
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
new file mode 100644
index 0000000..5640c8a
--- /dev/null
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -0,0 +1,1944 @@
+/*
+ * 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 "JIT.h"
+
+#if ENABLE(JIT)
+
+#include "CodeBlock.h"
+#include "JITInlineMethods.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "Interpreter.h"
+#include "ResultType.h"
+#include "SamplingTool.h"
+
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+using namespace std;
+
+namespace JSC {
+
+#if COMPILER(GCC) && PLATFORM(X86)
+
+COMPILE_ASSERT(STUB_ARGS_code == 0x0C, STUB_ARGS_code_is_0x0C);
+COMPILE_ASSERT(STUB_ARGS_callFrame == 0x0E, STUB_ARGS_callFrame_is_0x0E);
+
+#if PLATFORM(DARWIN)
+#define SYMBOL_STRING(name) "_" #name
+#else
+#define SYMBOL_STRING(name) #name
+#endif
+
+asm(
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+ "pushl %ebp" "\n"
+ "movl %esp, %ebp" "\n"
+ "pushl %esi" "\n"
+ "pushl %edi" "\n"
+ "pushl %ebx" "\n"
+ "subl $0x1c, %esp" "\n"
+ "movl $512, %esi" "\n"
+ "movl 0x38(%esp), %edi" "\n" // Ox38 = 0x0E * 4, 0x0E = STUB_ARGS_callFrame (see assertion above)
+ "call *0x30(%esp)" "\n" // Ox30 = 0x0C * 4, 0x0C = STUB_ARGS_code (see assertion above)
+ "addl $0x1c, %esp" "\n"
+ "popl %ebx" "\n"
+ "popl %edi" "\n"
+ "popl %esi" "\n"
+ "popl %ebp" "\n"
+ "ret" "\n"
+);
+
+asm(
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+ "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPvz) "\n"
+#else
+#if USE(JIT_STUB_ARGUMENT_REGISTER)
+ "movl %esp, %ecx" "\n"
+#else // JIT_STUB_ARGUMENT_STACK
+ "movl %esp, 0(%esp)" "\n"
+#endif
+ "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPPv) "\n"
+#endif
+ "addl $0x1c, %esp" "\n"
+ "popl %ebx" "\n"
+ "popl %edi" "\n"
+ "popl %esi" "\n"
+ "popl %ebp" "\n"
+ "ret" "\n"
+);
+
+#elif COMPILER(GCC) && PLATFORM(X86_64)
+
+COMPILE_ASSERT(STUB_ARGS_code == 0x10, STUB_ARGS_code_is_0x10);
+COMPILE_ASSERT(STUB_ARGS_callFrame == 0x12, STUB_ARGS_callFrame_is_0x12);
+
+#if PLATFORM(DARWIN)
+#define SYMBOL_STRING(name) "_" #name
+#else
+#define SYMBOL_STRING(name) #name
+#endif
+
+asm(
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+ "pushq %rbp" "\n"
+ "movq %rsp, %rbp" "\n"
+ "pushq %r12" "\n"
+ "pushq %r13" "\n"
+ "pushq %r14" "\n"
+ "pushq %r15" "\n"
+ "pushq %rbx" "\n"
+ "subq $0x48, %rsp" "\n"
+ "movq $512, %r12" "\n"
+ "movq $0xFFFF000000000000, %r14" "\n"
+ "movq $0xFFFF000000000002, %r15" "\n"
+ "movq 0x90(%rsp), %r13" "\n" // Ox90 = 0x12 * 8, 0x12 = STUB_ARGS_callFrame (see assertion above)
+ "call *0x80(%rsp)" "\n" // Ox80 = 0x10 * 8, 0x10 = STUB_ARGS_code (see assertion above)
+ "addq $0x48, %rsp" "\n"
+ "popq %rbx" "\n"
+ "popq %r15" "\n"
+ "popq %r14" "\n"
+ "popq %r13" "\n"
+ "popq %r12" "\n"
+ "popq %rbp" "\n"
+ "ret" "\n"
+);
+
+asm(
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+#if USE(JIT_STUB_ARGUMENT_REGISTER)
+ "movq %rsp, %rdi" "\n"
+ "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPPv) "\n"
+#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
+#error "JIT_STUB_ARGUMENT configuration not supported."
+#endif
+ "addq $0x48, %rsp" "\n"
+ "popq %rbx" "\n"
+ "popq %r15" "\n"
+ "popq %r14" "\n"
+ "popq %r13" "\n"
+ "popq %r12" "\n"
+ "popq %rbp" "\n"
+ "ret" "\n"
+);
+
+#elif COMPILER(MSVC)
+
+extern "C" {
+
+ __declspec(naked) JSValueEncodedAsPointer* ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValuePtr* exception, Profiler**, JSGlobalData*)
+ {
+ __asm {
+ push ebp;
+ mov ebp, esp;
+ push esi;
+ push edi;
+ push ebx;
+ sub esp, 0x1c;
+ mov esi, 512;
+ mov ecx, esp;
+ mov edi, [esp + 0x38];
+ call [esp + 0x30]; // Ox30 = 0x0C * 4, 0x0C = STUB_ARGS_code (see assertion above)
+ add esp, 0x1c;
+ pop ebx;
+ pop edi;
+ pop esi;
+ pop ebp;
+ ret;
+ }
+ }
+
+ __declspec(naked) void ctiVMThrowTrampoline()
+ {
+ __asm {
+#if USE(JIT_STUB_ARGUMENT_REGISTER)
+ mov ecx, esp;
+#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
+#error "JIT_STUB_ARGUMENT configuration not supported."
+#endif
+ call JSC::Interpreter::cti_vm_throw;
+ add esp, 0x1c;
+ pop ebx;
+ pop edi;
+ pop esi;
+ pop ebp;
+ ret;
+ }
+ }
+
+}
+
+#endif
+
+void ctiSetReturnAddress(void** where, void* what)
+{
+ *where = what;
+}
+
+void ctiPatchCallByReturnAddress(void* where, void* what)
+{
+ MacroAssembler::Jump::patch(where, what);
+}
+
+JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock)
+ : m_interpreter(globalData->interpreter)
+ , m_globalData(globalData)
+ , m_codeBlock(codeBlock)
+ , m_labels(codeBlock ? codeBlock->instructions().size() : 0)
+ , m_propertyAccessCompilationInfo(codeBlock ? codeBlock->numberOfStructureStubInfos() : 0)
+ , m_callStructureStubCompilationInfo(codeBlock ? codeBlock->numberOfCallLinkInfos() : 0)
+ , m_lastResultBytecodeRegister(std::numeric_limits<int>::max())
+ , m_jumpTargetsPosition(0)
+{
+}
+
+void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqType type)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned src1 = currentInstruction[2].u.operand;
+ unsigned src2 = currentInstruction[3].u.operand;
+
+ emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx);
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ // Jump to a slow case if either operand is a number, or if both are JSCell*s.
+ move(X86::eax, X86::ecx);
+ orPtr(X86::edx, X86::ecx);
+ addSlowCase(emitJumpIfJSCell(X86::ecx));
+ addSlowCase(emitJumpIfImmediateNumber(X86::ecx));
+
+ if (type == OpStrictEq)
+ sete32(X86::edx, X86::eax);
+ else
+ setne32(X86::edx, X86::eax);
+ emitTagAsBoolImmediate(X86::eax);
+#else
+ bool negated = (type == OpNStrictEq);
+
+ // Check that both are immediates, if so check if they're equal
+ Jump firstNotImmediate = emitJumpIfJSCell(X86::eax);
+ Jump secondNotImmediate = emitJumpIfJSCell(X86::edx);
+ Jump bothWereImmediatesButNotEqual = jnePtr(X86::edx, X86::eax);
+
+ // They are equal - set the result to true. (Or false, if negated).
+ move(ImmPtr(JSValuePtr::encode(jsBoolean(!negated))), X86::eax);
+ Jump bothWereImmediatesAndEqual = jump();
+
+ // eax was not an immediate, we haven't yet checked edx.
+ // If edx is also a JSCell, or is 0, then jump to a slow case,
+ // otherwise these values are not equal.
+ firstNotImmediate.link(this);
+ emitJumpSlowCaseIfJSCell(X86::edx);
+ addSlowCase(jePtr(X86::edx, ImmPtr(JSValuePtr::encode(js0()))));
+ Jump firstWasNotImmediate = jump();
+
+ // eax was an immediate, but edx wasn't.
+ // If eax is 0 jump to a slow case, otherwise these values are not equal.
+ secondNotImmediate.link(this);
+ addSlowCase(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0()))));
+
+ // We get here if the two values are different immediates, or one is 0 and the other is a JSCell.
+ // Vaelues are not equal, set the result to false.
+ bothWereImmediatesButNotEqual.link(this);
+ firstWasNotImmediate.link(this);
+ move(ImmPtr(JSValuePtr::encode(jsBoolean(negated))), X86::eax);
+
+ bothWereImmediatesAndEqual.link(this);
+#endif
+
+ emitPutVirtualRegister(dst);
+}
+
+void JIT::emitSlowScriptCheck()
+{
+ Jump skipTimeout = jnzSub32(Imm32(1), timeoutCheckRegister);
+ emitCTICall(Interpreter::cti_timeout_check);
+ move(X86::eax, timeoutCheckRegister);
+ skipTimeout.link(this);
+
+ killLastResultRegister();
+}
+
+
+#define NEXT_OPCODE(name) \
+ m_bytecodeIndex += OPCODE_LENGTH(name); \
+ break;
+
+#define CTI_COMPILE_BINARY_OP(name) \
+ case name: { \
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx); \
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx); \
+ emitCTICall(Interpreter::cti_##name); \
+ emitPutVirtualRegister(currentInstruction[1].u.operand); \
+ NEXT_OPCODE(name); \
+ }
+
+#define CTI_COMPILE_UNARY_OP(name) \
+ case name: { \
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx); \
+ emitCTICall(Interpreter::cti_##name); \
+ emitPutVirtualRegister(currentInstruction[1].u.operand); \
+ NEXT_OPCODE(name); \
+ }
+
+void JIT::privateCompileMainPass()
+{
+ Instruction* instructionsBegin = m_codeBlock->instructions().begin();
+ unsigned instructionCount = m_codeBlock->instructions().size();
+ unsigned propertyAccessInstructionIndex = 0;
+ unsigned globalResolveInfoIndex = 0;
+ unsigned callLinkInfoIndex = 0;
+
+ for (m_bytecodeIndex = 0; m_bytecodeIndex < instructionCount; ) {
+ Instruction* currentInstruction = instructionsBegin + m_bytecodeIndex;
+ ASSERT_WITH_MESSAGE(m_interpreter->isOpcode(currentInstruction->u.opcode), "privateCompileMainPass gone bad @ %d", m_bytecodeIndex);
+
+#if ENABLE(OPCODE_SAMPLING)
+ if (m_bytecodeIndex > 0) // Avoid the overhead of sampling op_enter twice.
+ sampleInstruction(currentInstruction);
+#endif
+
+ m_labels[m_bytecodeIndex] = label();
+ OpcodeID opcodeID = m_interpreter->getOpcodeID(currentInstruction->u.opcode);
+
+ switch (opcodeID) {
+ case op_mov: {
+ emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_mov);
+ }
+ case op_add: {
+ compileFastArith_op_add(currentInstruction);
+ NEXT_OPCODE(op_add);
+ }
+ case op_end: {
+ if (m_codeBlock->needsFullScopeChain())
+ emitCTICall(Interpreter::cti_op_end);
+ emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+ push(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register))));
+ ret();
+ NEXT_OPCODE(op_end);
+ }
+ case op_jmp: {
+ unsigned target = currentInstruction[1].u.operand;
+ addJump(jump(), target + 1);
+ NEXT_OPCODE(op_jmp);
+ }
+ case op_pre_inc: {
+ compileFastArith_op_pre_inc(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_pre_inc);
+ }
+ case op_loop: {
+ emitSlowScriptCheck();
+
+ unsigned target = currentInstruction[1].u.operand;
+ addJump(jump(), target + 1);
+ NEXT_OPCODE(op_end);
+ }
+ case op_loop_if_less: {
+ emitSlowScriptCheck();
+
+ unsigned op1 = currentInstruction[1].u.operand;
+ unsigned op2 = currentInstruction[2].u.operand;
+ unsigned target = currentInstruction[3].u.operand;
+ if (isOperandConstantImmediateInt(op2)) {
+ emitGetVirtualRegister(op1, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ int32_t op2imm = getConstantOperandImmediateInt(op2);
+#else
+ int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
+#endif
+ addJump(jl32(X86::eax, Imm32(op2imm)), target + 3);
+ } else {
+ emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+ addJump(jl32(X86::eax, X86::edx), target + 3);
+ }
+ NEXT_OPCODE(op_loop_if_less);
+ }
+ case op_loop_if_lesseq: {
+ emitSlowScriptCheck();
+
+ unsigned op1 = currentInstruction[1].u.operand;
+ unsigned op2 = currentInstruction[2].u.operand;
+ unsigned target = currentInstruction[3].u.operand;
+ if (isOperandConstantImmediateInt(op2)) {
+ emitGetVirtualRegister(op1, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ int32_t op2imm = getConstantOperandImmediateInt(op2);
+#else
+ int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
+#endif
+ addJump(jle32(X86::eax, Imm32(op2imm)), target + 3);
+ } else {
+ emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+ addJump(jle32(X86::eax, X86::edx), target + 3);
+ }
+ NEXT_OPCODE(op_loop_if_less);
+ }
+ case op_new_object: {
+ emitCTICall(Interpreter::cti_op_new_object);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_new_object);
+ }
+ case op_put_by_id: {
+ compilePutByIdHotPath(currentInstruction[1].u.operand, &(m_codeBlock->identifier(currentInstruction[2].u.operand)), currentInstruction[3].u.operand, propertyAccessInstructionIndex++);
+ NEXT_OPCODE(op_put_by_id);
+ }
+ case op_get_by_id: {
+ compileGetByIdHotPath(currentInstruction[1].u.operand, currentInstruction[2].u.operand, &(m_codeBlock->identifier(currentInstruction[3].u.operand)), propertyAccessInstructionIndex++);
+ NEXT_OPCODE(op_get_by_id);
+ }
+ case op_instanceof: {
+ emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax); // value
+ emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx); // baseVal
+ emitGetVirtualRegister(currentInstruction[4].u.operand, X86::edx); // proto
+
+ // check if any are immediates
+ move(X86::eax, X86::ebx);
+ orPtr(X86::ecx, X86::ebx);
+ orPtr(X86::edx, X86::ebx);
+ emitJumpSlowCaseIfNotJSCell(X86::ebx);
+
+ // check that all are object type - this is a bit of a bithack to avoid excess branching;
+ // we check that the sum of the three type codes from Structures is exactly 3 * ObjectType,
+ // this works because NumberType and StringType are smaller
+ move(Imm32(3 * ObjectType), X86::ebx);
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::eax);
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ loadPtr(Address(X86::edx, FIELD_OFFSET(JSCell, m_structure)), X86::edx);
+ sub32(Address(X86::eax, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx);
+ sub32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx);
+ addSlowCase(jne32(Address(X86::edx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx));
+
+ // check that baseVal's flags include ImplementsHasInstance but not OverridesHasInstance
+ load32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), X86::ecx);
+ and32(Imm32(ImplementsHasInstance | OverridesHasInstance), X86::ecx);
+ addSlowCase(jne32(X86::ecx, Imm32(ImplementsHasInstance)));
+
+ emitGetVirtualRegister(currentInstruction[2].u.operand, X86::ecx); // reload value
+ emitGetVirtualRegister(currentInstruction[4].u.operand, X86::edx); // reload proto
+
+ // optimistically load true result
+ move(ImmPtr(JSValuePtr::encode(jsBoolean(true))), X86::eax);
+
+ Label loop(this);
+
+ // load value's prototype
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
+
+ Jump exit = jePtr(X86::ecx, X86::edx);
+
+ jnePtr(X86::ecx, ImmPtr(JSValuePtr::encode(jsNull())), loop);
+
+ move(ImmPtr(JSValuePtr::encode(jsBoolean(false))), X86::eax);
+
+ exit.link(this);
+
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+
+ NEXT_OPCODE(op_instanceof);
+ }
+ case op_del_by_id: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+ emitPutJITStubArgConstant(ident, 2);
+ emitCTICall(Interpreter::cti_op_del_by_id);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_del_by_id);
+ }
+ case op_mul: {
+ compileFastArith_op_mul(currentInstruction);
+ NEXT_OPCODE(op_mul);
+ }
+ case op_new_func: {
+ FuncDeclNode* func = m_codeBlock->function(currentInstruction[2].u.operand);
+ emitPutJITStubArgConstant(func, 1);
+ emitCTICall(Interpreter::cti_op_new_func);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_new_func);
+ }
+ case op_call: {
+ compileOpCall(opcodeID, currentInstruction, callLinkInfoIndex++);
+ NEXT_OPCODE(op_call);
+ }
+ case op_call_eval: {
+ compileOpCall(opcodeID, currentInstruction, callLinkInfoIndex++);
+ NEXT_OPCODE(op_call_eval);
+ }
+ case op_construct: {
+ compileOpCall(opcodeID, currentInstruction, callLinkInfoIndex++);
+ NEXT_OPCODE(op_construct);
+ }
+ case op_get_global_var: {
+ JSVariableObject* globalObject = static_cast<JSVariableObject*>(currentInstruction[2].u.jsCell);
+ move(ImmPtr(globalObject), X86::eax);
+ emitGetVariableObjectRegister(X86::eax, currentInstruction[3].u.operand, X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_get_global_var);
+ }
+ case op_put_global_var: {
+ emitGetVirtualRegister(currentInstruction[3].u.operand, X86::edx);
+ JSVariableObject* globalObject = static_cast<JSVariableObject*>(currentInstruction[1].u.jsCell);
+ move(ImmPtr(globalObject), X86::eax);
+ emitPutVariableObjectRegister(X86::edx, X86::eax, currentInstruction[2].u.operand);
+ NEXT_OPCODE(op_put_global_var);
+ }
+ case op_get_scoped_var: {
+ int skip = currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain();
+
+ emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::eax);
+ while (skip--)
+ loadPtr(Address(X86::eax, FIELD_OFFSET(ScopeChainNode, next)), X86::eax);
+
+ loadPtr(Address(X86::eax, FIELD_OFFSET(ScopeChainNode, object)), X86::eax);
+ emitGetVariableObjectRegister(X86::eax, currentInstruction[2].u.operand, X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_get_scoped_var);
+ }
+ case op_put_scoped_var: {
+ int skip = currentInstruction[2].u.operand + m_codeBlock->needsFullScopeChain();
+
+ emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::edx);
+ emitGetVirtualRegister(currentInstruction[3].u.operand, X86::eax);
+ while (skip--)
+ loadPtr(Address(X86::edx, FIELD_OFFSET(ScopeChainNode, next)), X86::edx);
+
+ loadPtr(Address(X86::edx, FIELD_OFFSET(ScopeChainNode, object)), X86::edx);
+ emitPutVariableObjectRegister(X86::eax, X86::edx, currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_put_scoped_var);
+ }
+ case op_tear_off_activation: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
+ emitCTICall(Interpreter::cti_op_tear_off_activation);
+ NEXT_OPCODE(op_tear_off_activation);
+ }
+ case op_tear_off_arguments: {
+ emitCTICall(Interpreter::cti_op_tear_off_arguments);
+ NEXT_OPCODE(op_tear_off_arguments);
+ }
+ case op_ret: {
+ // We could JIT generate the deref, only calling out to C when the refcount hits zero.
+ if (m_codeBlock->needsFullScopeChain())
+ emitCTICall(Interpreter::cti_op_ret_scopeChain);
+
+ // Return the result in %eax.
+ emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+
+ // Grab the return address.
+ emitGetFromCallFrameHeader(RegisterFile::ReturnPC, X86::edx);
+
+ // Restore our caller's "r".
+ emitGetFromCallFrameHeader(RegisterFile::CallerFrame, callFrameRegister);
+
+ // Return.
+ push(X86::edx);
+ ret();
+
+ NEXT_OPCODE(op_ret);
+ }
+ case op_new_array: {
+ emitPutJITStubArgConstant(currentInstruction[2].u.operand, 1);
+ emitPutJITStubArgConstant(currentInstruction[3].u.operand, 2);
+ emitCTICall(Interpreter::cti_op_new_array);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_new_array);
+ }
+ case op_resolve: {
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
+ emitPutJITStubArgConstant(ident, 1);
+ emitCTICall(Interpreter::cti_op_resolve);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_resolve);
+ }
+ case op_construct_verify: {
+ emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+
+ emitJumpSlowCaseIfNotJSCell(X86::eax);
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ addSlowCase(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
+
+ NEXT_OPCODE(op_construct_verify);
+ }
+ case op_get_by_val: {
+ emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ // This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter.
+ // We check the value as if it was a uint32 against the m_fastAccessCutoff - which will always fail if
+ // number was signed since m_fastAccessCutoff is always less than intmax (since the total allocation
+ // size is always less than 4Gb). As such zero extending wil have been correct (and extending the value
+ // to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign
+ // extending since it makes it easier to re-tag the value in the slow case.
+ zeroExtend32ToPtr(X86::edx, X86::edx);
+#else
+ emitFastArithImmToInt(X86::edx);
+#endif
+ emitJumpSlowCaseIfNotJSCell(X86::eax);
+ addSlowCase(jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)));
+
+ // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
+ addSlowCase(jae32(X86::edx, Address(X86::eax, FIELD_OFFSET(JSArray, m_fastAccessCutoff))));
+
+ // Get the value from the vector
+ loadPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_get_by_val);
+ }
+ case op_resolve_func: {
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+ emitPutJITStubArgConstant(ident, 1);
+ emitCTICall(Interpreter::cti_op_resolve_func);
+ emitPutVirtualRegister(currentInstruction[2].u.operand, X86::edx);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_resolve_func);
+ }
+ case op_sub: {
+ compileFastArith_op_sub(currentInstruction);
+ NEXT_OPCODE(op_sub);
+ }
+ case op_put_by_val: {
+ emitGetVirtualRegisters(currentInstruction[1].u.operand, X86::eax, currentInstruction[2].u.operand, X86::edx);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ // See comment in op_get_by_val.
+ zeroExtend32ToPtr(X86::edx, X86::edx);
+#else
+ emitFastArithImmToInt(X86::edx);
+#endif
+ emitJumpSlowCaseIfNotJSCell(X86::eax);
+ addSlowCase(jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)));
+
+ // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
+ Jump inFastVector = jb32(X86::edx, Address(X86::eax, FIELD_OFFSET(JSArray, m_fastAccessCutoff)));
+ // No; oh well, check if the access if within the vector - if so, we may still be okay.
+ addSlowCase(jae32(X86::edx, Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_vectorLength))));
+
+ // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.
+ // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff.
+ addSlowCase(jzPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0]))));
+
+ // All good - put the value into the array.
+ inFastVector.link(this);
+ emitGetVirtualRegister(currentInstruction[3].u.operand, X86::eax);
+ storePtr(X86::eax, BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])));
+ NEXT_OPCODE(op_put_by_val);
+ }
+ CTI_COMPILE_BINARY_OP(op_lesseq)
+ case op_loop_if_true: {
+ emitSlowScriptCheck();
+
+ unsigned target = currentInstruction[2].u.operand;
+ emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+
+ Jump isZero = jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0())));
+ addJump(emitJumpIfImmediateInteger(X86::eax), target + 2);
+
+ addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
+ addSlowCase(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
+
+ isZero.link(this);
+ NEXT_OPCODE(op_loop_if_true);
+ };
+ case op_resolve_base: {
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
+ emitPutJITStubArgConstant(ident, 1);
+ emitCTICall(Interpreter::cti_op_resolve_base);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_resolve_base);
+ }
+ case op_negate: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
+ emitCTICall(Interpreter::cti_op_negate);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_negate);
+ }
+ case op_resolve_skip: {
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
+ emitPutJITStubArgConstant(ident, 1);
+ emitPutJITStubArgConstant(currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain(), 2);
+ emitCTICall(Interpreter::cti_op_resolve_skip);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_resolve_skip);
+ }
+ case op_resolve_global: {
+ // Fast case
+ void* globalObject = currentInstruction[2].u.jsCell;
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+
+ unsigned currentIndex = globalResolveInfoIndex++;
+ void* structureAddress = &(m_codeBlock->globalResolveInfo(currentIndex).structure);
+ void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset);
+
+ // Check Structure of global object
+ move(ImmPtr(globalObject), X86::eax);
+ loadPtr(structureAddress, X86::edx);
+ Jump noMatch = jnePtr(X86::edx, Address(X86::eax, FIELD_OFFSET(JSCell, m_structure))); // Structures don't match
+
+ // Load cached property
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSGlobalObject, m_propertyStorage)), X86::eax);
+ load32(offsetAddr, X86::edx);
+ loadPtr(BaseIndex(X86::eax, X86::edx, ScalePtr), X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ Jump end = jump();
+
+ // Slow case
+ noMatch.link(this);
+ emitPutJITStubArgConstant(globalObject, 1);
+ emitPutJITStubArgConstant(ident, 2);
+ emitPutJITStubArgConstant(currentIndex, 3);
+ emitCTICall(Interpreter::cti_op_resolve_global);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ end.link(this);
+ NEXT_OPCODE(op_resolve_global);
+ }
+ CTI_COMPILE_BINARY_OP(op_div)
+ case op_pre_dec: {
+ compileFastArith_op_pre_dec(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_pre_dec);
+ }
+ case op_jnless: {
+ unsigned op1 = currentInstruction[1].u.operand;
+ unsigned op2 = currentInstruction[2].u.operand;
+ unsigned target = currentInstruction[3].u.operand;
+ if (isOperandConstantImmediateInt(op2)) {
+ emitGetVirtualRegister(op1, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ int32_t op2imm = getConstantOperandImmediateInt(op2);
+#else
+ int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
+#endif
+ addJump(jge32(X86::eax, Imm32(op2imm)), target + 3);
+ } else {
+ emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+ addJump(jge32(X86::eax, X86::edx), target + 3);
+ }
+ NEXT_OPCODE(op_jnless);
+ }
+ case op_not: {
+ emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
+ xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), X86::eax);
+ addSlowCase(jnzPtr(X86::eax, Imm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));
+ xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_not);
+ }
+ case op_jfalse: {
+ unsigned target = currentInstruction[2].u.operand;
+ emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+
+ addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0()))), target + 2);
+ Jump isNonZero = emitJumpIfImmediateInteger(X86::eax);
+
+ addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))), target + 2);
+ addSlowCase(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))));
+
+ isNonZero.link(this);
+ NEXT_OPCODE(op_jfalse);
+ };
+ case op_jeq_null: {
+ unsigned src = currentInstruction[1].u.operand;
+ unsigned target = currentInstruction[2].u.operand;
+
+ emitGetVirtualRegister(src, X86::eax);
+ Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
+
+ // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ addJump(jnz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+ Jump wasNotImmediate = jump();
+
+ // Now handle the immediate cases - undefined & null
+ isImmediate.link(this);
+ andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
+ addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);
+
+ wasNotImmediate.link(this);
+ NEXT_OPCODE(op_jeq_null);
+ };
+ case op_jneq_null: {
+ unsigned src = currentInstruction[1].u.operand;
+ unsigned target = currentInstruction[2].u.operand;
+
+ emitGetVirtualRegister(src, X86::eax);
+ Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
+
+ // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ addJump(jz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+ Jump wasNotImmediate = jump();
+
+ // Now handle the immediate cases - undefined & null
+ isImmediate.link(this);
+ andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
+ addJump(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);
+
+ wasNotImmediate.link(this);
+ NEXT_OPCODE(op_jneq_null);
+ }
+ case op_post_inc: {
+ compileFastArith_op_post_inc(currentInstruction[1].u.operand, currentInstruction[2].u.operand);
+ NEXT_OPCODE(op_post_inc);
+ }
+ case op_unexpected_load: {
+ JSValuePtr v = m_codeBlock->unexpectedConstant(currentInstruction[2].u.operand);
+ move(ImmPtr(JSValuePtr::encode(v)), X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_unexpected_load);
+ }
+ case op_jsr: {
+ int retAddrDst = currentInstruction[1].u.operand;
+ int target = currentInstruction[2].u.operand;
+ DataLabelPtr storeLocation = storePtrWithPatch(Address(callFrameRegister, sizeof(Register) * retAddrDst));
+ addJump(jump(), target + 2);
+ m_jsrSites.append(JSRInfo(storeLocation, label()));
+ NEXT_OPCODE(op_jsr);
+ }
+ case op_sret: {
+ jump(Address(callFrameRegister, sizeof(Register) * currentInstruction[1].u.operand));
+ NEXT_OPCODE(op_sret);
+ }
+ case op_eq: {
+ emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
+ emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
+ sete32(X86::edx, X86::eax);
+ emitTagAsBoolImmediate(X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_eq);
+ }
+ case op_lshift: {
+ compileFastArith_op_lshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);
+ NEXT_OPCODE(op_lshift);
+ }
+ case op_bitand: {
+ compileFastArith_op_bitand(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);
+ NEXT_OPCODE(op_bitand);
+ }
+ case op_rshift: {
+ compileFastArith_op_rshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);
+ NEXT_OPCODE(op_rshift);
+ }
+ case op_bitnot: {
+ emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ not32(X86::eax);
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+#else
+ xorPtr(Imm32(~JSImmediate::TagTypeNumber), X86::eax);
+#endif
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_bitnot);
+ }
+ case op_resolve_with_base: {
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+ emitPutJITStubArgConstant(ident, 1);
+ emitCTICall(Interpreter::cti_op_resolve_with_base);
+ emitPutVirtualRegister(currentInstruction[2].u.operand, X86::edx);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_resolve_with_base);
+ }
+ case op_new_func_exp: {
+ FuncExprNode* func = m_codeBlock->functionExpression(currentInstruction[2].u.operand);
+ emitPutJITStubArgConstant(func, 1);
+ emitCTICall(Interpreter::cti_op_new_func_exp);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_new_func_exp);
+ }
+ case op_mod: {
+ compileFastArith_op_mod(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);
+ NEXT_OPCODE(op_mod);
+ }
+ case op_jtrue: {
+ unsigned target = currentInstruction[2].u.operand;
+ emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+
+ Jump isZero = jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0())));
+ addJump(emitJumpIfImmediateInteger(X86::eax), target + 2);
+
+ addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
+ addSlowCase(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
+
+ isZero.link(this);
+ NEXT_OPCODE(op_jtrue);
+ }
+ CTI_COMPILE_BINARY_OP(op_less)
+ case op_neq: {
+ emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
+ emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
+ setne32(X86::edx, X86::eax);
+ emitTagAsBoolImmediate(X86::eax);
+
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+
+ NEXT_OPCODE(op_neq);
+ }
+ case op_post_dec: {
+ compileFastArith_op_post_dec(currentInstruction[1].u.operand, currentInstruction[2].u.operand);
+ NEXT_OPCODE(op_post_dec);
+ }
+ CTI_COMPILE_BINARY_OP(op_urshift)
+ case op_bitxor: {
+ emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
+ emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
+ xorPtr(X86::edx, X86::eax);
+ emitFastArithReTagImmediate(X86::eax, X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_bitxor);
+ }
+ case op_new_regexp: {
+ RegExp* regExp = m_codeBlock->regexp(currentInstruction[2].u.operand);
+ emitPutJITStubArgConstant(regExp, 1);
+ emitCTICall(Interpreter::cti_op_new_regexp);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_new_regexp);
+ }
+ case op_bitor: {
+ emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
+ emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
+ orPtr(X86::edx, X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_bitor);
+ }
+ case op_throw: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
+ emitCTICall(Interpreter::cti_op_throw);
+#if PLATFORM(X86_64)
+ addPtr(Imm32(0x48), X86::esp);
+ pop(X86::ebx);
+ pop(X86::r15);
+ pop(X86::r14);
+ pop(X86::r13);
+ pop(X86::r12);
+ pop(X86::ebp);
+ ret();
+#else
+ addPtr(Imm32(0x1c), X86::esp);
+ pop(X86::ebx);
+ pop(X86::edi);
+ pop(X86::esi);
+ pop(X86::ebp);
+ ret();
+#endif
+ NEXT_OPCODE(op_throw);
+ }
+ case op_get_pnames: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
+ emitCTICall(Interpreter::cti_op_get_pnames);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_get_pnames);
+ }
+ case op_next_pname: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
+ unsigned target = currentInstruction[3].u.operand;
+ emitCTICall(Interpreter::cti_op_next_pname);
+ Jump endOfIter = jzPtr(X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ addJump(jump(), target + 3);
+ endOfIter.link(this);
+ NEXT_OPCODE(op_next_pname);
+ }
+ case op_push_scope: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
+ emitCTICall(Interpreter::cti_op_push_scope);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_push_scope);
+ }
+ case op_pop_scope: {
+ emitCTICall(Interpreter::cti_op_pop_scope);
+ NEXT_OPCODE(op_pop_scope);
+ }
+ CTI_COMPILE_UNARY_OP(op_typeof)
+ CTI_COMPILE_UNARY_OP(op_is_undefined)
+ CTI_COMPILE_UNARY_OP(op_is_boolean)
+ CTI_COMPILE_UNARY_OP(op_is_number)
+ CTI_COMPILE_UNARY_OP(op_is_string)
+ CTI_COMPILE_UNARY_OP(op_is_object)
+ CTI_COMPILE_UNARY_OP(op_is_function)
+ case op_stricteq: {
+ compileOpStrictEq(currentInstruction, OpStrictEq);
+ NEXT_OPCODE(op_stricteq);
+ }
+ case op_nstricteq: {
+ compileOpStrictEq(currentInstruction, OpNStrictEq);
+ NEXT_OPCODE(op_nstricteq);
+ }
+ case op_to_jsnumber: {
+ int srcVReg = currentInstruction[2].u.operand;
+ emitGetVirtualRegister(srcVReg, X86::eax);
+
+ Jump wasImmediate = emitJumpIfImmediateInteger(X86::eax);
+
+ emitJumpSlowCaseIfNotJSCell(X86::eax, srcVReg);
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ addSlowCase(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), Imm32(NumberType)));
+
+ wasImmediate.link(this);
+
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_to_jsnumber);
+ }
+ CTI_COMPILE_BINARY_OP(op_in)
+ case op_push_new_scope: {
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
+ emitPutJITStubArgConstant(ident, 1);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_push_new_scope);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_push_new_scope);
+ }
+ case op_catch: {
+ emitGetCTIParam(STUB_ARGS_callFrame, callFrameRegister);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_catch);
+ }
+ case op_jmp_scopes: {
+ unsigned count = currentInstruction[1].u.operand;
+ emitPutJITStubArgConstant(count, 1);
+ emitCTICall(Interpreter::cti_op_jmp_scopes);
+ unsigned target = currentInstruction[2].u.operand;
+ addJump(jump(), target + 2);
+ NEXT_OPCODE(op_jmp_scopes);
+ }
+ case op_put_by_index: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
+ emitPutJITStubArgConstant(currentInstruction[2].u.operand, 2);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
+ emitCTICall(Interpreter::cti_op_put_by_index);
+ NEXT_OPCODE(op_put_by_index);
+ }
+ case op_switch_imm: {
+ unsigned tableIndex = currentInstruction[1].u.operand;
+ unsigned defaultOffset = currentInstruction[2].u.operand;
+ unsigned scrutinee = currentInstruction[3].u.operand;
+
+ // create jump table for switch destinations, track this switch statement.
+ SimpleJumpTable* jumpTable = &m_codeBlock->immediateSwitchJumpTable(tableIndex);
+ m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Immediate));
+ jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
+
+ emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
+ emitPutJITStubArgConstant(tableIndex, 2);
+ emitCTICall(Interpreter::cti_op_switch_imm);
+ jump(X86::eax);
+ NEXT_OPCODE(op_switch_imm);
+ }
+ case op_switch_char: {
+ unsigned tableIndex = currentInstruction[1].u.operand;
+ unsigned defaultOffset = currentInstruction[2].u.operand;
+ unsigned scrutinee = currentInstruction[3].u.operand;
+
+ // create jump table for switch destinations, track this switch statement.
+ SimpleJumpTable* jumpTable = &m_codeBlock->characterSwitchJumpTable(tableIndex);
+ m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Character));
+ jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
+
+ emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
+ emitPutJITStubArgConstant(tableIndex, 2);
+ emitCTICall(Interpreter::cti_op_switch_char);
+ jump(X86::eax);
+ NEXT_OPCODE(op_switch_char);
+ }
+ case op_switch_string: {
+ unsigned tableIndex = currentInstruction[1].u.operand;
+ unsigned defaultOffset = currentInstruction[2].u.operand;
+ unsigned scrutinee = currentInstruction[3].u.operand;
+
+ // create jump table for switch destinations, track this switch statement.
+ StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex);
+ m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset));
+
+ emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
+ emitPutJITStubArgConstant(tableIndex, 2);
+ emitCTICall(Interpreter::cti_op_switch_string);
+ jump(X86::eax);
+ NEXT_OPCODE(op_switch_string);
+ }
+ case op_del_by_val: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_del_by_val);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_del_by_val);
+ }
+ case op_put_getter: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
+ emitPutJITStubArgConstant(ident, 2);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
+ emitCTICall(Interpreter::cti_op_put_getter);
+ NEXT_OPCODE(op_put_getter);
+ }
+ case op_put_setter: {
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
+ Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
+ emitPutJITStubArgConstant(ident, 2);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
+ emitCTICall(Interpreter::cti_op_put_setter);
+ NEXT_OPCODE(op_put_setter);
+ }
+ case op_new_error: {
+ JSValuePtr message = m_codeBlock->unexpectedConstant(currentInstruction[3].u.operand);
+ emitPutJITStubArgConstant(currentInstruction[2].u.operand, 1);
+ emitPutJITStubArgConstant(JSValuePtr::encode(message), 2);
+ emitPutJITStubArgConstant(m_bytecodeIndex, 3);
+ emitCTICall(Interpreter::cti_op_new_error);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_new_error);
+ }
+ case op_debug: {
+ emitPutJITStubArgConstant(currentInstruction[1].u.operand, 1);
+ emitPutJITStubArgConstant(currentInstruction[2].u.operand, 2);
+ emitPutJITStubArgConstant(currentInstruction[3].u.operand, 3);
+ emitCTICall(Interpreter::cti_op_debug);
+ NEXT_OPCODE(op_debug);
+ }
+ case op_eq_null: {
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned src1 = currentInstruction[2].u.operand;
+
+ emitGetVirtualRegister(src1, X86::eax);
+ Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
+
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ setnz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), X86::eax);
+
+ Jump wasNotImmediate = jump();
+
+ isImmediate.link(this);
+
+ andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
+ sete32(Imm32(JSImmediate::FullTagTypeNull), X86::eax);
+
+ wasNotImmediate.link(this);
+
+ emitTagAsBoolImmediate(X86::eax);
+ emitPutVirtualRegister(dst);
+
+ NEXT_OPCODE(op_eq_null);
+ }
+ case op_neq_null: {
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned src1 = currentInstruction[2].u.operand;
+
+ emitGetVirtualRegister(src1, X86::eax);
+ Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
+
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ setz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), X86::eax);
+
+ Jump wasNotImmediate = jump();
+
+ isImmediate.link(this);
+
+ andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
+ setne32(Imm32(JSImmediate::FullTagTypeNull), X86::eax);
+
+ wasNotImmediate.link(this);
+
+ emitTagAsBoolImmediate(X86::eax);
+ emitPutVirtualRegister(dst);
+
+ NEXT_OPCODE(op_neq_null);
+ }
+ case op_enter: {
+ // Even though CTI doesn't use them, we initialize our constant
+ // registers to zap stale pointers, to avoid unnecessarily prolonging
+ // object lifetime and increasing GC pressure.
+ size_t count = m_codeBlock->m_numVars + m_codeBlock->numberOfConstantRegisters();
+ for (size_t j = 0; j < count; ++j)
+ emitInitRegister(j);
+
+ NEXT_OPCODE(op_enter);
+ }
+ case op_enter_with_activation: {
+ // Even though CTI doesn't use them, we initialize our constant
+ // registers to zap stale pointers, to avoid unnecessarily prolonging
+ // object lifetime and increasing GC pressure.
+ size_t count = m_codeBlock->m_numVars + m_codeBlock->numberOfConstantRegisters();
+ for (size_t j = 0; j < count; ++j)
+ emitInitRegister(j);
+
+ emitCTICall(Interpreter::cti_op_push_activation);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+
+ NEXT_OPCODE(op_enter_with_activation);
+ }
+ case op_create_arguments: {
+ if (m_codeBlock->m_numParameters == 1)
+ emitCTICall(Interpreter::cti_op_create_arguments_no_params);
+ else
+ emitCTICall(Interpreter::cti_op_create_arguments);
+ NEXT_OPCODE(op_create_arguments);
+ }
+ case op_convert_this: {
+ emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+
+ emitJumpSlowCaseIfNotJSCell(X86::eax);
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::edx);
+ addSlowCase(jnz32(Address(X86::edx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+
+ NEXT_OPCODE(op_convert_this);
+ }
+ case op_profile_will_call: {
+ emitGetCTIParam(STUB_ARGS_profilerReference, X86::eax);
+ Jump noProfiler = jzPtr(Address(X86::eax));
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::eax);
+ emitCTICall(Interpreter::cti_op_profile_will_call);
+ noProfiler.link(this);
+
+ NEXT_OPCODE(op_profile_will_call);
+ }
+ case op_profile_did_call: {
+ emitGetCTIParam(STUB_ARGS_profilerReference, X86::eax);
+ Jump noProfiler = jzPtr(Address(X86::eax));
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::eax);
+ emitCTICall(Interpreter::cti_op_profile_did_call);
+ noProfiler.link(this);
+
+ NEXT_OPCODE(op_profile_did_call);
+ }
+ case op_get_array_length:
+ case op_get_by_id_chain:
+ case op_get_by_id_generic:
+ case op_get_by_id_proto:
+ case op_get_by_id_proto_list:
+ case op_get_by_id_self:
+ case op_get_by_id_self_list:
+ case op_get_string_length:
+ case op_put_by_id_generic:
+ case op_put_by_id_replace:
+ case op_put_by_id_transition:
+ ASSERT_NOT_REACHED();
+ }
+ }
+
+ ASSERT(propertyAccessInstructionIndex == m_codeBlock->numberOfStructureStubInfos());
+ ASSERT(callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
+
+#ifndef NDEBUG
+ // reset this, in order to guard it's use with asserts
+ m_bytecodeIndex = (unsigned)-1;
+#endif
+}
+
+
+void JIT::privateCompileLinkPass()
+{
+ unsigned jmpTableCount = m_jmpTable.size();
+ for (unsigned i = 0; i < jmpTableCount; ++i)
+ m_jmpTable[i].from.linkTo(m_labels[m_jmpTable[i].toBytecodeIndex], this);
+ m_jmpTable.clear();
+}
+
+void JIT::privateCompileSlowCases()
+{
+ Instruction* instructionsBegin = m_codeBlock->instructions().begin();
+ unsigned propertyAccessInstructionIndex = 0;
+ unsigned callLinkInfoIndex = 0;
+
+ for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end();) {
+ // FIXME: enable peephole optimizations for slow cases when applicable
+ killLastResultRegister();
+
+ m_bytecodeIndex = iter->to;
+#ifndef NDEBUG
+ unsigned firstTo = m_bytecodeIndex;
+#endif
+ Instruction* currentInstruction = instructionsBegin + m_bytecodeIndex;
+
+ switch (OpcodeID opcodeID = m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
+ case op_convert_this: {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_convert_this);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_convert_this);
+ }
+ case op_add: {
+ compileFastArithSlow_op_add(currentInstruction, iter);
+ NEXT_OPCODE(op_add);
+ }
+ case op_construct_verify: {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+
+ NEXT_OPCODE(op_construct_verify);
+ }
+ case op_get_by_val: {
+ // The slow case that handles accesses to arrays (below) may jump back up to here.
+ Label beginGetByValSlow(this);
+
+ Jump notImm = getSlowCase(iter);
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
+ notImm.link(this);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitCTICall(Interpreter::cti_op_get_by_val);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
+
+ // This is slow case that handles accesses to arrays above the fast cut-off.
+ // First, check if this is an access to the vector
+ linkSlowCase(iter);
+ jae32(X86::edx, Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_vectorLength)), beginGetByValSlow);
+
+ // okay, missed the fast region, but it is still in the vector. Get the value.
+ loadPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), X86::ecx);
+ // Check whether the value loaded is zero; if so we need to return undefined.
+ jzPtr(X86::ecx, beginGetByValSlow);
+ move(X86::ecx, X86::eax);
+ emitPutVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+
+ NEXT_OPCODE(op_get_by_val);
+ }
+ case op_sub: {
+ compileFastArithSlow_op_sub(currentInstruction, iter);
+ NEXT_OPCODE(op_sub);
+ }
+ case op_rshift: {
+ compileFastArithSlow_op_rshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter);
+ NEXT_OPCODE(op_rshift);
+ }
+ case op_lshift: {
+ compileFastArithSlow_op_lshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter);
+ NEXT_OPCODE(op_lshift);
+ }
+ case op_loop_if_less: {
+ unsigned op2 = currentInstruction[2].u.operand;
+ unsigned target = currentInstruction[3].u.operand;
+ if (isOperandConstantImmediateInt(op2)) {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_loop_if_less);
+ emitJumpSlowToHot(jnz32(X86::eax), target + 3);
+ } else {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitCTICall(Interpreter::cti_op_loop_if_less);
+ emitJumpSlowToHot(jnz32(X86::eax), target + 3);
+ }
+ NEXT_OPCODE(op_loop_if_less);
+ }
+ case op_put_by_id: {
+ compilePutByIdSlowCase(currentInstruction[1].u.operand, &(m_codeBlock->identifier(currentInstruction[2].u.operand)), currentInstruction[3].u.operand, iter, propertyAccessInstructionIndex++);
+ NEXT_OPCODE(op_put_by_id);
+ }
+ case op_get_by_id: {
+ compileGetByIdSlowCase(currentInstruction[1].u.operand, currentInstruction[2].u.operand, &(m_codeBlock->identifier(currentInstruction[3].u.operand)), iter, propertyAccessInstructionIndex++);
+ NEXT_OPCODE(op_get_by_id);
+ }
+ case op_loop_if_lesseq: {
+ unsigned op2 = currentInstruction[2].u.operand;
+ unsigned target = currentInstruction[3].u.operand;
+ if (isOperandConstantImmediateInt(op2)) {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_loop_if_lesseq);
+ emitJumpSlowToHot(jnz32(X86::eax), target + 3);
+ } else {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitCTICall(Interpreter::cti_op_loop_if_lesseq);
+ emitJumpSlowToHot(jnz32(X86::eax), target + 3);
+ }
+ NEXT_OPCODE(op_loop_if_lesseq);
+ }
+ case op_pre_inc: {
+ compileFastArithSlow_op_pre_inc(currentInstruction[1].u.operand, iter);
+ NEXT_OPCODE(op_pre_inc);
+ }
+ case op_put_by_val: {
+ // Normal slow cases - either is not an immediate imm, or is an array.
+ Jump notImm = getSlowCase(iter);
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
+ notImm.link(this);
+ emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitPutJITStubArg(X86::ecx, 3);
+ emitCTICall(Interpreter::cti_op_put_by_val);
+ emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_put_by_val));
+
+ // slow cases for immediate int accesses to arrays
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitPutJITStubArg(X86::ecx, 3);
+ emitCTICall(Interpreter::cti_op_put_by_val_array);
+
+ NEXT_OPCODE(op_put_by_val);
+ }
+ case op_loop_if_true: {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_jtrue);
+ unsigned target = currentInstruction[2].u.operand;
+ emitJumpSlowToHot(jnz32(X86::eax), target + 2);
+ NEXT_OPCODE(op_loop_if_true);
+ }
+ case op_pre_dec: {
+ compileFastArithSlow_op_pre_dec(currentInstruction[1].u.operand, iter);
+ NEXT_OPCODE(op_pre_dec);
+ }
+ case op_jnless: {
+ unsigned op2 = currentInstruction[2].u.operand;
+ unsigned target = currentInstruction[3].u.operand;
+ if (isOperandConstantImmediateInt(op2)) {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_jless);
+ emitJumpSlowToHot(jz32(X86::eax), target + 3);
+ } else {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitCTICall(Interpreter::cti_op_jless);
+ emitJumpSlowToHot(jz32(X86::eax), target + 3);
+ }
+ NEXT_OPCODE(op_jnless);
+ }
+ case op_not: {
+ linkSlowCase(iter);
+ xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), X86::eax);
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_not);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_not);
+ }
+ case op_jfalse: {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_jtrue);
+ unsigned target = currentInstruction[2].u.operand;
+ emitJumpSlowToHot(jz32(X86::eax), target + 2); // inverted!
+ NEXT_OPCODE(op_jfalse);
+ }
+ case op_post_inc: {
+ compileFastArithSlow_op_post_inc(currentInstruction[1].u.operand, currentInstruction[2].u.operand, iter);
+ NEXT_OPCODE(op_post_inc);
+ }
+ case op_bitnot: {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_bitnot);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_bitnot);
+ }
+ case op_bitand: {
+ compileFastArithSlow_op_bitand(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter);
+ NEXT_OPCODE(op_bitand);
+ }
+ case op_jtrue: {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_jtrue);
+ unsigned target = currentInstruction[2].u.operand;
+ emitJumpSlowToHot(jnz32(X86::eax), target + 2);
+ NEXT_OPCODE(op_jtrue);
+ }
+ case op_post_dec: {
+ compileFastArithSlow_op_post_dec(currentInstruction[1].u.operand, currentInstruction[2].u.operand, iter);
+ NEXT_OPCODE(op_post_dec);
+ }
+ case op_bitxor: {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitCTICall(Interpreter::cti_op_bitxor);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_bitxor);
+ }
+ case op_bitor: {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitCTICall(Interpreter::cti_op_bitor);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_bitor);
+ }
+ case op_eq: {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitCTICall(Interpreter::cti_op_eq);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_eq);
+ }
+ case op_neq: {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitCTICall(Interpreter::cti_op_neq);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_neq);
+ }
+ case op_stricteq: {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+#if !USE(ALTERNATE_JSIMMEDIATE)
+ linkSlowCase(iter);
+#endif
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitCTICall(Interpreter::cti_op_stricteq);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_stricteq);
+ }
+ case op_nstricteq: {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+#if !USE(ALTERNATE_JSIMMEDIATE)
+ linkSlowCase(iter);
+#endif
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ emitCTICall(Interpreter::cti_op_nstricteq);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_nstricteq);
+ }
+ case op_instanceof: {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[4].u.operand, 3, X86::ecx);
+ emitCTICall(Interpreter::cti_op_instanceof);
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_instanceof);
+ }
+ case op_mod: {
+ compileFastArithSlow_op_mod(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter);
+ NEXT_OPCODE(op_mod);
+ }
+ case op_mul: {
+ compileFastArithSlow_op_mul(currentInstruction, iter);
+ NEXT_OPCODE(op_mul);
+ }
+
+ case op_call: {
+ compileOpCallSlowCase(currentInstruction, iter, callLinkInfoIndex++, opcodeID);
+ NEXT_OPCODE(op_call);
+ }
+ case op_call_eval: {
+ compileOpCallSlowCase(currentInstruction, iter, callLinkInfoIndex++, opcodeID);
+ NEXT_OPCODE(op_call_eval);
+ }
+ case op_construct: {
+ compileOpCallSlowCase(currentInstruction, iter, callLinkInfoIndex++, opcodeID);
+ NEXT_OPCODE(op_construct);
+ }
+ case op_to_jsnumber: {
+ linkSlowCaseIfNotJSCell(iter, currentInstruction[2].u.operand);
+ linkSlowCase(iter);
+
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_to_jsnumber);
+
+ emitPutVirtualRegister(currentInstruction[1].u.operand);
+ NEXT_OPCODE(op_to_jsnumber);
+ }
+
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ ASSERT_WITH_MESSAGE(iter == m_slowCases.end() || firstTo != iter->to,"Not enough jumps linked in slow case codegen.");
+ ASSERT_WITH_MESSAGE(firstTo == (iter - 1)->to, "Too many jumps linked in slow case codegen.");
+
+ emitJumpSlowToHot(jump(), 0);
+ }
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+ ASSERT(propertyAccessInstructionIndex == m_codeBlock->numberOfStructureStubInfos());
+#endif
+ ASSERT(callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
+
+#ifndef NDEBUG
+ // reset this, in order to guard it's use with asserts
+ m_bytecodeIndex = (unsigned)-1;
+#endif
+}
+
+void JIT::privateCompile()
+{
+ sampleCodeBlock(m_codeBlock);
+#if ENABLE(OPCODE_SAMPLING)
+ sampleInstruction(m_codeBlock->instructions().begin());
+#endif
+
+ // Could use a pop_m, but would need to offset the following instruction if so.
+ pop(X86::ecx);
+ emitPutToCallFrameHeader(X86::ecx, RegisterFile::ReturnPC);
+
+ Jump slowRegisterFileCheck;
+ Label afterRegisterFileCheck;
+ if (m_codeBlock->codeType() == FunctionCode) {
+ // In the case of a fast linked call, we do not set this up in the caller.
+ emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock);
+
+ emitGetCTIParam(STUB_ARGS_registerFile, X86::eax);
+ addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, X86::edx);
+
+ slowRegisterFileCheck = jg32(X86::edx, Address(X86::eax, FIELD_OFFSET(RegisterFile, m_end)));
+ afterRegisterFileCheck = label();
+ }
+
+ privateCompileMainPass();
+ privateCompileLinkPass();
+ privateCompileSlowCases();
+
+ if (m_codeBlock->codeType() == FunctionCode) {
+ slowRegisterFileCheck.link(this);
+ m_bytecodeIndex = 0; // emitCTICall will add to the map, but doesn't actually need this...
+ emitCTICall(Interpreter::cti_register_file_check);
+#ifndef NDEBUG
+ // reset this, in order to guard it's use with asserts
+ m_bytecodeIndex = (unsigned)-1;
+#endif
+ jump(afterRegisterFileCheck);
+ }
+
+ ASSERT(m_jmpTable.isEmpty());
+
+ RefPtr<ExecutablePool> allocator = m_globalData->poolForSize(m_assembler.size());
+ void* code = m_assembler.executableCopy(allocator.get());
+ JITCodeRef codeRef(code, allocator);
+#ifndef NDEBUG
+ codeRef.codeSize = m_assembler.size();
+#endif
+
+ PatchBuffer patchBuffer(code);
+
+ // Translate vPC offsets into addresses in JIT generated code, for switch tables.
+ for (unsigned i = 0; i < m_switches.size(); ++i) {
+ SwitchRecord record = m_switches[i];
+ unsigned bytecodeIndex = record.bytecodeIndex;
+
+ if (record.type != SwitchRecord::String) {
+ ASSERT(record.type == SwitchRecord::Immediate || record.type == SwitchRecord::Character);
+ ASSERT(record.jumpTable.simpleJumpTable->branchOffsets.size() == record.jumpTable.simpleJumpTable->ctiOffsets.size());
+
+ record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
+
+ for (unsigned j = 0; j < record.jumpTable.simpleJumpTable->branchOffsets.size(); ++j) {
+ unsigned offset = record.jumpTable.simpleJumpTable->branchOffsets[j];
+ record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.simpleJumpTable->ctiDefault;
+ }
+ } else {
+ ASSERT(record.type == SwitchRecord::String);
+
+ record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
+
+ StringJumpTable::StringOffsetTable::iterator end = record.jumpTable.stringJumpTable->offsetTable.end();
+ for (StringJumpTable::StringOffsetTable::iterator it = record.jumpTable.stringJumpTable->offsetTable.begin(); it != end; ++it) {
+ unsigned offset = it->second.branchOffset;
+ it->second.ctiOffset = offset ? patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.stringJumpTable->ctiDefault;
+ }
+ }
+ }
+
+ for (size_t i = 0; i < m_codeBlock->numberOfExceptionHandlers(); ++i) {
+ HandlerInfo& handler = m_codeBlock->exceptionHandler(i);
+ handler.nativeCode = patchBuffer.addressOf(m_labels[handler.target]);
+ }
+
+ for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+ if (iter->to)
+ patchBuffer.link(iter->from, iter->to);
+ }
+
+ if (m_codeBlock->hasExceptionInfo()) {
+ m_codeBlock->pcVector().reserveCapacity(m_calls.size());
+ for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter)
+ m_codeBlock->pcVector().append(PC(reinterpret_cast<void**>(patchBuffer.addressOf(iter->from)) - reinterpret_cast<void**>(code), iter->bytecodeIndex));
+ }
+
+ // Link absolute addresses for jsr
+ for (Vector<JSRInfo>::iterator iter = m_jsrSites.begin(); iter != m_jsrSites.end(); ++iter)
+ patchBuffer.setPtr(iter->storeLocation, patchBuffer.addressOf(iter->target));
+
+ for (unsigned i = 0; i < m_codeBlock->numberOfStructureStubInfos(); ++i) {
+ StructureStubInfo& info = m_codeBlock->structureStubInfo(i);
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+ info.callReturnLocation = patchBuffer.addressOf(m_propertyAccessCompilationInfo[i].callReturnLocation);
+ info.hotPathBegin = patchBuffer.addressOf(m_propertyAccessCompilationInfo[i].hotPathBegin);
+#else
+ info.callReturnLocation = 0;
+ info.hotPathBegin = 0;
+#endif
+ }
+ for (unsigned i = 0; i < m_codeBlock->numberOfCallLinkInfos(); ++i) {
+ CallLinkInfo& info = m_codeBlock->callLinkInfo(i);
+#if ENABLE(JIT_OPTIMIZE_CALL)
+ info.callReturnLocation = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].callReturnLocation);
+ info.hotPathBegin = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].hotPathBegin);
+ info.hotPathOther = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].hotPathOther);
+ info.coldPathOther = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].coldPathOther);
+#else
+ info.callReturnLocation = 0;
+ info.hotPathBegin = 0;
+ info.hotPathOther = 0;
+ info.coldPathOther = 0;
+#endif
+ }
+
+ m_codeBlock->setJITCode(codeRef);
+}
+
+void JIT::privateCompileCTIMachineTrampolines()
+{
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+ // (1) The first function provides fast property access for array length
+ Label arrayLengthBegin = align();
+
+ // Check eax is an array
+ Jump array_failureCases1 = emitJumpIfNotJSCell(X86::eax);
+ Jump array_failureCases2 = jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr));
+
+ // Checks out okay! - get the length from the storage
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::eax);
+ load32(Address(X86::eax, FIELD_OFFSET(ArrayStorage, m_length)), X86::eax);
+
+ Jump array_failureCases3 = ja32(X86::eax, Imm32(JSImmediate::maxImmediateInt));
+
+ // X86::eax contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+
+ ret();
+
+ // (2) The second function provides fast property access for string length
+ Label stringLengthBegin = align();
+
+ // Check eax is a string
+ Jump string_failureCases1 = emitJumpIfNotJSCell(X86::eax);
+ Jump string_failureCases2 = jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsStringVptr));
+
+ // Checks out okay! - get the length from the Ustring.
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSString, m_value) + FIELD_OFFSET(UString, m_rep)), X86::eax);
+ load32(Address(X86::eax, FIELD_OFFSET(UString::Rep, len)), X86::eax);
+
+ Jump string_failureCases3 = ja32(X86::eax, Imm32(JSImmediate::maxImmediateInt));
+
+ // X86::eax contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+
+ ret();
+#endif
+
+ // (3) Trampolines for the slow cases of op_call / op_call_eval / op_construct.
+
+ Label virtualCallPreLinkBegin = align();
+
+ // Load the callee CodeBlock* into eax
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
+ loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
+ Jump hasCodeBlock1 = jnzPtr(X86::eax);
+ pop(X86::ebx);
+ restoreArgumentReference();
+ Jump callJSFunction1 = call();
+ emitGetJITStubArg(1, X86::ecx);
+ emitGetJITStubArg(3, X86::edx);
+ push(X86::ebx);
+ hasCodeBlock1.link(this);
+
+ // Check argCount matches callee arity.
+ Jump arityCheckOkay1 = je32(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
+ pop(X86::ebx);
+ emitPutJITStubArg(X86::ebx, 2);
+ emitPutJITStubArg(X86::eax, 4);
+ restoreArgumentReference();
+ Jump callArityCheck1 = call();
+ move(X86::edx, callFrameRegister);
+ emitGetJITStubArg(1, X86::ecx);
+ emitGetJITStubArg(3, X86::edx);
+ push(X86::ebx);
+ arityCheckOkay1.link(this);
+
+ compileOpCallInitializeCallFrame();
+
+ pop(X86::ebx);
+ emitPutJITStubArg(X86::ebx, 2);
+ restoreArgumentReference();
+ Jump callDontLazyLinkCall = call();
+ push(X86::ebx);
+
+ jump(X86::eax);
+
+ Label virtualCallLinkBegin = align();
+
+ // Load the callee CodeBlock* into eax
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
+ loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
+ Jump hasCodeBlock2 = jnzPtr(X86::eax);
+ pop(X86::ebx);
+ restoreArgumentReference();
+ Jump callJSFunction2 = call();
+ emitGetJITStubArg(1, X86::ecx);
+ emitGetJITStubArg(3, X86::edx);
+ push(X86::ebx);
+ hasCodeBlock2.link(this);
+
+ // Check argCount matches callee arity.
+ Jump arityCheckOkay2 = je32(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
+ pop(X86::ebx);
+ emitPutJITStubArg(X86::ebx, 2);
+ emitPutJITStubArg(X86::eax, 4);
+ restoreArgumentReference();
+ Jump callArityCheck2 = call();
+ move(X86::edx, callFrameRegister);
+ emitGetJITStubArg(1, X86::ecx);
+ emitGetJITStubArg(3, X86::edx);
+ push(X86::ebx);
+ arityCheckOkay2.link(this);
+
+ compileOpCallInitializeCallFrame();
+
+ pop(X86::ebx);
+ emitPutJITStubArg(X86::ebx, 2);
+ restoreArgumentReference();
+ Jump callLazyLinkCall = call();
+ push(X86::ebx);
+
+ jump(X86::eax);
+
+ Label virtualCallBegin = align();
+
+ // Load the callee CodeBlock* into eax
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
+ loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
+ Jump hasCodeBlock3 = jnzPtr(X86::eax);
+ pop(X86::ebx);
+ restoreArgumentReference();
+ Jump callJSFunction3 = call();
+ emitGetJITStubArg(1, X86::ecx);
+ emitGetJITStubArg(3, X86::edx);
+ push(X86::ebx);
+ hasCodeBlock3.link(this);
+
+ // Check argCount matches callee arity.
+ Jump arityCheckOkay3 = je32(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
+ pop(X86::ebx);
+ emitPutJITStubArg(X86::ebx, 2);
+ emitPutJITStubArg(X86::eax, 4);
+ restoreArgumentReference();
+ Jump callArityCheck3 = call();
+ move(X86::edx, callFrameRegister);
+ emitGetJITStubArg(1, X86::ecx);
+ emitGetJITStubArg(3, X86::edx);
+ push(X86::ebx);
+ arityCheckOkay3.link(this);
+
+ compileOpCallInitializeCallFrame();
+
+ // load ctiCode from the new codeBlock.
+ loadPtr(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_jitCode)), X86::eax);
+
+ jump(X86::eax);
+
+ // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
+ m_interpreter->m_executablePool = m_globalData->poolForSize(m_assembler.size());
+ void* code = m_assembler.executableCopy(m_interpreter->m_executablePool.get());
+ PatchBuffer patchBuffer(code);
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+ patchBuffer.link(array_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
+ patchBuffer.link(array_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
+ patchBuffer.link(array_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
+ patchBuffer.link(string_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
+ patchBuffer.link(string_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
+ patchBuffer.link(string_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
+
+ m_interpreter->m_ctiArrayLengthTrampoline = patchBuffer.addressOf(arrayLengthBegin);
+ m_interpreter->m_ctiStringLengthTrampoline = patchBuffer.addressOf(stringLengthBegin);
+#endif
+ patchBuffer.link(callArityCheck1, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
+ patchBuffer.link(callArityCheck2, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
+ patchBuffer.link(callArityCheck3, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
+ patchBuffer.link(callJSFunction1, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
+ patchBuffer.link(callJSFunction2, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
+ patchBuffer.link(callJSFunction3, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
+ patchBuffer.link(callDontLazyLinkCall, reinterpret_cast<void*>(Interpreter::cti_vm_dontLazyLinkCall));
+ patchBuffer.link(callLazyLinkCall, reinterpret_cast<void*>(Interpreter::cti_vm_lazyLinkCall));
+
+ m_interpreter->m_ctiVirtualCallPreLink = patchBuffer.addressOf(virtualCallPreLinkBegin);
+ m_interpreter->m_ctiVirtualCallLink = patchBuffer.addressOf(virtualCallLinkBegin);
+ m_interpreter->m_ctiVirtualCall = patchBuffer.addressOf(virtualCallBegin);
+}
+
+void JIT::emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst)
+{
+ loadPtr(Address(variableObject, FIELD_OFFSET(JSVariableObject, d)), dst);
+ loadPtr(Address(dst, FIELD_OFFSET(JSVariableObject::JSVariableObjectData, registers)), dst);
+ loadPtr(Address(dst, index * sizeof(Register)), dst);
+}
+
+void JIT::emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index)
+{
+ loadPtr(Address(variableObject, FIELD_OFFSET(JSVariableObject, d)), variableObject);
+ loadPtr(Address(variableObject, FIELD_OFFSET(JSVariableObject::JSVariableObjectData, registers)), variableObject);
+ storePtr(src, Address(variableObject, index * sizeof(Register)));
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
new file mode 100644
index 0000000..d13fbb5
--- /dev/null
+++ b/JavaScriptCore/jit/JIT.h
@@ -0,0 +1,577 @@
+/*
+ * 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 JIT_h
+#define JIT_h
+
+#include <wtf/Platform.h>
+#include <bytecode/SamplingTool.h>
+
+#if ENABLE(JIT)
+
+#define WTF_USE_CTI_REPATCH_PIC 1
+
+#include "Interpreter.h"
+#include "Opcode.h"
+#include "RegisterFile.h"
+#include "MacroAssembler.h"
+#include "Profiler.h"
+#include <wtf/AlwaysInline.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(X86_64)
+#define STUB_ARGS_offset 0x10
+#else
+#define STUB_ARGS_offset 0x0C
+#endif
+
+#define STUB_ARGS_code (STUB_ARGS_offset)
+#define STUB_ARGS_registerFile (STUB_ARGS_offset + 1)
+#define STUB_ARGS_callFrame (STUB_ARGS_offset + 2)
+#define STUB_ARGS_exception (STUB_ARGS_offset + 3)
+#define STUB_ARGS_profilerReference (STUB_ARGS_offset + 4)
+#define STUB_ARGS_globalData (STUB_ARGS_offset + 5)
+
+#define ARG_callFrame static_cast<CallFrame*>(ARGS[STUB_ARGS_callFrame])
+#define ARG_registerFile static_cast<RegisterFile*>(ARGS[STUB_ARGS_registerFile])
+#define ARG_exception static_cast<JSValuePtr*>(ARGS[STUB_ARGS_exception])
+#define ARG_profilerReference static_cast<Profiler**>(ARGS[STUB_ARGS_profilerReference])
+#define ARG_globalData static_cast<JSGlobalData*>(ARGS[STUB_ARGS_globalData])
+
+#define ARG_setCallFrame(newCallFrame) (ARGS[STUB_ARGS_callFrame] = (newCallFrame))
+
+#define ARG_src1 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[1]))
+#define ARG_src2 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[2]))
+#define ARG_src3 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[3]))
+#define ARG_src4 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[4]))
+#define ARG_src5 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[5]))
+#define ARG_id1 static_cast<Identifier*>(ARGS[1])
+#define ARG_id2 static_cast<Identifier*>(ARGS[2])
+#define ARG_id3 static_cast<Identifier*>(ARGS[3])
+#define ARG_id4 static_cast<Identifier*>(ARGS[4])
+#define ARG_int1 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[1]))
+#define ARG_int2 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[2]))
+#define ARG_int3 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[3]))
+#define ARG_int4 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[4]))
+#define ARG_int5 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[5]))
+#define ARG_int6 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[6]))
+#define ARG_func1 static_cast<FuncDeclNode*>(ARGS[1])
+#define ARG_funcexp1 static_cast<FuncExprNode*>(ARGS[1])
+#define ARG_regexp1 static_cast<RegExp*>(ARGS[1])
+#define ARG_pni1 static_cast<JSPropertyNameIterator*>(ARGS[1])
+#define ARG_returnAddress2 static_cast<void*>(ARGS[2])
+#define ARG_codeBlock4 static_cast<CodeBlock*>(ARGS[4])
+
+#define STUB_RETURN_ADDRESS_SLOT (ARGS[-1])
+
+namespace JSC {
+
+ class CodeBlock;
+ class JSPropertyNameIterator;
+ class Interpreter;
+ class Register;
+ class RegisterFile;
+ class ScopeChainNode;
+ class SimpleJumpTable;
+ class StringJumpTable;
+ class StructureChain;
+
+ struct CallLinkInfo;
+ struct Instruction;
+ struct OperandTypes;
+ struct PolymorphicAccessStructureList;
+ struct StructureStubInfo;
+
+ typedef JSValueEncodedAsPointer* (JIT_STUB *CTIHelper_j)(STUB_ARGS);
+ typedef JSObject* (JIT_STUB *CTIHelper_o)(STUB_ARGS);
+ typedef JSPropertyNameIterator* (JIT_STUB *CTIHelper_p)(STUB_ARGS);
+ typedef void (JIT_STUB *CTIHelper_v)(STUB_ARGS);
+ typedef void* (JIT_STUB *CTIHelper_s)(STUB_ARGS);
+ typedef int (JIT_STUB *CTIHelper_b)(STUB_ARGS);
+ typedef VoidPtrPair (JIT_STUB *CTIHelper_2)(STUB_ARGS);
+
+ struct CallRecord {
+ MacroAssembler::Jump from;
+ unsigned bytecodeIndex;
+ void* to;
+
+ CallRecord()
+ {
+ }
+
+ CallRecord(MacroAssembler::Jump from, unsigned bytecodeIndex, void* to = 0)
+ : from(from)
+ , bytecodeIndex(bytecodeIndex)
+ , to(to)
+ {
+ }
+ };
+
+ struct JumpTable {
+ MacroAssembler::Jump from;
+ unsigned toBytecodeIndex;
+
+ JumpTable(MacroAssembler::Jump f, unsigned t)
+ : from(f)
+ , toBytecodeIndex(t)
+ {
+ }
+ };
+
+ struct SlowCaseEntry {
+ MacroAssembler::Jump from;
+ unsigned to;
+ unsigned hint;
+
+ SlowCaseEntry(MacroAssembler::Jump f, unsigned t, unsigned h = 0)
+ : from(f)
+ , to(t)
+ , hint(h)
+ {
+ }
+ };
+
+ struct SwitchRecord {
+ enum Type {
+ Immediate,
+ Character,
+ String
+ };
+
+ Type type;
+
+ union {
+ SimpleJumpTable* simpleJumpTable;
+ StringJumpTable* stringJumpTable;
+ } jumpTable;
+
+ unsigned bytecodeIndex;
+ unsigned defaultOffset;
+
+ SwitchRecord(SimpleJumpTable* jumpTable, unsigned bytecodeIndex, unsigned defaultOffset, Type type)
+ : type(type)
+ , bytecodeIndex(bytecodeIndex)
+ , defaultOffset(defaultOffset)
+ {
+ this->jumpTable.simpleJumpTable = jumpTable;
+ }
+
+ SwitchRecord(StringJumpTable* jumpTable, unsigned bytecodeIndex, unsigned defaultOffset)
+ : type(String)
+ , bytecodeIndex(bytecodeIndex)
+ , defaultOffset(defaultOffset)
+ {
+ this->jumpTable.stringJumpTable = jumpTable;
+ }
+ };
+
+ struct PropertyStubCompilationInfo {
+ MacroAssembler::Jump callReturnLocation;
+ MacroAssembler::Label hotPathBegin;
+ };
+
+ struct StructureStubCompilationInfo {
+ MacroAssembler::DataLabelPtr hotPathBegin;
+ MacroAssembler::Jump hotPathOther;
+ MacroAssembler::Jump callReturnLocation;
+ MacroAssembler::Label coldPathOther;
+ };
+
+ extern "C" {
+ JSValueEncodedAsPointer* ctiTrampoline(
+#if PLATFORM(X86_64)
+ // FIXME: (bug #22910) this will force all arguments onto the stack (regparm(0) does not appear to have any effect).
+ // We can allow register passing here, and move the writes of these values into the trampoline.
+ void*, void*, void*, void*, void*, void*,
+#endif
+ void* code, RegisterFile*, CallFrame*, JSValuePtr* exception, Profiler**, JSGlobalData*);
+ void ctiVMThrowTrampoline();
+ };
+
+ void ctiSetReturnAddress(void** where, void* what);
+ void ctiPatchCallByReturnAddress(void* where, void* what);
+
+ class JIT : private MacroAssembler {
+ using MacroAssembler::Jump;
+ using MacroAssembler::JumpList;
+ using MacroAssembler::Label;
+
+#if PLATFORM(X86_64)
+ static const RegisterID timeoutCheckRegister = X86::r12;
+ static const RegisterID callFrameRegister = X86::r13;
+ static const RegisterID tagTypeNumberRegister = X86::r14;
+ static const RegisterID tagMaskRegister = X86::r15;
+#else
+ static const RegisterID timeoutCheckRegister = X86::esi;
+ static const RegisterID callFrameRegister = X86::edi;
+#endif
+
+ static const int patchGetByIdDefaultStructure = -1;
+ // Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler
+ // will compress the displacement, and we may not be able to fit a patched offset.
+ static const int patchGetByIdDefaultOffset = 256;
+
+#if USE(JIT_STUB_ARGUMENT_REGISTER)
+#if PLATFORM(X86_64)
+ static const int ctiArgumentInitSize = 6;
+#else
+ static const int ctiArgumentInitSize = 2;
+#endif
+#elif USE(JIT_STUB_ARGUMENT_STACK)
+ static const int ctiArgumentInitSize = 4;
+#else // JIT_STUB_ARGUMENT_VA_LIST
+ static const int ctiArgumentInitSize = 0;
+#endif
+
+#if PLATFORM(X86_64)
+ // These architecture specific value are used to enable patching - see comment on op_put_by_id.
+ static const int patchOffsetPutByIdStructure = 10;
+ static const int patchOffsetPutByIdPropertyMapOffset = 31;
+ // These architecture specific value are used to enable patching - see comment on op_get_by_id.
+ static const int patchOffsetGetByIdStructure = 10;
+ static const int patchOffsetGetByIdBranchToSlowCase = 20;
+ static const int patchOffsetGetByIdPropertyMapOffset = 31;
+ static const int patchOffsetGetByIdPutResult = 31;
+#if ENABLE(OPCODE_SAMPLING)
+ static const int patchOffsetGetByIdSlowCaseCall = 53 + ctiArgumentInitSize;
+#else
+ static const int patchOffsetGetByIdSlowCaseCall = 30 + ctiArgumentInitSize;
+#endif
+ static const int patchOffsetOpCallCompareToJump = 9;
+#else
+ // These architecture specific value are used to enable patching - see comment on op_put_by_id.
+ static const int patchOffsetPutByIdStructure = 7;
+ static const int patchOffsetPutByIdPropertyMapOffset = 22;
+ // These architecture specific value are used to enable patching - see comment on op_get_by_id.
+ static const int patchOffsetGetByIdStructure = 7;
+ static const int patchOffsetGetByIdBranchToSlowCase = 13;
+ static const int patchOffsetGetByIdPropertyMapOffset = 22;
+ static const int patchOffsetGetByIdPutResult = 22;
+#if ENABLE(OPCODE_SAMPLING)
+ static const int patchOffsetGetByIdSlowCaseCall = 31 + ctiArgumentInitSize;
+#else
+ static const int patchOffsetGetByIdSlowCaseCall = 21 + ctiArgumentInitSize;
+#endif
+ static const int patchOffsetOpCallCompareToJump = 6;
+#endif
+
+ public:
+ static void compile(JSGlobalData* globalData, CodeBlock* codeBlock)
+ {
+ JIT jit(globalData, codeBlock);
+ jit.privateCompile();
+ }
+
+ static void compileGetByIdSelf(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+ {
+ JIT jit(globalData, codeBlock);
+ jit.privateCompileGetByIdSelf(stubInfo, structure, cachedOffset, returnAddress);
+ }
+
+ static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, void* returnAddress)
+ {
+ JIT jit(globalData, codeBlock);
+ jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, cachedOffset, returnAddress, callFrame);
+ }
+
+#if USE(CTI_REPATCH_PIC)
+ static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset)
+ {
+ JIT jit(globalData, codeBlock);
+ jit.privateCompileGetByIdSelfList(stubInfo, polymorphicStructures, currentIndex, structure, cachedOffset);
+ }
+ static void compileGetByIdProtoList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset)
+ {
+ JIT jit(globalData, codeBlock);
+ jit.privateCompileGetByIdProtoList(stubInfo, prototypeStructureList, currentIndex, structure, prototypeStructure, 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)
+ {
+ JIT jit(globalData, codeBlock);
+ jit.privateCompileGetByIdChainList(stubInfo, prototypeStructureList, currentIndex, structure, chain, count, cachedOffset, callFrame);
+ }
+#endif
+
+ static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, void* returnAddress)
+ {
+ JIT jit(globalData, codeBlock);
+ jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, cachedOffset, returnAddress, callFrame);
+ }
+
+ static void compilePutByIdReplace(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+ {
+ JIT jit(globalData, codeBlock);
+ jit.privateCompilePutByIdReplace(stubInfo, structure, cachedOffset, returnAddress);
+ }
+
+ static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, void* returnAddress)
+ {
+ JIT jit(globalData, codeBlock);
+ jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress);
+ }
+
+ static void compileCTIMachineTrampolines(JSGlobalData* globalData)
+ {
+ JIT jit(globalData);
+ jit.privateCompileCTIMachineTrampolines();
+ }
+
+ static void patchGetByIdSelf(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
+ static void patchPutByIdReplace(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
+
+ static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, void* returnAddress)
+ {
+ JIT jit(globalData, codeBlock);
+ return jit.privateCompilePatchGetArrayLength(returnAddress);
+ }
+
+ static void linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount);
+ static void unlinkCall(CallLinkInfo*);
+
+ inline static JSValuePtr execute(void* code, RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData, JSValuePtr* exception)
+ {
+ return JSValuePtr::decode(ctiTrampoline(
+#if PLATFORM(X86_64)
+ 0, 0, 0, 0, 0, 0,
+#endif
+ code, registerFile, callFrame, exception, Profiler::enabledProfilerReference(), globalData));
+ }
+
+ private:
+ JIT(JSGlobalData*, CodeBlock* = 0);
+
+ void privateCompileMainPass();
+ void privateCompileLinkPass();
+ void privateCompileSlowCases();
+ void privateCompile();
+ void privateCompileGetByIdSelf(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
+ void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, size_t cachedOffset, void* returnAddress, CallFrame* callFrame);
+#if USE(CTI_REPATCH_PIC)
+ void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, size_t cachedOffset);
+ void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame);
+ void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame);
+#endif
+ void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, size_t cachedOffset, void* returnAddress, CallFrame* callFrame);
+ void privateCompilePutByIdReplace(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
+ void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, void* returnAddress);
+
+ void privateCompileCTIMachineTrampolines();
+ void privateCompilePatchGetArrayLength(void* returnAddress);
+
+ void addSlowCase(Jump);
+ void addJump(Jump, int);
+ void emitJumpSlowToHot(Jump, int);
+
+ void compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned propertyAccessInstructionIndex);
+ void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex);
+ void compilePutByIdHotPath(int baseVReg, Identifier* ident, int valueVReg, unsigned propertyAccessInstructionIndex);
+ void compilePutByIdSlowCase(int baseVReg, Identifier* ident, int valueVReg, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex);
+ void compileOpCall(OpcodeID, Instruction* instruction, unsigned callLinkInfoIndex);
+ void compileOpCallInitializeCallFrame();
+ void compileOpCallSetupArgs(Instruction*);
+ void compileOpCallEvalSetupArgs(Instruction*);
+ void compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex, OpcodeID opcodeID);
+ void compileOpConstructSetupArgs(Instruction*);
+ enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq };
+ void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type);
+ void putDoubleResultToJSNumberCellOrJSImmediate(X86Assembler::XMMRegisterID xmmSource, RegisterID jsNumberCell, unsigned dst, X86Assembler::JmpSrc* wroteJSNumberCell, X86Assembler::XMMRegisterID tempXmm, RegisterID tempReg1, RegisterID tempReg2);
+
+ void compileFastArith_op_add(Instruction*);
+ void compileFastArith_op_sub(Instruction*);
+ void compileFastArith_op_mul(Instruction*);
+ void compileFastArith_op_mod(unsigned result, unsigned op1, unsigned op2);
+ void compileFastArith_op_bitand(unsigned result, unsigned op1, unsigned op2);
+ void compileFastArith_op_lshift(unsigned result, unsigned op1, unsigned op2);
+ void compileFastArith_op_rshift(unsigned result, unsigned op1, unsigned op2);
+ void compileFastArith_op_pre_inc(unsigned srcDst);
+ void compileFastArith_op_pre_dec(unsigned srcDst);
+ void compileFastArith_op_post_inc(unsigned result, unsigned srcDst);
+ void compileFastArith_op_post_dec(unsigned result, unsigned srcDst);
+ void compileFastArithSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void compileFastArithSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void compileFastArithSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void compileFastArithSlow_op_mod(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&);
+ void compileFastArithSlow_op_bitand(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&);
+ void compileFastArithSlow_op_lshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&);
+ void compileFastArithSlow_op_rshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&);
+ void compileFastArithSlow_op_pre_inc(unsigned srcDst, Vector<SlowCaseEntry>::iterator&);
+ void compileFastArithSlow_op_pre_dec(unsigned srcDst, Vector<SlowCaseEntry>::iterator&);
+ void compileFastArithSlow_op_post_inc(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator&);
+ void compileFastArithSlow_op_post_dec(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator&);
+#if ENABLE(JIT_OPTIMIZE_ARITHMETIC)
+ void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi);
+ void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi);
+#endif
+
+ void emitGetVirtualRegister(int src, RegisterID dst);
+ void emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2);
+ void emitPutVirtualRegister(unsigned dst, RegisterID from = X86::eax);
+
+ void emitPutJITStubArg(RegisterID src, unsigned argumentNumber);
+ void emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch);
+ void emitPutJITStubArgConstant(unsigned value, unsigned argumentNumber);
+ void emitPutJITStubArgConstant(void* value, unsigned argumentNumber);
+ void emitGetJITStubArg(unsigned argumentNumber, RegisterID dst);
+
+ void emitInitRegister(unsigned dst);
+
+ void emitPutCTIParam(void* value, unsigned name);
+ void emitPutCTIParam(RegisterID from, unsigned name);
+ void emitGetCTIParam(unsigned name, RegisterID to);
+
+ void emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry);
+ void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry);
+ void emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, RegisterID to);
+
+ JSValuePtr getConstantOperand(unsigned src);
+ int32_t getConstantOperandImmediateInt(unsigned src);
+ bool isOperandConstantImmediateInt(unsigned src);
+
+ Jump emitJumpIfJSCell(RegisterID);
+ Jump emitJumpIfBothJSCells(RegisterID, RegisterID, RegisterID);
+ void emitJumpSlowCaseIfJSCell(RegisterID);
+ Jump emitJumpIfNotJSCell(RegisterID);
+ void emitJumpSlowCaseIfNotJSCell(RegisterID);
+ void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ JIT::Jump emitJumpIfImmediateNumber(RegisterID);
+ JIT::Jump emitJumpIfNotImmediateNumber(RegisterID);
+#endif
+
+ Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter)
+ {
+ return iter++->from;
+ }
+ void linkSlowCase(Vector<SlowCaseEntry>::iterator& iter)
+ {
+ iter->from.link(this);
+ ++iter;
+ }
+ void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, int vReg);
+
+ JIT::Jump emitJumpIfImmediateInteger(RegisterID);
+ JIT::Jump emitJumpIfNotImmediateInteger(RegisterID);
+ JIT::Jump emitJumpIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
+ void emitJumpSlowCaseIfNotImmediateInteger(RegisterID);
+ void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
+
+ Jump checkStructure(RegisterID reg, Structure* structure);
+
+#if !USE(ALTERNATE_JSIMMEDIATE)
+ void emitFastArithDeTagImmediate(RegisterID);
+ Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID);
+#endif
+ void emitFastArithReTagImmediate(RegisterID src, RegisterID dest);
+ void emitFastArithImmToInt(RegisterID);
+ void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest);
+
+ void emitTagAsBoolImmediate(RegisterID reg);
+
+ void restoreArgumentReference();
+ void restoreArgumentReferenceForTrampoline();
+
+ Jump emitNakedCall(RegisterID);
+ Jump emitNakedCall(void* function);
+ Jump emitCTICall_internal(void*);
+ Jump emitCTICall(CTIHelper_j helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Jump emitCTICall(CTIHelper_o helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Jump emitCTICall(CTIHelper_p helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Jump emitCTICall(CTIHelper_v helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Jump emitCTICall(CTIHelper_s helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Jump emitCTICall(CTIHelper_b helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Jump emitCTICall(CTIHelper_2 helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+
+ void emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst);
+ void emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index);
+
+ void emitSlowScriptCheck();
+#ifndef NDEBUG
+ void printBytecodeOperandTypes(unsigned src1, unsigned src2);
+#endif
+
+ void killLastResultRegister();
+
+#if ENABLE(CODEBLOCK_SAMPLING)
+ void sampleCodeBlock(CodeBlock* codeBlock)
+ {
+#if PLATFORM(X86_64)
+ move(ImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86::ecx);
+ storePtr(ImmPtr(codeBlock), X86::ecx);
+#else
+ storePtr(ImmPtr(codeBlock), m_interpreter->sampler()->codeBlockSlot());
+#endif
+ }
+#else
+ void sampleCodeBlock(CodeBlock*) {}
+#endif
+
+#if ENABLE(OPCODE_SAMPLING)
+ void sampleInstruction(Instruction* instruction, bool inHostFunction=false)
+ {
+#if PLATFORM(X86_64)
+ move(ImmPtr(m_interpreter->sampler()->sampleSlot()), X86::ecx);
+ storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), X86::ecx);
+#else
+ storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), m_interpreter->sampler()->sampleSlot());
+#endif
+ }
+#else
+ void sampleInstruction(Instruction*, bool) {}
+#endif
+
+ Interpreter* m_interpreter;
+ JSGlobalData* m_globalData;
+ CodeBlock* m_codeBlock;
+
+ Vector<CallRecord> m_calls;
+ Vector<Label> m_labels;
+ Vector<PropertyStubCompilationInfo> m_propertyAccessCompilationInfo;
+ Vector<StructureStubCompilationInfo> m_callStructureStubCompilationInfo;
+ Vector<JumpTable> m_jmpTable;
+
+ struct JSRInfo {
+ DataLabelPtr storeLocation;
+ Label target;
+
+ JSRInfo(DataLabelPtr storeLocation, Label targetLocation)
+ : storeLocation(storeLocation)
+ , target(targetLocation)
+ {
+ }
+ };
+
+ unsigned m_bytecodeIndex;
+ Vector<JSRInfo> m_jsrSites;
+ Vector<SlowCaseEntry> m_slowCases;
+ Vector<SwitchRecord> m_switches;
+
+ int m_lastResultBytecodeRegister;
+ unsigned m_jumpTargetsPosition;
+ };
+}
+
+#endif // ENABLE(JIT)
+
+#endif // JIT_h
diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp
new file mode 100644
index 0000000..0a3e9ab
--- /dev/null
+++ b/JavaScriptCore/jit/JITArithmetic.cpp
@@ -0,0 +1,974 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JIT.h"
+
+#if ENABLE(JIT)
+
+#include "CodeBlock.h"
+#include "JITInlineMethods.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "Interpreter.h"
+#include "ResultType.h"
+#include "SamplingTool.h"
+
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+#define __ m_assembler.
+
+using namespace std;
+
+namespace JSC {
+
+void JIT::compileFastArith_op_lshift(unsigned result, unsigned op1, unsigned op2)
+{
+ emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
+ // FIXME: would we be better using 'emitJumpSlowCaseIfNotImmediateIntegers'? - we *probably* ought to be consistent.
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::ecx);
+ emitFastArithImmToInt(X86::eax);
+ emitFastArithImmToInt(X86::ecx);
+#if !PLATFORM(X86)
+ // Mask with 0x1f as per ecma-262 11.7.2 step 7.
+ // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
+ and32(Imm32(0x1f), X86::ecx);
+#endif
+ lshift32(X86::ecx, X86::eax);
+#if !USE(ALTERNATE_JSIMMEDIATE)
+ addSlowCase(joAdd32(X86::eax, X86::eax));
+ signExtend32ToPtr(X86::eax, X86::eax);
+#endif
+ emitFastArithReTagImmediate(X86::eax, X86::eax);
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_lshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator& iter)
+{
+#if USE(ALTERNATE_JSIMMEDIATE)
+ UNUSED_PARAM(op1);
+ UNUSED_PARAM(op2);
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+#else
+ // If we are limited to 32-bit immediates there is a third slow case, which required the operands to have been reloaded.
+ Jump notImm1 = getSlowCase(iter);
+ Jump notImm2 = getSlowCase(iter);
+ linkSlowCase(iter);
+ emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
+ notImm1.link(this);
+ notImm2.link(this);
+#endif
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::ecx, 2);
+ emitCTICall(Interpreter::cti_op_lshift);
+ emitPutVirtualRegister(result);
+}
+
+void JIT::compileFastArith_op_rshift(unsigned result, unsigned op1, unsigned op2)
+{
+ if (isOperandConstantImmediateInt(op2)) {
+ emitGetVirtualRegister(op1, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ // Mask with 0x1f as per ecma-262 11.7.2 step 7.
+#if USE(ALTERNATE_JSIMMEDIATE)
+ rshift32(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), X86::eax);
+#else
+ rshiftPtr(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), X86::eax);
+#endif
+ } else {
+ emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::ecx);
+ emitFastArithImmToInt(X86::ecx);
+#if !PLATFORM(X86)
+ // Mask with 0x1f as per ecma-262 11.7.2 step 7.
+ // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
+ and32(Imm32(0x1f), X86::ecx);
+#endif
+#if USE(ALTERNATE_JSIMMEDIATE)
+ rshift32(X86::ecx, X86::eax);
+#else
+ rshiftPtr(X86::ecx, X86::eax);
+#endif
+ }
+#if USE(ALTERNATE_JSIMMEDIATE)
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+#else
+ orPtr(Imm32(JSImmediate::TagTypeNumber), X86::eax);
+#endif
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_rshift(unsigned result, unsigned, unsigned op2, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ if (isOperandConstantImmediateInt(op2))
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ else {
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::ecx, 2);
+ }
+
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_rshift);
+ emitPutVirtualRegister(result);
+}
+
+void JIT::compileFastArith_op_bitand(unsigned result, unsigned op1, unsigned op2)
+{
+ if (isOperandConstantImmediateInt(op1)) {
+ emitGetVirtualRegister(op2, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ int32_t imm = getConstantOperandImmediateInt(op1);
+ andPtr(Imm32(imm), X86::eax);
+ if (imm >= 0)
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+#else
+ andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)))), X86::eax);
+#endif
+ } else if (isOperandConstantImmediateInt(op2)) {
+ emitGetVirtualRegister(op1, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ int32_t imm = getConstantOperandImmediateInt(op2);
+ andPtr(Imm32(imm), X86::eax);
+ if (imm >= 0)
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+#else
+ andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)))), X86::eax);
+#endif
+ } else {
+ emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
+ andPtr(X86::edx, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ }
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_bitand(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ if (isOperandConstantImmediateInt(op1)) {
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArg(X86::eax, 2);
+ } else if (isOperandConstantImmediateInt(op2)) {
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ } else {
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArg(X86::edx, 2);
+ }
+ emitCTICall(Interpreter::cti_op_bitand);
+ emitPutVirtualRegister(result);
+}
+
+void JIT::compileFastArith_op_mod(unsigned result, unsigned op1, unsigned op2)
+{
+ emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::ecx);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ addSlowCase(jePtr(X86::ecx, ImmPtr(JSValuePtr::encode(js0()))));
+ mod32(X86::ecx, X86::eax, X86::edx);
+#else
+ emitFastArithDeTagImmediate(X86::eax);
+ addSlowCase(emitFastArithDeTagImmediateJumpIfZero(X86::ecx));
+ mod32(X86::ecx, X86::eax, X86::edx);
+ signExtend32ToPtr(X86::edx, X86::edx);
+#endif
+ emitFastArithReTagImmediate(X86::edx, X86::eax);
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_mod(unsigned result, unsigned, unsigned, Vector<SlowCaseEntry>::iterator& iter)
+{
+#if USE(ALTERNATE_JSIMMEDIATE)
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+#else
+ Jump notImm1 = getSlowCase(iter);
+ Jump notImm2 = getSlowCase(iter);
+ linkSlowCase(iter);
+ emitFastArithReTagImmediate(X86::eax, X86::eax);
+ emitFastArithReTagImmediate(X86::ecx, X86::ecx);
+ notImm1.link(this);
+ notImm2.link(this);
+#endif
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::ecx, 2);
+ emitCTICall(Interpreter::cti_op_mod);
+ emitPutVirtualRegister(result);
+}
+
+void JIT::compileFastArith_op_post_inc(unsigned result, unsigned srcDst)
+{
+ emitGetVirtualRegister(srcDst, X86::eax);
+ move(X86::eax, X86::edx);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ addSlowCase(joAdd32(Imm32(1), X86::edx));
+ emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
+#else
+ addSlowCase(joAdd32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::edx));
+ signExtend32ToPtr(X86::edx, X86::edx);
+#endif
+ emitPutVirtualRegister(srcDst, X86::edx);
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_post_inc(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_post_inc);
+ emitPutVirtualRegister(srcDst, X86::edx);
+ emitPutVirtualRegister(result);
+}
+
+void JIT::compileFastArith_op_post_dec(unsigned result, unsigned srcDst)
+{
+ emitGetVirtualRegister(srcDst, X86::eax);
+ move(X86::eax, X86::edx);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ addSlowCase(joSub32(Imm32(1), X86::edx));
+ emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
+#else
+ addSlowCase(joSub32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::edx));
+ signExtend32ToPtr(X86::edx, X86::edx);
+#endif
+ emitPutVirtualRegister(srcDst, X86::edx);
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_post_dec(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_post_dec);
+ emitPutVirtualRegister(srcDst, X86::edx);
+ emitPutVirtualRegister(result);
+}
+
+void JIT::compileFastArith_op_pre_inc(unsigned srcDst)
+{
+ emitGetVirtualRegister(srcDst, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ addSlowCase(joAdd32(Imm32(1), X86::eax));
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+#else
+ addSlowCase(joAdd32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::eax));
+ signExtend32ToPtr(X86::eax, X86::eax);
+#endif
+ emitPutVirtualRegister(srcDst);
+}
+void JIT::compileFastArithSlow_op_pre_inc(unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter)
+{
+ Jump notImm = getSlowCase(iter);
+ linkSlowCase(iter);
+ emitGetVirtualRegister(srcDst, X86::eax);
+ notImm.link(this);
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_pre_inc);
+ emitPutVirtualRegister(srcDst);
+}
+
+void JIT::compileFastArith_op_pre_dec(unsigned srcDst)
+{
+ emitGetVirtualRegister(srcDst, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+#if USE(ALTERNATE_JSIMMEDIATE)
+ addSlowCase(joSub32(Imm32(1), X86::eax));
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+#else
+ addSlowCase(joSub32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::eax));
+ signExtend32ToPtr(X86::eax, X86::eax);
+#endif
+ emitPutVirtualRegister(srcDst);
+}
+void JIT::compileFastArithSlow_op_pre_dec(unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter)
+{
+ Jump notImm = getSlowCase(iter);
+ linkSlowCase(iter);
+ emitGetVirtualRegister(srcDst, X86::eax);
+ notImm.link(this);
+ emitPutJITStubArg(X86::eax, 1);
+ emitCTICall(Interpreter::cti_op_pre_dec);
+ emitPutVirtualRegister(srcDst);
+}
+
+
+#if !ENABLE(JIT_OPTIMIZE_ARITHMETIC)
+
+void JIT::compileFastArith_op_add(Instruction* currentInstruction)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_add);
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_mul);
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_sub);
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+#elif USE(ALTERNATE_JSIMMEDIATE) // *AND* ENABLE(JIT_OPTIMIZE_ARITHMETIC)
+
+void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned, unsigned op1, unsigned op2, OperandTypes)
+{
+ emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+ if (opcodeID == op_add)
+ addSlowCase(joAdd32(X86::edx, X86::eax));
+ else if (opcodeID == op_sub)
+ addSlowCase(joSub32(X86::edx, X86::eax));
+ else {
+ ASSERT(opcodeID == op_mul);
+ addSlowCase(joMul32(X86::edx, X86::eax));
+ addSlowCase(jz32(X86::eax));
+ }
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+}
+
+void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned, unsigned op1, unsigned, OperandTypes types)
+{
+ // We assume that subtracting TagTypeNumber is equivalent to adding DoubleEncodeOffset.
+ COMPILE_ASSERT(((JSImmediate::TagTypeNumber + JSImmediate::DoubleEncodeOffset) == 0), TagTypeNumber_PLUS_DoubleEncodeOffset_EQUALS_0);
+
+ Jump notImm1 = getSlowCase(iter);
+ Jump notImm2 = getSlowCase(iter);
+
+ linkSlowCase(iter); // Integer overflow case - we could handle this in JIT code, but this is likely rare.
+ if (opcodeID == op_mul) // op_mul has an extra slow case to handle 0 * negative number.
+ linkSlowCase(iter);
+ emitGetVirtualRegister(op1, X86::eax);
+
+ Label stubFunctionCall(this);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 2);
+ if (opcodeID == op_add)
+ emitCTICall(Interpreter::cti_op_add);
+ else if (opcodeID == op_sub)
+ emitCTICall(Interpreter::cti_op_sub);
+ else {
+ ASSERT(opcodeID == op_mul);
+ emitCTICall(Interpreter::cti_op_mul);
+ }
+ Jump end = jump();
+
+ // if we get here, eax is not an int32, edx not yet checked.
+ notImm1.link(this);
+ if (!types.first().definitelyIsNumber())
+ emitJumpIfNotImmediateNumber(X86::eax).linkTo(stubFunctionCall, this);
+ if (!types.second().definitelyIsNumber())
+ emitJumpIfNotImmediateNumber(X86::edx).linkTo(stubFunctionCall, this);
+ addPtr(tagTypeNumberRegister, X86::eax);
+ m_assembler.movq_rr(X86::eax, X86::xmm1);
+ Jump op2isDouble = emitJumpIfNotImmediateInteger(X86::edx);
+ m_assembler.cvtsi2sd_rr(X86::edx, X86::xmm2);
+ Jump op2wasInteger = jump();
+
+ // if we get here, eax IS an int32, edx is not.
+ notImm2.link(this);
+ if (!types.second().definitelyIsNumber())
+ emitJumpIfNotImmediateNumber(X86::edx).linkTo(stubFunctionCall, this);
+ m_assembler.cvtsi2sd_rr(X86::eax, X86::xmm1);
+ op2isDouble.link(this);
+ addPtr(tagTypeNumberRegister, X86::edx);
+ m_assembler.movq_rr(X86::edx, X86::xmm2);
+ op2wasInteger.link(this);
+
+ if (opcodeID == op_add)
+ m_assembler.addsd_rr(X86::xmm2, X86::xmm1);
+ else if (opcodeID == op_sub)
+ m_assembler.subsd_rr(X86::xmm2, X86::xmm1);
+ else {
+ ASSERT(opcodeID == op_mul);
+ m_assembler.mulsd_rr(X86::xmm2, X86::xmm1);
+ }
+ m_assembler.movq_rr(X86::xmm1, X86::eax);
+ subPtr(tagTypeNumberRegister, X86::eax);
+
+ end.link(this);
+}
+
+void JIT::compileFastArith_op_add(Instruction* currentInstruction)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+ OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+ if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_add);
+ emitPutVirtualRegister(result);
+ return;
+ }
+
+ if (isOperandConstantImmediateInt(op1)) {
+ emitGetVirtualRegister(op2, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1)), X86::eax));
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+ } else if (isOperandConstantImmediateInt(op2)) {
+ emitGetVirtualRegister(op1, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2)), X86::eax));
+ emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+ } else
+ compileBinaryArithOp(op_add, result, op1, op2, types);
+
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+ OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+ if (isOperandConstantImmediateInt(op1)) {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_add);
+ } else if (isOperandConstantImmediateInt(op2)) {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_add);
+ } else
+ compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types);
+
+ emitPutVirtualRegister(result);
+}
+
+void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+ OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+ // For now, only plant a fast int case if the constant operand is greater than zero.
+ int32_t value;
+ if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
+ emitGetVirtualRegister(op2, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
+ emitFastArithReTagImmediate(X86::eax, X86::eax);
+ } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
+ emitGetVirtualRegister(op1, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
+ emitFastArithReTagImmediate(X86::eax, X86::eax);
+ } else
+ compileBinaryArithOp(op_mul, result, op1, op2, types);
+
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+ OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+ if ((isOperandConstantImmediateInt(op1) && (getConstantOperandImmediateInt(op1) > 0))
+ || (isOperandConstantImmediateInt(op2) && (getConstantOperandImmediateInt(op2) > 0))) {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_mul);
+ } else
+ compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, types);
+
+ emitPutVirtualRegister(result);
+}
+
+void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+ OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+ compileBinaryArithOp(op_sub, result, op1, op2, types);
+
+ emitPutVirtualRegister(result);
+}
+void JIT::compileFastArithSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+ OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+ compileBinaryArithOpSlowCase(op_sub, iter, result, op1, op2, types);
+
+ emitPutVirtualRegister(result);
+}
+
+#else
+
+typedef X86Assembler::JmpSrc JmpSrc;
+typedef X86Assembler::JmpDst JmpDst;
+typedef X86Assembler::XMMRegisterID XMMRegisterID;
+
+#if PLATFORM(MAC)
+
+static inline bool isSSE2Present()
+{
+ return true; // All X86 Macs are guaranteed to support at least SSE2
+}
+
+#else
+
+static bool isSSE2Present()
+{
+ static const int SSE2FeatureBit = 1 << 26;
+ struct SSE2Check {
+ SSE2Check()
+ {
+ int flags;
+#if COMPILER(MSVC)
+ _asm {
+ mov eax, 1 // cpuid function 1 gives us the standard feature set
+ cpuid;
+ mov flags, edx;
+ }
+#else
+ flags = 0;
+ // FIXME: Add GCC code to do above asm
+#endif
+ present = (flags & SSE2FeatureBit) != 0;
+ }
+ bool present;
+ };
+ static SSE2Check check;
+ return check.present;
+}
+
+#endif
+
+/*
+ This is required since number representation is canonical - values representable as a JSImmediate should not be stored in a JSNumberCell.
+
+ In the common case, the double value from 'xmmSource' is written to the reusable JSNumberCell pointed to by 'jsNumberCell', then 'jsNumberCell'
+ is written to the output SF Register 'dst', and then a jump is planted (stored into *wroteJSNumberCell).
+
+ However if the value from xmmSource is representable as a JSImmediate, then the JSImmediate value will be written to the output, and flow
+ control will fall through from the code planted.
+*/
+void JIT::putDoubleResultToJSNumberCellOrJSImmediate(X86::XMMRegisterID xmmSource, X86::RegisterID jsNumberCell, unsigned dst, JmpSrc* wroteJSNumberCell, X86::XMMRegisterID tempXmm, X86::RegisterID tempReg1, X86::RegisterID tempReg2)
+{
+ // convert (double -> JSImmediate -> double), and check if the value is unchanged - in which case the value is representable as a JSImmediate.
+ __ cvttsd2si_rr(xmmSource, tempReg1);
+ __ addl_rr(tempReg1, tempReg1);
+ __ sarl_i8r(1, tempReg1);
+ __ cvtsi2sd_rr(tempReg1, tempXmm);
+ // Compare & branch if immediate.
+ __ ucomisd_rr(tempXmm, xmmSource);
+ JmpSrc resultIsImm = __ je();
+ JmpDst resultLookedLikeImmButActuallyIsnt = __ label();
+
+ // Store the result to the JSNumberCell and jump.
+ __ movsd_rm(xmmSource, FIELD_OFFSET(JSNumberCell, m_value), jsNumberCell);
+ if (jsNumberCell != X86::eax)
+ __ movl_rr(jsNumberCell, X86::eax);
+ emitPutVirtualRegister(dst);
+ *wroteJSNumberCell = __ jmp();
+
+ __ link(resultIsImm, __ label());
+ // value == (double)(JSImmediate)value... or at least, it looks that way...
+ // ucomi will report that (0 == -0), and will report true if either input in NaN (result is unordered).
+ __ link(__ jp(), resultLookedLikeImmButActuallyIsnt); // Actually was a NaN
+ __ pextrw_irr(3, xmmSource, tempReg2);
+ __ cmpl_ir(0x8000, tempReg2);
+ __ link(__ je(), resultLookedLikeImmButActuallyIsnt); // Actually was -0
+ // Yes it really really really is representable as a JSImmediate.
+ emitFastArithIntToImmNoCheck(tempReg1, X86::eax);
+ emitPutVirtualRegister(dst);
+}
+
+void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes types)
+{
+ Structure* numberStructure = m_globalData->numberStructure.get();
+ JmpSrc wasJSNumberCell1;
+ JmpSrc wasJSNumberCell1b;
+ JmpSrc wasJSNumberCell2;
+ JmpSrc wasJSNumberCell2b;
+
+ emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx);
+
+ if (types.second().isReusable() && isSSE2Present()) {
+ ASSERT(types.second().mightBeNumber());
+
+ // Check op2 is a number
+ __ testl_i32r(JSImmediate::TagTypeNumber, X86::edx);
+ JmpSrc op2imm = __ jne();
+ if (!types.second().definitelyIsNumber()) {
+ emitJumpSlowCaseIfNotJSCell(X86::edx, src2);
+ __ cmpl_im(reinterpret_cast<unsigned>(numberStructure), FIELD_OFFSET(JSCell, m_structure), X86::edx);
+ addSlowCase(__ jne());
+ }
+
+ // (1) In this case src2 is a reusable number cell.
+ // Slow case if src1 is not a number type.
+ __ testl_i32r(JSImmediate::TagTypeNumber, X86::eax);
+ JmpSrc op1imm = __ jne();
+ if (!types.first().definitelyIsNumber()) {
+ emitJumpSlowCaseIfNotJSCell(X86::eax, src1);
+ __ cmpl_im(reinterpret_cast<unsigned>(numberStructure), FIELD_OFFSET(JSCell, m_structure), X86::eax);
+ addSlowCase(__ jne());
+ }
+
+ // (1a) if we get here, src1 is also a number cell
+ __ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
+ JmpSrc loadedDouble = __ jmp();
+ // (1b) if we get here, src1 is an immediate
+ __ link(op1imm, __ label());
+ emitFastArithImmToInt(X86::eax);
+ __ cvtsi2sd_rr(X86::eax, X86::xmm0);
+ // (1c)
+ __ link(loadedDouble, __ label());
+ if (opcodeID == op_add)
+ __ addsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
+ else if (opcodeID == op_sub)
+ __ subsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
+ else {
+ ASSERT(opcodeID == op_mul);
+ __ mulsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
+ }
+
+ putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::edx, dst, &wasJSNumberCell2, X86::xmm1, X86::ecx, X86::eax);
+ wasJSNumberCell2b = __ jmp();
+
+ // (2) This handles cases where src2 is an immediate number.
+ // Two slow cases - either src1 isn't an immediate, or the subtract overflows.
+ __ link(op2imm, __ label());
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ } else if (types.first().isReusable() && isSSE2Present()) {
+ ASSERT(types.first().mightBeNumber());
+
+ // Check op1 is a number
+ __ testl_i32r(JSImmediate::TagTypeNumber, X86::eax);
+ JmpSrc op1imm = __ jne();
+ if (!types.first().definitelyIsNumber()) {
+ emitJumpSlowCaseIfNotJSCell(X86::eax, src1);
+ __ cmpl_im(reinterpret_cast<unsigned>(numberStructure), FIELD_OFFSET(JSCell, m_structure), X86::eax);
+ addSlowCase(__ jne());
+ }
+
+ // (1) In this case src1 is a reusable number cell.
+ // Slow case if src2 is not a number type.
+ __ testl_i32r(JSImmediate::TagTypeNumber, X86::edx);
+ JmpSrc op2imm = __ jne();
+ if (!types.second().definitelyIsNumber()) {
+ emitJumpSlowCaseIfNotJSCell(X86::edx, src2);
+ __ cmpl_im(reinterpret_cast<unsigned>(numberStructure), FIELD_OFFSET(JSCell, m_structure), X86::edx);
+ addSlowCase(__ jne());
+ }
+
+ // (1a) if we get here, src2 is also a number cell
+ __ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm1);
+ JmpSrc loadedDouble = __ jmp();
+ // (1b) if we get here, src2 is an immediate
+ __ link(op2imm, __ label());
+ emitFastArithImmToInt(X86::edx);
+ __ cvtsi2sd_rr(X86::edx, X86::xmm1);
+ // (1c)
+ __ link(loadedDouble, __ label());
+ __ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
+ if (opcodeID == op_add)
+ __ addsd_rr(X86::xmm1, X86::xmm0);
+ else if (opcodeID == op_sub)
+ __ subsd_rr(X86::xmm1, X86::xmm0);
+ else {
+ ASSERT(opcodeID == op_mul);
+ __ mulsd_rr(X86::xmm1, X86::xmm0);
+ }
+ __ movsd_rm(X86::xmm0, FIELD_OFFSET(JSNumberCell, m_value), X86::eax);
+ emitPutVirtualRegister(dst);
+
+ putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::eax, dst, &wasJSNumberCell1, X86::xmm1, X86::ecx, X86::edx);
+ wasJSNumberCell1b = __ jmp();
+
+ // (2) This handles cases where src1 is an immediate number.
+ // Two slow cases - either src2 isn't an immediate, or the subtract overflows.
+ __ link(op1imm, __ label());
+ emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+ } else
+ emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
+
+ if (opcodeID == op_add) {
+ emitFastArithDeTagImmediate(X86::eax);
+ __ addl_rr(X86::edx, X86::eax);
+ addSlowCase(__ jo());
+ } else if (opcodeID == op_sub) {
+ __ subl_rr(X86::edx, X86::eax);
+ addSlowCase(__ jo());
+ signExtend32ToPtr(X86::eax, X86::eax);
+ emitFastArithReTagImmediate(X86::eax, X86::eax);
+ } else {
+ ASSERT(opcodeID == op_mul);
+ // convert eax & edx from JSImmediates to ints, and check if either are zero
+ emitFastArithImmToInt(X86::edx);
+ JmpSrc op1Zero = emitFastArithDeTagImmediateJumpIfZero(X86::eax);
+ __ testl_rr(X86::edx, X86::edx);
+ JmpSrc op2NonZero = __ jne();
+ __ link(op1Zero, __ label());
+ // if either input is zero, add the two together, and check if the result is < 0.
+ // If it is, we have a problem (N < 0), (N * 0) == -0, not representatble as a JSImmediate.
+ __ movl_rr(X86::eax, X86::ecx);
+ __ addl_rr(X86::edx, X86::ecx);
+ addSlowCase(__ js());
+ // Skip the above check if neither input is zero
+ __ link(op2NonZero, __ label());
+ __ imull_rr(X86::edx, X86::eax);
+ addSlowCase(__ jo());
+ signExtend32ToPtr(X86::eax, X86::eax);
+ emitFastArithReTagImmediate(X86::eax, X86::eax);
+ }
+ emitPutVirtualRegister(dst);
+
+ if (types.second().isReusable() && isSSE2Present()) {
+ __ link(wasJSNumberCell2, __ label());
+ __ link(wasJSNumberCell2b, __ label());
+ }
+ else if (types.first().isReusable() && isSSE2Present()) {
+ __ link(wasJSNumberCell1, __ label());
+ __ link(wasJSNumberCell1b, __ label());
+ }
+}
+
+void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes types)
+{
+ linkSlowCase(iter);
+ if (types.second().isReusable() && isSSE2Present()) {
+ if (!types.first().definitelyIsNumber()) {
+ linkSlowCaseIfNotJSCell(iter, src1);
+ linkSlowCase(iter);
+ }
+ if (!types.second().definitelyIsNumber()) {
+ linkSlowCaseIfNotJSCell(iter, src2);
+ linkSlowCase(iter);
+ }
+ } else if (types.first().isReusable() && isSSE2Present()) {
+ if (!types.first().definitelyIsNumber()) {
+ linkSlowCaseIfNotJSCell(iter, src1);
+ linkSlowCase(iter);
+ }
+ if (!types.second().definitelyIsNumber()) {
+ linkSlowCaseIfNotJSCell(iter, src2);
+ linkSlowCase(iter);
+ }
+ }
+ linkSlowCase(iter);
+
+ // additional entry point to handle -0 cases.
+ if (opcodeID == op_mul)
+ linkSlowCase(iter);
+
+ emitPutJITStubArgFromVirtualRegister(src1, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(src2, 2, X86::ecx);
+ if (opcodeID == op_add)
+ emitCTICall(Interpreter::cti_op_add);
+ else if (opcodeID == op_sub)
+ emitCTICall(Interpreter::cti_op_sub);
+ else {
+ ASSERT(opcodeID == op_mul);
+ emitCTICall(Interpreter::cti_op_mul);
+ }
+ emitPutVirtualRegister(dst);
+}
+
+void JIT::compileFastArith_op_add(Instruction* currentInstruction)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+
+ if (isOperandConstantImmediateInt(op1)) {
+ emitGetVirtualRegister(op2, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax));
+ signExtend32ToPtr(X86::eax, X86::eax);
+ emitPutVirtualRegister(result);
+ } else if (isOperandConstantImmediateInt(op2)) {
+ emitGetVirtualRegister(op1, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax));
+ signExtend32ToPtr(X86::eax, X86::eax);
+ emitPutVirtualRegister(result);
+ } else {
+ OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+ if (types.first().mightBeNumber() && types.second().mightBeNumber())
+ compileBinaryArithOp(op_add, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
+ else {
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_add);
+ emitPutVirtualRegister(result);
+ }
+ }
+}
+void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+
+ if (isOperandConstantImmediateInt(op1)) {
+ Jump notImm = getSlowCase(iter);
+ linkSlowCase(iter);
+ sub32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax);
+ notImm.link(this);
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArg(X86::eax, 2);
+ emitCTICall(Interpreter::cti_op_add);
+ emitPutVirtualRegister(result);
+ } else if (isOperandConstantImmediateInt(op2)) {
+ Jump notImm = getSlowCase(iter);
+ linkSlowCase(iter);
+ sub32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax);
+ notImm.link(this);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_add);
+ emitPutVirtualRegister(result);
+ } else {
+ OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+ ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber());
+ compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types);
+ }
+}
+
+void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+
+ // For now, only plant a fast int case if the constant operand is greater than zero.
+ int32_t value;
+ if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
+ emitGetVirtualRegister(op2, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitFastArithDeTagImmediate(X86::eax);
+ addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
+ signExtend32ToPtr(X86::eax, X86::eax);
+ emitFastArithReTagImmediate(X86::eax, X86::eax);
+ emitPutVirtualRegister(result);
+ } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
+ emitGetVirtualRegister(op1, X86::eax);
+ emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitFastArithDeTagImmediate(X86::eax);
+ addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
+ signExtend32ToPtr(X86::eax, X86::eax);
+ emitFastArithReTagImmediate(X86::eax, X86::eax);
+ emitPutVirtualRegister(result);
+ } else
+ compileBinaryArithOp(op_mul, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
+}
+void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+
+ if ((isOperandConstantImmediateInt(op1) && (getConstantOperandImmediateInt(op1) > 0))
+ || (isOperandConstantImmediateInt(op2) && (getConstantOperandImmediateInt(op2) > 0))) {
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
+ emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitCTICall(Interpreter::cti_op_mul);
+ emitPutVirtualRegister(result);
+ } else
+ compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
+}
+
+void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
+{
+ compileBinaryArithOp(op_sub, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand));
+}
+void JIT::compileFastArithSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ compileBinaryArithOpSlowCase(op_sub, iter, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand));
+}
+
+#endif
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITCall.cpp b/JavaScriptCore/jit/JITCall.cpp
new file mode 100644
index 0000000..af26712
--- /dev/null
+++ b/JavaScriptCore/jit/JITCall.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JIT.h"
+
+#if ENABLE(JIT)
+
+#include "CodeBlock.h"
+#include "JITInlineMethods.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "Interpreter.h"
+#include "ResultType.h"
+#include "SamplingTool.h"
+
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+using namespace std;
+
+namespace JSC {
+
+void JIT::unlinkCall(CallLinkInfo* callLinkInfo)
+{
+ // When the JSFunction is deleted the pointer embedded in the instruction stream will no longer be valid
+ // (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive
+ // match). Reset the check so it no longer matches.
+ DataLabelPtr::patch(callLinkInfo->hotPathBegin, JSValuePtr::encode(jsImpossibleValue()));
+}
+
+void JIT::linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount)
+{
+ // Currently we only link calls with the exact number of arguments.
+ if (callerArgCount == calleeCodeBlock->m_numParameters) {
+ ASSERT(!callLinkInfo->isLinked());
+
+ calleeCodeBlock->addCaller(callLinkInfo);
+
+ DataLabelPtr::patch(callLinkInfo->hotPathBegin, callee);
+ Jump::patch(callLinkInfo->hotPathOther, ctiCode);
+ }
+
+ // patch the instruction that jumps out to the cold path, so that we only try to link once.
+ void* patchCheck = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(callLinkInfo->hotPathBegin) + patchOffsetOpCallCompareToJump);
+ Jump::patch(patchCheck, callLinkInfo->coldPathOther);
+}
+
+void JIT::compileOpCallInitializeCallFrame()
+{
+ store32(X86::edx, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
+
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), X86::edx); // newScopeChain
+
+ storePtr(ImmPtr(JSValuePtr::encode(noValue())), Address(callFrameRegister, RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register))));
+ storePtr(X86::ecx, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register))));
+ storePtr(X86::edx, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register))));
+}
+
+void JIT::compileOpCallSetupArgs(Instruction* instruction)
+{
+ int argCount = instruction[3].u.operand;
+ int registerOffset = instruction[4].u.operand;
+
+ // ecx holds func
+ emitPutJITStubArg(X86::ecx, 1);
+ emitPutJITStubArgConstant(registerOffset, 2);
+ emitPutJITStubArgConstant(argCount, 3);
+}
+
+void JIT::compileOpCallEvalSetupArgs(Instruction* instruction)
+{
+ int argCount = instruction[3].u.operand;
+ int registerOffset = instruction[4].u.operand;
+
+ // ecx holds func
+ emitPutJITStubArg(X86::ecx, 1);
+ emitPutJITStubArgConstant(registerOffset, 2);
+ emitPutJITStubArgConstant(argCount, 3);
+}
+
+void JIT::compileOpConstructSetupArgs(Instruction* instruction)
+{
+ int argCount = instruction[3].u.operand;
+ int registerOffset = instruction[4].u.operand;
+ int proto = instruction[5].u.operand;
+ int thisRegister = instruction[6].u.operand;
+
+ // ecx holds func
+ emitPutJITStubArg(X86::ecx, 1);
+ emitPutJITStubArgConstant(registerOffset, 2);
+ emitPutJITStubArgConstant(argCount, 3);
+ emitPutJITStubArgFromVirtualRegister(proto, 4, X86::eax);
+ emitPutJITStubArgConstant(thisRegister, 5);
+}
+
+#if !ENABLE(JIT_OPTIMIZE_CALL)
+
+void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
+{
+ int dst = instruction[1].u.operand;
+ int callee = instruction[2].u.operand;
+ int argCount = instruction[3].u.operand;
+ int registerOffset = instruction[4].u.operand;
+
+ // Handle eval
+ Jump wasEval;
+ if (opcodeID == op_call_eval) {
+ emitGetVirtualRegister(callee, X86::ecx);
+ compileOpCallEvalSetupArgs(instruction);
+
+ emitCTICall(Interpreter::cti_op_call_eval);
+ wasEval = jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
+ }
+
+ emitGetVirtualRegister(callee, X86::ecx);
+ // The arguments have been set up on the hot path for op_call_eval
+ if (opcodeID == op_call)
+ compileOpCallSetupArgs(instruction);
+ else if (opcodeID == op_construct)
+ compileOpConstructSetupArgs(instruction);
+
+ // Check for JSFunctions.
+ emitJumpSlowCaseIfNotJSCell(X86::ecx);
+ addSlowCase(jnePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr)));
+
+ // First, in the case of a construct, allocate the new object.
+ if (opcodeID == op_construct) {
+ emitCTICall(Interpreter::cti_op_construct_JSConstruct);
+ emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
+ emitGetVirtualRegister(callee, X86::ecx);
+ }
+
+ // Speculatively roll the callframe, assuming argCount will match the arity.
+ storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
+ addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
+ move(Imm32(argCount), X86::edx);
+
+ emitNakedCall(m_interpreter->m_ctiVirtualCall);
+
+ if (opcodeID == op_call_eval)
+ wasEval.link(this);
+
+ // Put the return value in dst. In the interpreter, op_ret does this.
+ emitPutVirtualRegister(dst);
+
+ sampleCodeBlock(m_codeBlock);
+}
+
+void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned, OpcodeID opcodeID)
+{
+ int dst = instruction[1].u.operand;
+
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+
+ // This handles host functions
+ emitCTICall(((opcodeID == op_construct) ? Interpreter::cti_op_construct_NotJSConstruct : Interpreter::cti_op_call_NotJSFunction));
+ // Put the return value in dst. In the interpreter, op_ret does this.
+ emitPutVirtualRegister(dst);
+
+ sampleCodeBlock(m_codeBlock);
+}
+
+#else
+
+static NO_RETURN void unreachable()
+{
+ ASSERT_NOT_REACHED();
+ exit(1);
+}
+
+void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned callLinkInfoIndex)
+{
+ int dst = instruction[1].u.operand;
+ int callee = instruction[2].u.operand;
+ int argCount = instruction[3].u.operand;
+ int registerOffset = instruction[4].u.operand;
+
+ // Handle eval
+ Jump wasEval;
+ if (opcodeID == op_call_eval) {
+ emitGetVirtualRegister(callee, X86::ecx);
+ compileOpCallEvalSetupArgs(instruction);
+
+ emitCTICall(Interpreter::cti_op_call_eval);
+ wasEval = jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
+ }
+
+ // This plants a check for a cached JSFunction value, so we can plant a fast link to the callee.
+ // This deliberately leaves the callee in ecx, used when setting up the stack frame below
+ emitGetVirtualRegister(callee, X86::ecx);
+ DataLabelPtr addressOfLinkedFunctionCheck;
+ Jump jumpToSlow = jnePtrWithPatch(X86::ecx, addressOfLinkedFunctionCheck, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
+ addSlowCase(jumpToSlow);
+ ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump);
+ m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
+
+ // The following is the fast case, only used whan a callee can be linked.
+
+ // In the case of OpConstruct, call out to a cti_ function to create the new object.
+ if (opcodeID == op_construct) {
+ int proto = instruction[5].u.operand;
+ int thisRegister = instruction[6].u.operand;
+
+ emitPutJITStubArg(X86::ecx, 1);
+ emitPutJITStubArgFromVirtualRegister(proto, 4, X86::eax);
+ emitCTICall(Interpreter::cti_op_construct_JSConstruct);
+ emitPutVirtualRegister(thisRegister);
+ emitGetVirtualRegister(callee, X86::ecx);
+ }
+
+ // Fast version of stack frame initialization, directly relative to edi.
+ // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
+ storePtr(ImmPtr(JSValuePtr::encode(noValue())), Address(callFrameRegister, (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register))));
+ storePtr(X86::ecx, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register))));
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), X86::edx); // newScopeChain
+ store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register))));
+ storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register))));
+ storePtr(X86::edx, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register))));
+ addPtr(Imm32(registerOffset * sizeof(Register)), callFrameRegister);
+
+ // Call to the callee
+ m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(reinterpret_cast<void*>(unreachable));
+
+ if (opcodeID == op_call_eval)
+ wasEval.link(this);
+
+ // Put the return value in dst. In the interpreter, op_ret does this.
+ emitPutVirtualRegister(dst);
+
+ sampleCodeBlock(m_codeBlock);
+}
+
+void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex, OpcodeID opcodeID)
+{
+ int dst = instruction[1].u.operand;
+ int callee = instruction[2].u.operand;
+ int argCount = instruction[3].u.operand;
+ int registerOffset = instruction[4].u.operand;
+
+ linkSlowCase(iter);
+
+ // The arguments have been set up on the hot path for op_call_eval
+ if (opcodeID == op_call)
+ compileOpCallSetupArgs(instruction);
+ else if (opcodeID == op_construct)
+ compileOpConstructSetupArgs(instruction);
+
+ // Fast check for JS function.
+ Jump callLinkFailNotObject = emitJumpIfNotJSCell(X86::ecx);
+ Jump callLinkFailNotJSFunction = jnePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr));
+
+ // First, in the case of a construct, allocate the new object.
+ if (opcodeID == op_construct) {
+ emitCTICall(Interpreter::cti_op_construct_JSConstruct);
+ emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
+ emitGetVirtualRegister(callee, X86::ecx);
+ }
+
+ move(Imm32(argCount), X86::edx);
+
+ // Speculatively roll the callframe, assuming argCount will match the arity.
+ storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
+ addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
+
+ m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation =
+ emitNakedCall(m_interpreter->m_ctiVirtualCallPreLink);
+
+ Jump storeResultForFirstRun = jump();
+
+// FIXME: this label can be removed, since it is a fixed offset from 'callReturnLocation'.
+ // This is the address for the cold path *after* the first run (which tries to link the call).
+ m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = MacroAssembler::Label(this);
+
+ // The arguments have been set up on the hot path for op_call_eval
+ if (opcodeID == op_call)
+ compileOpCallSetupArgs(instruction);
+ else if (opcodeID == op_construct)
+ compileOpConstructSetupArgs(instruction);
+
+ // Check for JSFunctions.
+ Jump isNotObject = emitJumpIfNotJSCell(X86::ecx);
+ Jump isJSFunction = jePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr));
+
+ // This handles host functions
+ isNotObject.link(this);
+ callLinkFailNotObject.link(this);
+ callLinkFailNotJSFunction.link(this);
+ emitCTICall(((opcodeID == op_construct) ? Interpreter::cti_op_construct_NotJSConstruct : Interpreter::cti_op_call_NotJSFunction));
+ Jump wasNotJSFunction = jump();
+
+ // Next, handle JSFunctions...
+ isJSFunction.link(this);
+
+ // First, in the case of a construct, allocate the new object.
+ if (opcodeID == op_construct) {
+ emitCTICall(Interpreter::cti_op_construct_JSConstruct);
+ emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
+ emitGetVirtualRegister(callee, X86::ecx);
+ }
+
+ // Speculatively roll the callframe, assuming argCount will match the arity.
+ storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
+ addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
+ move(Imm32(argCount), X86::edx);
+
+ emitNakedCall(m_interpreter->m_ctiVirtualCall);
+
+ // Put the return value in dst. In the interpreter, op_ret does this.
+ wasNotJSFunction.link(this);
+ storeResultForFirstRun.link(this);
+ emitPutVirtualRegister(dst);
+
+ sampleCodeBlock(m_codeBlock);
+}
+
+#endif
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITInlineMethods.h b/JavaScriptCore/jit/JITInlineMethods.h
new file mode 100644
index 0000000..7a97cd8
--- /dev/null
+++ b/JavaScriptCore/jit/JITInlineMethods.h
@@ -0,0 +1,434 @@
+/*
+ * 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 JITInlineMethods_h
+#define JITInlineMethods_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(JIT)
+
+#if PLATFORM(WIN)
+#undef FIELD_OFFSET // Fix conflict with winnt.h.
+#endif
+
+// FIELD_OFFSET: Like the C++ offsetof macro, but you can use it with classes.
+// The magic number 0x4000 is insignificant. We use it to avoid using NULL, since
+// NULL can cause compiler problems, especially in cases of multiple inheritance.
+#define FIELD_OFFSET(class, field) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->field)) - 0x4000)
+
+namespace JSC {
+
+ALWAYS_INLINE void JIT::killLastResultRegister()
+{
+ m_lastResultBytecodeRegister = std::numeric_limits<int>::max();
+}
+
+// get arg puts an arg from the SF register array into a h/w register
+ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, RegisterID dst)
+{
+ ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+
+ // TODO: we want to reuse values that are already in registers if we can - add a register allocator!
+ if (m_codeBlock->isConstantRegisterIndex(src)) {
+ JSValuePtr value = m_codeBlock->getConstant(src);
+ move(ImmPtr(JSValuePtr::encode(value)), dst);
+ killLastResultRegister();
+ return;
+ }
+
+ if (src == m_lastResultBytecodeRegister && m_codeBlock->isTemporaryRegisterIndex(src)) {
+ bool atJumpTarget = false;
+ while (m_jumpTargetsPosition < m_codeBlock->numberOfJumpTargets() && m_codeBlock->jumpTarget(m_jumpTargetsPosition) <= m_bytecodeIndex) {
+ if (m_codeBlock->jumpTarget(m_jumpTargetsPosition) == m_bytecodeIndex)
+ atJumpTarget = true;
+ ++m_jumpTargetsPosition;
+ }
+
+ if (!atJumpTarget) {
+ // The argument we want is already stored in eax
+ if (dst != X86::eax)
+ move(X86::eax, dst);
+ killLastResultRegister();
+ return;
+ }
+ }
+
+ loadPtr(Address(callFrameRegister, src * sizeof(Register)), dst);
+ killLastResultRegister();
+}
+
+ALWAYS_INLINE void JIT::emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2)
+{
+ if (src2 == m_lastResultBytecodeRegister) {
+ emitGetVirtualRegister(src2, dst2);
+ emitGetVirtualRegister(src1, dst1);
+ } else {
+ emitGetVirtualRegister(src1, dst1);
+ emitGetVirtualRegister(src2, dst2);
+ }
+}
+
+// puts an arg onto the stack, as an arg to a context threaded function.
+ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID src, unsigned argumentNumber)
+{
+ poke(src, argumentNumber);
+}
+
+ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(unsigned value, unsigned argumentNumber)
+{
+ poke(Imm32(value), argumentNumber);
+}
+
+ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(void* value, unsigned argumentNumber)
+{
+ poke(ImmPtr(value), argumentNumber);
+}
+
+ALWAYS_INLINE void JIT::emitGetJITStubArg(unsigned argumentNumber, RegisterID dst)
+{
+ peek(dst, argumentNumber);
+}
+
+ALWAYS_INLINE JSValuePtr JIT::getConstantOperand(unsigned src)
+{
+ ASSERT(m_codeBlock->isConstantRegisterIndex(src));
+ return m_codeBlock->getConstant(src);
+}
+
+ALWAYS_INLINE int32_t JIT::getConstantOperandImmediateInt(unsigned src)
+{
+ return getConstantOperand(src).getInt32Fast();
+}
+
+ALWAYS_INLINE bool JIT::isOperandConstantImmediateInt(unsigned src)
+{
+ return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isInt32Fast();
+}
+
+// get arg puts an arg from the SF register array onto the stack, as an arg to a context threaded function.
+ALWAYS_INLINE void JIT::emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch)
+{
+ if (m_codeBlock->isConstantRegisterIndex(src)) {
+ JSValuePtr value = m_codeBlock->getConstant(src);
+ emitPutJITStubArgConstant(JSValuePtr::encode(value), argumentNumber);
+ } else {
+ loadPtr(Address(callFrameRegister, src * sizeof(Register)), scratch);
+ emitPutJITStubArg(scratch, argumentNumber);
+ }
+
+ killLastResultRegister();
+}
+
+ALWAYS_INLINE void JIT::emitPutCTIParam(void* value, unsigned name)
+{
+ poke(ImmPtr(value), name);
+}
+
+ALWAYS_INLINE void JIT::emitPutCTIParam(RegisterID from, unsigned name)
+{
+ poke(from, name);
+}
+
+ALWAYS_INLINE void JIT::emitGetCTIParam(unsigned name, RegisterID to)
+{
+ peek(to, name);
+ killLastResultRegister();
+}
+
+ALWAYS_INLINE void JIT::emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
+{
+ storePtr(from, Address(callFrameRegister, entry * sizeof(Register)));
+}
+
+ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry)
+{
+ storePtr(ImmPtr(value), Address(callFrameRegister, entry * sizeof(Register)));
+}
+
+ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, RegisterID to)
+{
+ loadPtr(Address(callFrameRegister, entry * sizeof(Register)), to);
+ killLastResultRegister();
+}
+
+ALWAYS_INLINE void JIT::emitPutVirtualRegister(unsigned dst, RegisterID from)
+{
+ storePtr(from, Address(callFrameRegister, dst * sizeof(Register)));
+ m_lastResultBytecodeRegister = (from == X86::eax) ? dst : std::numeric_limits<int>::max();
+ // FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
+}
+
+ALWAYS_INLINE void JIT::emitInitRegister(unsigned dst)
+{
+ storePtr(ImmPtr(JSValuePtr::encode(jsUndefined())), Address(callFrameRegister, dst * sizeof(Register)));
+ // FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
+}
+
+ALWAYS_INLINE JIT::Jump JIT::emitNakedCall(X86::RegisterID r)
+{
+ ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+
+ Jump nakedCall = call(r);
+ m_calls.append(CallRecord(nakedCall, m_bytecodeIndex));
+ return nakedCall;
+}
+
+ALWAYS_INLINE JIT::Jump JIT::emitNakedCall(void* function)
+{
+ ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+
+ Jump nakedCall = call();
+ m_calls.append(CallRecord(nakedCall, m_bytecodeIndex, function));
+ return nakedCall;
+}
+
+#if USE(JIT_STUB_ARGUMENT_REGISTER)
+ALWAYS_INLINE void JIT::restoreArgumentReference()
+{
+#if PLATFORM(X86_64)
+ move(X86::esp, X86::edi);
+#else
+ move(X86::esp, X86::ecx);
+#endif
+ emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
+}
+ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
+{
+ // In the trampoline on x86-64, the first argument register is not overwritten.
+#if !PLATFORM(X86_64)
+ move(X86::esp, X86::ecx);
+ addPtr(Imm32(sizeof(void*)), X86::ecx);
+#endif
+}
+#elif USE(JIT_STUB_ARGUMENT_STACK)
+ALWAYS_INLINE void JIT::restoreArgumentReference()
+{
+ storePtr(X86::esp, X86::esp);
+ emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
+}
+ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() {}
+#else // JIT_STUB_ARGUMENT_VA_LIST
+ALWAYS_INLINE void JIT::restoreArgumentReference()
+{
+ emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
+}
+ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() {}
+#endif
+
+ALWAYS_INLINE JIT::Jump JIT::emitCTICall_internal(void* helper)
+{
+ ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+
+#if ENABLE(OPCODE_SAMPLING)
+ sampleInstruction(m_codeBlock->instructions().begin() + m_bytecodeIndex, true);
+#endif
+ restoreArgumentReference();
+ Jump ctiCall = call();
+ m_calls.append(CallRecord(ctiCall, m_bytecodeIndex, helper));
+#if ENABLE(OPCODE_SAMPLING)
+ sampleInstruction(m_codeBlock->instructions().begin() + m_bytecodeIndex, false);
+#endif
+ killLastResultRegister();
+
+ return ctiCall;
+}
+
+ALWAYS_INLINE JIT::Jump JIT::checkStructure(RegisterID reg, Structure* structure)
+{
+ return jnePtr(Address(reg, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(structure));
+}
+
+ALWAYS_INLINE JIT::Jump JIT::emitJumpIfJSCell(RegisterID reg)
+{
+#if USE(ALTERNATE_JSIMMEDIATE)
+ return jzPtr(reg, tagMaskRegister);
+#else
+ return jz32(reg, Imm32(JSImmediate::TagMask));
+#endif
+}
+
+ALWAYS_INLINE JIT::Jump JIT::emitJumpIfBothJSCells(RegisterID reg1, RegisterID reg2, RegisterID scratch)
+{
+ move(reg1, scratch);
+ orPtr(reg2, scratch);
+ return emitJumpIfJSCell(scratch);
+}
+
+ALWAYS_INLINE void JIT::emitJumpSlowCaseIfJSCell(RegisterID reg)
+{
+ addSlowCase(emitJumpIfJSCell(reg));
+}
+
+ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotJSCell(RegisterID reg)
+{
+#if USE(ALTERNATE_JSIMMEDIATE)
+ return jnzPtr(reg, tagMaskRegister);
+#else
+ return jnz32(reg, Imm32(JSImmediate::TagMask));
+#endif
+}
+
+ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg)
+{
+ addSlowCase(emitJumpIfNotJSCell(reg));
+}
+
+ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg, int vReg)
+{
+ if (!m_codeBlock->isKnownNotImmediate(vReg))
+ emitJumpSlowCaseIfNotJSCell(reg);
+}
+
+ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, int vReg)
+{
+ if (!m_codeBlock->isKnownNotImmediate(vReg))
+ linkSlowCase(iter);
+}
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateNumber(RegisterID reg)
+{
+ return jnzPtr(reg, tagTypeNumberRegister);
+}
+ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateNumber(RegisterID reg)
+{
+ return jzPtr(reg, tagTypeNumberRegister);
+}
+#endif
+
+ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateInteger(RegisterID reg)
+{
+#if USE(ALTERNATE_JSIMMEDIATE)
+ return jaePtr(reg, tagTypeNumberRegister);
+#else
+ return jnz32(reg, Imm32(JSImmediate::TagTypeNumber));
+#endif
+}
+
+ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateInteger(RegisterID reg)
+{
+#if USE(ALTERNATE_JSIMMEDIATE)
+ return jbPtr(reg, tagTypeNumberRegister);
+#else
+ return jz32(reg, Imm32(JSImmediate::TagTypeNumber));
+#endif
+}
+
+ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateIntegers(RegisterID reg1, RegisterID reg2, RegisterID scratch)
+{
+ move(reg1, scratch);
+ andPtr(reg2, scratch);
+ return emitJumpIfNotImmediateInteger(scratch);
+}
+
+ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateInteger(RegisterID reg)
+{
+ addSlowCase(emitJumpIfNotImmediateInteger(reg));
+}
+
+ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateIntegers(RegisterID reg1, RegisterID reg2, RegisterID scratch)
+{
+ addSlowCase(emitJumpIfNotImmediateIntegers(reg1, reg2, scratch));
+}
+
+#if !USE(ALTERNATE_JSIMMEDIATE)
+ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg)
+{
+ subPtr(Imm32(JSImmediate::TagTypeNumber), reg);
+}
+
+ALWAYS_INLINE JIT::Jump JIT::emitFastArithDeTagImmediateJumpIfZero(RegisterID reg)
+{
+ return jzSubPtr(Imm32(JSImmediate::TagTypeNumber), reg);
+}
+#endif
+
+ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID src, RegisterID dest)
+{
+#if USE(ALTERNATE_JSIMMEDIATE)
+ emitFastArithIntToImmNoCheck(src, dest);
+#else
+ if (src != dest)
+ move(src, dest);
+ addPtr(Imm32(JSImmediate::TagTypeNumber), dest);
+#endif
+}
+
+ALWAYS_INLINE void JIT::emitFastArithImmToInt(RegisterID reg)
+{
+#if USE(ALTERNATE_JSIMMEDIATE)
+ UNUSED_PARAM(reg);
+#else
+ rshiftPtr(Imm32(JSImmediate::IntegerPayloadShift), reg);
+#endif
+}
+
+// operand is int32_t, must have been zero-extended if register is 64-bit.
+ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest)
+{
+#if USE(ALTERNATE_JSIMMEDIATE)
+ if (src != dest)
+ move(src, dest);
+ orPtr(tagTypeNumberRegister, dest);
+#else
+ signExtend32ToPtr(src, dest);
+ addPtr(dest, dest);
+ emitFastArithReTagImmediate(dest, dest);
+#endif
+}
+
+ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg)
+{
+ lshift32(Imm32(JSImmediate::ExtendedPayloadShift), reg);
+ or32(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), reg);
+}
+
+ALWAYS_INLINE void JIT::addSlowCase(Jump jump)
+{
+ ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+
+ m_slowCases.append(SlowCaseEntry(jump, m_bytecodeIndex));
+}
+
+ALWAYS_INLINE void JIT::addJump(Jump jump, int relativeOffset)
+{
+ ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+
+ m_jmpTable.append(JumpTable(jump, m_bytecodeIndex + relativeOffset));
+}
+
+ALWAYS_INLINE void JIT::emitJumpSlowToHot(Jump jump, int relativeOffset)
+{
+ ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+
+ jump.linkTo(m_labels[m_bytecodeIndex + relativeOffset], this);
+}
+
+}
+
+#endif // ENABLE(JIT)
+
+#endif
diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp
new file mode 100644
index 0000000..6740bec
--- /dev/null
+++ b/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -0,0 +1,704 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JIT.h"
+
+#if ENABLE(JIT)
+
+#include "CodeBlock.h"
+#include "JITInlineMethods.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "Interpreter.h"
+#include "ResultType.h"
+#include "SamplingTool.h"
+
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+using namespace std;
+
+namespace JSC {
+
+#if !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned)
+{
+ // As for put_by_id, get_by_id requires the offset of the Structure and the offset of the access to be patched.
+ // Additionally, for get_by_id we need patch the offset of the branch to the slow case (we patch this to jump
+ // to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
+ // to jump back to if one of these trampolies finds a match.
+
+ emitGetVirtualRegister(baseVReg, X86::eax);
+
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArgConstant(ident, 2);
+ emitCTICall(Interpreter::cti_op_get_by_id_generic);
+ emitPutVirtualRegister(resultVReg);
+}
+
+
+void JIT::compileGetByIdSlowCase(int, int, Identifier*, Vector<SlowCaseEntry>::iterator&, unsigned)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void JIT::compilePutByIdHotPath(int baseVReg, Identifier* ident, int valueVReg, unsigned)
+{
+ // In order to be able to patch both the Structure, and the object offset, we store one pointer,
+ // to just after the arguments have been loaded into registers 'hotPathBegin', and we generate code
+ // such that the Structure & offset are always at the same distance from this.
+
+ emitGetVirtualRegisters(baseVReg, X86::eax, valueVReg, X86::edx);
+
+ emitPutJITStubArgConstant(ident, 2);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 3);
+ emitCTICall(Interpreter::cti_op_put_by_id_generic);
+}
+
+void JIT::compilePutByIdSlowCase(int, Identifier*, int, Vector<SlowCaseEntry>::iterator&, unsigned)
+{
+ ASSERT_NOT_REACHED();
+}
+
+#else
+
+void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier*, unsigned propertyAccessInstructionIndex)
+{
+ // As for put_by_id, get_by_id requires the offset of the Structure and the offset of the access to be patched.
+ // Additionally, for get_by_id we need patch the offset of the branch to the slow case (we patch this to jump
+ // to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
+ // to jump back to if one of these trampolies finds a match.
+
+ emitGetVirtualRegister(baseVReg, X86::eax);
+
+ emitJumpSlowCaseIfNotJSCell(X86::eax, baseVReg);
+
+ Label hotPathBegin(this);
+ m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
+
+ DataLabelPtr structureToCompare;
+ Jump structureCheck = jnePtrWithPatch(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+ addSlowCase(structureCheck);
+ ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetGetByIdStructure);
+ ASSERT(differenceBetween(hotPathBegin, structureCheck) == patchOffsetGetByIdBranchToSlowCase);
+
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
+ DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(X86::eax, patchGetByIdDefaultOffset), X86::eax);
+ ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetGetByIdPropertyMapOffset);
+
+ Label putResult(this);
+ ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult);
+ emitPutVirtualRegister(resultVReg);
+}
+
+
+void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex)
+{
+ // As for the hot path of get_by_id, above, we ensure that we can use an architecture specific offset
+ // so that we only need track one pointer into the slow case code - we track a pointer to the location
+ // of the call (which we can use to look up the patch information), but should a array-length or
+ // prototype access trampoline fail we want to bail out back to here. To do so we can subtract back
+ // the distance from the call to the head of the slow case.
+
+ linkSlowCaseIfNotJSCell(iter, baseVReg);
+ linkSlowCase(iter);
+
+#ifndef NDEBUG
+ Label coldPathBegin(this);
+#endif
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArgConstant(ident, 2);
+ Jump call = emitCTICall(Interpreter::cti_op_get_by_id);
+ emitPutVirtualRegister(resultVReg);
+
+ ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall);
+
+ // Track the location of the call; this will be used to recover patch information.
+ m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
+}
+
+void JIT::compilePutByIdHotPath(int baseVReg, Identifier*, int valueVReg, unsigned propertyAccessInstructionIndex)
+{
+ // In order to be able to patch both the Structure, and the object offset, we store one pointer,
+ // to just after the arguments have been loaded into registers 'hotPathBegin', and we generate code
+ // such that the Structure & offset are always at the same distance from this.
+
+ emitGetVirtualRegisters(baseVReg, X86::eax, valueVReg, X86::edx);
+
+ // Jump to a slow case if either the base object is an immediate, or if the Structure does not match.
+ emitJumpSlowCaseIfNotJSCell(X86::eax, baseVReg);
+
+ Label hotPathBegin(this);
+ m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
+
+ // It is important that the following instruction plants a 32bit immediate, in order that it can be patched over.
+ DataLabelPtr structureToCompare;
+ addSlowCase(jnePtrWithPatch(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
+ ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetPutByIdStructure);
+
+ // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used.
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
+ DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(X86::edx, Address(X86::eax, patchGetByIdDefaultOffset));
+ ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetPutByIdPropertyMapOffset);
+}
+
+void JIT::compilePutByIdSlowCase(int baseVReg, Identifier* ident, int, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex)
+{
+ linkSlowCaseIfNotJSCell(iter, baseVReg);
+ linkSlowCase(iter);
+
+ emitPutJITStubArgConstant(ident, 2);
+ emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(X86::edx, 3);
+ Jump call = emitCTICall(Interpreter::cti_op_put_by_id);
+
+ // Track the location of the call; this will be used to recover patch information.
+ m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
+}
+
+static JSObject* resizePropertyStorage(JSObject* baseObject, int32_t oldSize, int32_t newSize)
+{
+ baseObject->allocatePropertyStorage(oldSize, newSize);
+ return baseObject;
+}
+
+static inline bool transitionWillNeedStorageRealloc(Structure* oldStructure, Structure* newStructure)
+{
+ return oldStructure->propertyStorageCapacity() != newStructure->propertyStorageCapacity();
+}
+
+void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, void* returnAddress)
+{
+ JumpList failureCases;
+ // Check eax is an object of the right Structure.
+ failureCases.append(emitJumpIfNotJSCell(X86::eax));
+ failureCases.append(jnePtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(oldStructure)));
+ JumpList successCases;
+
+ // ecx = baseObject
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ // proto(ecx) = baseObject->structure()->prototype()
+ failureCases.append(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
+
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
+
+ // ecx = baseObject->m_structure
+ for (RefPtr<Structure>* it = chain->head(); *it; ++it) {
+ // null check the prototype
+ successCases.append(jePtr(X86::ecx, ImmPtr(JSValuePtr::encode(jsNull()))));
+
+ // Check the structure id
+ failureCases.append(jnePtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(it->get())));
+
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ failureCases.append(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
+ loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
+ }
+
+ successCases.link(this);
+
+ Jump callTarget;
+
+ // emit a call only if storage realloc is needed
+ if (transitionWillNeedStorageRealloc(oldStructure, newStructure)) {
+ pop(X86::ebx);
+#if PLATFORM(X86_64)
+ move(Imm32(newStructure->propertyStorageCapacity()), X86::edx);
+ move(Imm32(oldStructure->propertyStorageCapacity()), X86::esi);
+ move(X86::eax, X86::edi);
+ callTarget = call();
+#else
+ push(Imm32(newStructure->propertyStorageCapacity()));
+ push(Imm32(oldStructure->propertyStorageCapacity()));
+ push(X86::eax);
+ callTarget = call();
+ addPtr(Imm32(3 * sizeof(void*)), X86::esp);
+#endif
+ emitGetJITStubArg(3, X86::edx);
+ push(X86::ebx);
+ }
+
+ // Assumes m_refCount can be decremented easily, refcount decrement is safe as
+ // codeblock should ensure oldStructure->m_refCount > 0
+ sub32(Imm32(1), AbsoluteAddress(oldStructure->addressOfCount()));
+ add32(Imm32(1), AbsoluteAddress(newStructure->addressOfCount()));
+ storePtr(ImmPtr(newStructure), Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)));
+
+ // write the value
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
+ storePtr(X86::edx, Address(X86::eax, cachedOffset * sizeof(JSValuePtr)));
+
+ ret();
+
+ Jump failureJump;
+ bool plantedFailureJump = false;
+ if (!failureCases.empty()) {
+ failureCases.link(this);
+ restoreArgumentReferenceForTrampoline();
+ failureJump = jump();
+ plantedFailureJump = true;
+ }
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+ PatchBuffer patchBuffer(code);
+
+ if (plantedFailureJump)
+ patchBuffer.link(failureJump, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));
+
+ if (transitionWillNeedStorageRealloc(oldStructure, newStructure))
+ patchBuffer.link(callTarget, reinterpret_cast<void*>(resizePropertyStorage));
+
+ stubInfo->stubRoutine = code;
+
+ Jump::patch(returnAddress, code);
+}
+
+void JIT::patchGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+{
+ // We don't want to patch more than once - in future go to cti_op_get_by_id_generic.
+ // Should probably go to Interpreter::cti_op_get_by_id_fail, but that doesn't do anything interesting right now.
+ Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));
+
+ // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
+ void* structureAddress = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdStructure);
+ void* displacementAddress = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPropertyMapOffset);
+ DataLabelPtr::patch(structureAddress, structure);
+ DataLabel32::patch(displacementAddress, cachedOffset * sizeof(JSValuePtr));
+}
+
+void JIT::patchPutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+{
+ // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+ // Should probably go to Interpreter::cti_op_put_by_id_fail, but that doesn't do anything interesting right now.
+ Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_generic));
+
+ // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
+ void* structureAddress = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetPutByIdStructure;
+ void* displacementAddress = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetPutByIdPropertyMapOffset;
+ DataLabelPtr::patch(structureAddress, structure);
+ DataLabel32::patch(displacementAddress, cachedOffset * sizeof(JSValuePtr));
+}
+
+void JIT::privateCompilePatchGetArrayLength(void* returnAddress)
+{
+ StructureStubInfo* stubInfo = &m_codeBlock->getStubInfo(returnAddress);
+
+ // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+ Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
+
+ // Check eax is an array
+ Jump failureCases1 = jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr));
+
+ // Checks out okay! - get the length from the storage
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
+ load32(Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_length)), X86::ecx);
+
+ Jump failureCases2 = ja32(X86::ecx, Imm32(JSImmediate::maxImmediateInt));
+
+ emitFastArithIntToImmNoCheck(X86::ecx, X86::eax);
+ Jump success = jump();
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+ PatchBuffer patchBuffer(code);
+
+ // Use the patch information to link the failure cases back to the original slow case routine.
+ void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
+ patchBuffer.link(failureCases1, slowCaseBegin);
+ patchBuffer.link(failureCases2, slowCaseBegin);
+
+ // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+ void* hotPathPutResult = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
+ patchBuffer.link(success, hotPathPutResult);
+
+ // Track the stub we have created so that it will be deleted later.
+ stubInfo->stubRoutine = code;
+
+ // Finally patch the jump to sow case back in the hot path to jump here instead.
+ void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
+ Jump::patch(jumpLocation, code);
+}
+
+void JIT::privateCompileGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+{
+ // Check eax is an object of the right Structure.
+ Jump failureCases1 = emitJumpIfNotJSCell(X86::eax);
+ Jump failureCases2 = checkStructure(X86::eax, structure);
+
+ // Checks out okay! - getDirectOffset
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
+ loadPtr(Address(X86::eax, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ ret();
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+ PatchBuffer patchBuffer(code);
+
+ patchBuffer.link(failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));
+ patchBuffer.link(failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));
+
+ stubInfo->stubRoutine = code;
+
+ Jump::patch(returnAddress, code);
+}
+
+void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, void* returnAddress, CallFrame* callFrame)
+{
+#if USE(CTI_REPATCH_PIC)
+ // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+ Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list));
+
+ // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
+ // referencing the prototype object - let's speculatively load it's table nice and early!)
+ JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
+ PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
+ loadPtr(static_cast<void*>(protoPropertyStorage), X86::edx);
+
+ // Check eax is an object of the right Structure.
+ Jump failureCases1 = checkStructure(X86::eax, structure);
+
+ // Check the prototype object's Structure had not changed.
+ Structure** prototypeStructureAddress = &(protoObject->m_structure);
+#if PLATFORM(X86_64)
+ move(ImmPtr(prototypeStructure), X86::ebx);
+ Jump failureCases2 = jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress));
+#else
+ Jump failureCases2 = jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+#endif
+
+ // Checks out okay! - getDirectOffset
+ loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+
+ Jump success = jump();
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+ PatchBuffer patchBuffer(code);
+
+ // Use the patch information to link the failure cases back to the original slow case routine.
+ void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
+ patchBuffer.link(failureCases1, slowCaseBegin);
+ patchBuffer.link(failureCases2, slowCaseBegin);
+
+ // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+ intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
+ patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+
+ // Track the stub we have created so that it will be deleted later.
+ stubInfo->stubRoutine = code;
+
+ // Finally patch the jump to slow case back in the hot path to jump here instead.
+ void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
+ Jump::patch(jumpLocation, code);
+#else
+ // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
+ // referencing the prototype object - let's speculatively load it's table nice and early!)
+ JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
+ PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
+ loadPtr(protoPropertyStorage, X86::edx);
+
+ // Check eax is an object of the right Structure.
+ Jump failureCases1 = emitJumpIfNotJSCell(X86::eax);
+ Jump failureCases2 = checkStructure(X86::eax, structure);
+
+ // Check the prototype object's Structure had not changed.
+ Structure** prototypeStructureAddress = &(protoObject->m_structure);
+ Jump failureCases3 = jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+
+ // Checks out okay! - getDirectOffset
+ loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+
+ ret();
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+ PatchBuffer patchBuffer(code);
+
+ patchBuffer.link(failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
+ patchBuffer.link(failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
+ patchBuffer.link(failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
+
+ stubInfo->stubRoutine = code;
+
+ Jump::patch(returnAddress, code);
+#endif
+}
+
+#if USE(CTI_REPATCH_PIC)
+void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset)
+{
+ Jump failureCase = checkStructure(X86::eax, structure);
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
+ loadPtr(Address(X86::eax, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ Jump success = jump();
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+ ASSERT(code);
+ PatchBuffer patchBuffer(code);
+
+ // Use the patch information to link the failure cases back to the original slow case routine.
+ void* lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine;
+ if (!lastProtoBegin)
+ lastProtoBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
+
+ patchBuffer.link(failureCase, lastProtoBegin);
+
+ // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+ intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
+ patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+
+ structure->ref();
+ polymorphicStructures->list[currentIndex].set(code, structure);
+
+ // Finally patch the jump to slow case back in the hot path to jump here instead.
+ void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
+ Jump::patch(jumpLocation, code);
+}
+
+void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, 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!)
+ JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
+ PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
+ loadPtr(protoPropertyStorage, X86::edx);
+
+ // Check eax is an object of the right Structure.
+ Jump failureCases1 = checkStructure(X86::eax, structure);
+
+ // Check the prototype object's Structure had not changed.
+ Structure** prototypeStructureAddress = &(protoObject->m_structure);
+#if PLATFORM(X86_64)
+ move(ImmPtr(prototypeStructure), X86::ebx);
+ Jump failureCases2 = jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress));
+#else
+ Jump failureCases2 = jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+#endif
+
+ // Checks out okay! - getDirectOffset
+ loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+
+ Jump success = jump();
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+ PatchBuffer patchBuffer(code);
+
+ // Use the patch information to link the failure cases back to the original slow case routine.
+ void* lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
+ patchBuffer.link(failureCases1, lastProtoBegin);
+ patchBuffer.link(failureCases2, lastProtoBegin);
+
+ // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+ intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
+ patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+
+ structure->ref();
+ prototypeStructure->ref();
+ prototypeStructures->list[currentIndex].set(code, structure, prototypeStructure);
+
+ // Finally patch the jump to slow case back in the hot path to jump here instead.
+ void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
+ Jump::patch(jumpLocation, code);
+}
+
+void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame)
+{
+ ASSERT(count);
+
+ JumpList bucketsOfFail;
+
+ // Check eax is an object of the right Structure.
+ Jump baseObjectCheck = checkStructure(X86::eax, structure);
+ bucketsOfFail.append(baseObjectCheck);
+
+ Structure* currStructure = structure;
+ RefPtr<Structure>* chainEntries = chain->head();
+ JSObject* protoObject = 0;
+ for (unsigned i = 0; i < count; ++i) {
+ protoObject = asObject(currStructure->prototypeForLookup(callFrame));
+ currStructure = chainEntries[i].get();
+
+ // Check the prototype object's Structure had not changed.
+ Structure** prototypeStructureAddress = &(protoObject->m_structure);
+#if PLATFORM(X86_64)
+ move(ImmPtr(currStructure), X86::ebx);
+ bucketsOfFail.append(jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress)));
+#else
+ bucketsOfFail.append(jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+#endif
+ }
+ ASSERT(protoObject);
+
+ PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
+ loadPtr(protoPropertyStorage, X86::edx);
+ loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ Jump success = jump();
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+ PatchBuffer patchBuffer(code);
+
+ // Use the patch information to link the failure cases back to the original slow case routine.
+ void* lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
+
+ patchBuffer.link(bucketsOfFail, lastProtoBegin);
+
+ // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+ intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
+ patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+
+ // Track the stub we have created so that it will be deleted later.
+ structure->ref();
+ chain->ref();
+ prototypeStructures->list[currentIndex].set(code, structure, chain);
+
+ // Finally patch the jump to slow case back in the hot path to jump here instead.
+ void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
+ Jump::patch(jumpLocation, code);
+}
+#endif
+
+void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, void* returnAddress, CallFrame* callFrame)
+{
+#if USE(CTI_REPATCH_PIC)
+ // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+ Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list));
+
+ ASSERT(count);
+
+ JumpList bucketsOfFail;
+
+ // Check eax is an object of the right Structure.
+ bucketsOfFail.append(checkStructure(X86::eax, structure));
+
+ Structure* currStructure = structure;
+ RefPtr<Structure>* chainEntries = chain->head();
+ JSObject* protoObject = 0;
+ for (unsigned i = 0; i < count; ++i) {
+ protoObject = asObject(currStructure->prototypeForLookup(callFrame));
+ currStructure = chainEntries[i].get();
+
+ // Check the prototype object's Structure had not changed.
+ Structure** prototypeStructureAddress = &(protoObject->m_structure);
+#if PLATFORM(X86_64)
+ move(ImmPtr(currStructure), X86::ebx);
+ bucketsOfFail.append(jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress)));
+#else
+ bucketsOfFail.append(jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+#endif
+ }
+ ASSERT(protoObject);
+
+ PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
+ loadPtr(protoPropertyStorage, X86::edx);
+ loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ Jump success = jump();
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+ PatchBuffer patchBuffer(code);
+
+ // Use the patch information to link the failure cases back to the original slow case routine.
+ void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
+
+ patchBuffer.link(bucketsOfFail, slowCaseBegin);
+
+ // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+ intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
+ patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+
+ // Track the stub we have created so that it will be deleted later.
+ stubInfo->stubRoutine = code;
+
+ // Finally patch the jump to slow case back in the hot path to jump here instead.
+ void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
+ Jump::patch(jumpLocation, code);
+#else
+ ASSERT(count);
+
+ JumpList bucketsOfFail;
+
+ // Check eax is an object of the right Structure.
+ bucketsOfFail.append(emitJumpIfNotJSCell(X86::eax));
+ bucketsOfFail.append(checkStructure(X86::eax, structure));
+
+ Structure* currStructure = structure;
+ RefPtr<Structure>* chainEntries = chain->head();
+ JSObject* protoObject = 0;
+ for (unsigned i = 0; i < count; ++i) {
+ protoObject = asObject(currStructure->prototypeForLookup(callFrame));
+ currStructure = chainEntries[i].get();
+
+ // Check the prototype object's Structure had not changed.
+ Structure** prototypeStructureAddress = &(protoObject->m_structure);
+#if PLATFORM(X86_64)
+ move(ImmPtr(currStructure), X86::ebx);
+ bucketsOfFail.append(jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress)));
+#else
+ bucketsOfFail.append(jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+#endif
+ }
+ ASSERT(protoObject);
+
+ PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
+ loadPtr(protoPropertyStorage, X86::edx);
+ loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ ret();
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+
+ patchBuffer.link(bucketsOfFail, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
+
+ stubInfo->stubRoutine = code;
+
+ Jump::patch(returnAddress, code);
+#endif
+}
+
+void JIT::privateCompilePutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+{
+ // Check eax is an object of the right Structure.
+ Jump failureCases1 = emitJumpIfNotJSCell(X86::eax);
+ Jump failureCases2 = checkStructure(X86::eax, structure);
+
+ // checks out okay! - putDirectOffset
+ loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
+ storePtr(X86::edx, Address(X86::eax, cachedOffset * sizeof(JSValuePtr)));
+ ret();
+
+ void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
+ PatchBuffer patchBuffer(code);
+
+ patchBuffer.link(failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));
+ patchBuffer.link(failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));
+
+ stubInfo->stubRoutine = code;
+
+ Jump::patch(returnAddress, code);
+}
+
+#endif
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/kjs/Shell.cpp b/JavaScriptCore/jsc.cpp
index f35679e..666bd58 100644
--- a/JavaScriptCore/kjs/Shell.cpp
+++ b/JavaScriptCore/jsc.cpp
@@ -22,16 +22,16 @@
#include "config.h"
-#include "CodeGenerator.h"
+#include "BytecodeGenerator.h"
+#include "Completion.h"
#include "InitializeThreading.h"
#include "JSArray.h"
#include "JSLock.h"
#include "PrototypeFunction.h"
#include "SamplingTool.h"
-#include "completion.h"
-#include "interpreter.h"
#include <math.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#if !PLATFORM(WIN_OS)
@@ -51,7 +51,7 @@
#include <signal.h>
#endif
-#if COMPILER(MSVC)
+#if COMPILER(MSVC) && !PLATFORM(WIN_CE)
#include <crtdbg.h>
#include <windows.h>
#endif
@@ -64,27 +64,26 @@
using namespace JSC;
using namespace WTF;
+static void cleanupGlobalData(JSGlobalData*);
static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer);
-static JSValue* functionPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* functionDebug(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* functionGC(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* functionVersion(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* functionRun(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* functionLoad(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* functionReadline(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* functionQuit(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr functionPrint(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr functionDebug(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr functionGC(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr functionVersion(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr functionRun(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr functionLoad(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr functionReadline(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static NO_RETURN JSValuePtr functionQuit(ExecState*, JSObject*, JSValuePtr, const ArgList&);
struct Options {
Options()
: interactive(false)
- , prettyPrint(false)
, dump(false)
{
}
bool interactive;
- bool prettyPrint;
bool dump;
Vector<UString> fileNames;
Vector<UString> arguments;
@@ -175,13 +174,13 @@ GlobalObject::GlobalObject(const Vector<UString>& arguments)
putDirect(Identifier(globalExec(), "arguments"), array);
}
-JSValue* functionPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr functionPrint(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
for (unsigned i = 0; i < args.size(); ++i) {
if (i != 0)
putchar(' ');
- printf("%s", args.at(exec, i)->toString(exec).UTF8String().c_str());
+ printf("%s", args.at(exec, i).toString(exec).UTF8String().c_str());
}
putchar('\n');
@@ -189,30 +188,30 @@ JSValue* functionPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args
return jsUndefined();
}
-JSValue* functionDebug(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr functionDebug(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- fprintf(stderr, "--> %s\n", args.at(exec, 0)->toString(exec).UTF8String().c_str());
+ fprintf(stderr, "--> %s\n", args.at(exec, 0).toString(exec).UTF8String().c_str());
return jsUndefined();
}
-JSValue* functionGC(ExecState* exec, JSObject*, JSValue*, const ArgList&)
+JSValuePtr functionGC(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
{
JSLock lock(false);
exec->heap()->collect();
return jsUndefined();
}
-JSValue* functionVersion(ExecState*, JSObject*, JSValue*, const ArgList&)
+JSValuePtr functionVersion(ExecState*, JSObject*, JSValuePtr, const ArgList&)
{
// We need this function for compatibility with the Mozilla JS tests but for now
// we don't actually do any version-specific handling
return jsUndefined();
}
-JSValue* functionRun(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr functionRun(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
StopWatch stopWatch;
- UString fileName = args.at(exec, 0)->toString(exec);
+ UString fileName = args.at(exec, 0).toString(exec);
Vector<char> script;
if (!fillBufferWithContentsOfFile(fileName, script))
return throwError(exec, GeneralError, "Could not open file.");
@@ -220,26 +219,26 @@ JSValue* functionRun(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
stopWatch.start();
- Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
+ evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
stopWatch.stop();
return jsNumber(globalObject->globalExec(), stopWatch.getElapsedMS());
}
-JSValue* functionLoad(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr functionLoad(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- UString fileName = args.at(exec, 0)->toString(exec);
+ UString fileName = args.at(exec, 0).toString(exec);
Vector<char> script;
if (!fillBufferWithContentsOfFile(fileName, script))
return throwError(exec, GeneralError, "Could not open file.");
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
- Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
+ evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
return jsUndefined();
}
-JSValue* functionReadline(ExecState* exec, JSObject*, JSValue*, const ArgList&)
+JSValuePtr functionReadline(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
{
Vector<char, 256> line;
int c;
@@ -253,13 +252,10 @@ JSValue* functionReadline(ExecState* exec, JSObject*, JSValue*, const ArgList&)
return jsString(exec, line.data());
}
-JSValue* functionQuit(ExecState*, JSObject*, JSValue*, const ArgList&)
+JSValuePtr functionQuit(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
{
- exit(0);
-#if !COMPILER(MSVC)
- // MSVC knows that exit(0) never returns, so it flags this return statement as unreachable.
- return jsUndefined();
-#endif
+ cleanupGlobalData(&exec->globalData());
+ exit(EXIT_SUCCESS);
}
// Use SEH for Release builds only to get rid of the crash report dialog
@@ -292,37 +288,38 @@ int main(int argc, char** argv)
QCoreApplication app(argc, argv);
#endif
+ // Initialize JSC before getting JSGlobalData.
+ JSC::initializeThreading();
+
+ // We can't use destructors in the following code because it uses Windows
+ // Structured Exception Handling
int res = 0;
+ JSGlobalData* globalData = JSGlobalData::create().releaseRef();
TRY
- res = jscmain(argc, argv, JSGlobalData::create().releaseRef());
+ res = jscmain(argc, argv, globalData);
EXCEPT(res = 3)
+
+ cleanupGlobalData(globalData);
return res;
}
-static bool prettyPrintScript(ExecState* exec, const UString& fileName, const Vector<char>& script)
+static void cleanupGlobalData(JSGlobalData* globalData)
{
- int errLine = 0;
- UString errMsg;
- RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), makeSource(script.data(), fileName), &errLine, &errMsg);
- if (!programNode) {
- fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
- return false;
- }
-
- printf("%s\n", programNode->toString().UTF8String().c_str());
- return true;
+ JSLock lock(false);
+ globalData->heap.destroy();
+ globalData->deref();
}
-static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fileNames, bool prettyPrint, bool dump)
+static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fileNames, bool dump)
{
Vector<char> script;
if (dump)
- CodeGenerator::setDumpsGeneratedCode(true);
+ BytecodeGenerator::setDumpsGeneratedCode(true);
#if ENABLE(OPCODE_SAMPLING)
- Machine* machine = globalObject->globalData()->machine;
- machine->setSampler(new SamplingTool(machine));
+ Interpreter* interpreter = globalObject->globalData()->interpreter;
+ interpreter->setSampler(new SamplingTool(interpreter));
#endif
bool success = true;
@@ -332,32 +329,28 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fi
if (!fillBufferWithContentsOfFile(fileName, script))
return false; // fail early so we can catch missing files
- if (prettyPrint)
- prettyPrintScript(globalObject->globalExec(), fileName, script);
- else {
#if ENABLE(OPCODE_SAMPLING)
- machine->sampler()->start();
+ interpreter->sampler()->start();
#endif
- Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
- success = success && completion.complType() != Throw;
- if (dump) {
- if (completion.complType() == Throw)
- printf("Exception: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
- else
- printf("End: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
- }
+ Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
+ success = success && completion.complType() != Throw;
+ if (dump) {
+ if (completion.complType() == Throw)
+ printf("Exception: %s\n", completion.value().toString(globalObject->globalExec()).ascii());
+ else
+ printf("End: %s\n", completion.value().toString(globalObject->globalExec()).ascii());
+ }
- globalObject->globalExec()->clearException();
+ globalObject->globalExec()->clearException();
#if ENABLE(OPCODE_SAMPLING)
- machine->sampler()->stop();
+ interpreter->sampler()->stop();
#endif
- }
}
#if ENABLE(OPCODE_SAMPLING)
- machine->sampler()->dump(globalObject->globalExec());
- delete machine->sampler();
+ interpreter->sampler()->dump(globalObject->globalExec());
+ delete interpreter->sampler();
#endif
return success;
}
@@ -371,7 +364,7 @@ static void runInteractive(GlobalObject* globalObject)
break;
if (line[0])
add_history(line);
- Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line, interpreterName));
+ Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line, interpreterName));
free(line);
#else
puts(interactivePrompt);
@@ -384,28 +377,27 @@ static void runInteractive(GlobalObject* globalObject)
line.append(c);
}
line.append('\0');
- Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line.data(), interpreterName));
+ Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line.data(), interpreterName));
#endif
if (completion.complType() == Throw)
- printf("Exception: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
+ 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().c_str());
globalObject->globalExec()->clearException();
}
printf("\n");
}
-static void printUsageStatement()
+static NO_RETURN void printUsageStatement()
{
fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n");
fprintf(stderr, " -d Dumps bytecode (debug builds only)\n");
fprintf(stderr, " -f Specifies a source file (deprecated)\n");
fprintf(stderr, " -h|--help Prints this help message\n");
fprintf(stderr, " -i Enables interactive mode (default if no files are specified)\n");
- fprintf(stderr, " -p Prints formatted source code\n");
fprintf(stderr, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n");
- exit(-1);
+ exit(EXIT_FAILURE);
}
static void parseArguments(int argc, char** argv, Options& options)
@@ -426,10 +418,6 @@ static void parseArguments(int argc, char** argv, Options& options)
options.interactive = true;
continue;
}
- if (strcmp(arg, "-p") == 0) {
- options.prettyPrint = true;
- continue;
- }
if (strcmp(arg, "-d") == 0) {
options.dump = true;
continue;
@@ -459,15 +447,13 @@ static void parseArguments(int argc, char** argv, Options& options)
int jscmain(int argc, char** argv, JSGlobalData* globalData)
{
- JSC::initializeThreading();
-
JSLock lock(false);
Options options;
parseArguments(argc, argv, options);
GlobalObject* globalObject = new (globalData) GlobalObject(options.arguments);
- bool success = runWithScripts(globalObject, options.fileNames, options.prettyPrint, options.dump);
+ bool success = runWithScripts(globalObject, options.fileNames, options.dump);
if (options.interactive && success)
runInteractive(globalObject);
diff --git a/JavaScriptCore/kjs/jsc.pro b/JavaScriptCore/jsc.pro
index 2a30d65..6262e62 100644
--- a/JavaScriptCore/kjs/jsc.pro
+++ b/JavaScriptCore/jsc.pro
@@ -1,14 +1,15 @@
TEMPLATE = app
TARGET = jsc
-DESTDIR = ..
-SOURCES = Shell.cpp
+DESTDIR = .
+SOURCES = jsc.cpp
QT -= gui
-INCLUDEPATH += $$PWD/.. \
- $$PWD \
- $$PWD/../bindings \
- $$PWD/../bindings/c \
- $$PWD/../wtf \
- $$PWD/../VM
+INCLUDEPATH += $$PWD \
+ $$PWD/parser \
+ $$PWD/bindings \
+ $$PWD/bindings/c \
+ $$PWD/wtf \
+ $$PWD/jit \
+ $$PWD/bytecode
CONFIG -= app_bundle
DEFINES += BUILDING_QT__
CONFIG += building-libs
@@ -17,19 +18,22 @@ CONFIG(release) {
DEFINES += NDEBUG USE_SYSTEM_MALLOC
}
-include($$PWD/../../WebKit.pri)
+include($$PWD/../WebKit.pri)
CONFIG += link_pkgconfig
QMAKE_RPATHDIR += $$OUTPUT_DIR/lib
-isEmpty(OUTPUT_DIR):OUTPUT_DIR=$$PWD/../..
+isEmpty(OUTPUT_DIR):OUTPUT_DIR=$$PWD/..
include($$OUTPUT_DIR/config.pri)
OBJECTS_DIR = tmp
OBJECTS_DIR_WTR = $$OBJECTS_DIR/
win32-*: OBJECTS_DIR_WTR ~= s|/|\|
-include($$PWD/../JavaScriptCore.pri)
+include($$PWD/JavaScriptCore.pri)
lessThan(QT_MINOR_VERSION, 4) {
DEFINES += QT_BEGIN_NAMESPACE="" QT_END_NAMESPACE=""
}
+
+*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2
+*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3
diff --git a/JavaScriptCore/jscore.bkl b/JavaScriptCore/jscore.bkl
index c265abc..262c883 100644
--- a/JavaScriptCore/jscore.bkl
+++ b/JavaScriptCore/jscore.bkl
@@ -37,10 +37,12 @@ JavaScriptCore Bakefile project file.
<template id="jscore_base" template="icu,pthreads,wxwk_build_settings">
<sources>
- $(JSCORE_SOURCES_API)
+ $(JSCORE_API_SOURCES)
+ $(JSCORE_BYTECOMPILER_SOURCES)
$(JSCORE_DEBUGGER_SOURCES)
- $(JSCORE_SOURCES_KJS)
- $(JSCORE_SOURCES_PCRE)
+ $(JSCORE_JSC_SOURCES)
+ $(JSCORE_PCRE_SOURCES)
+ $(JSCORE_PARSER_SOURCES)
$(JSCORE_PROFILER_SOURCES)
$(JSCORE_RUNTIME_SOURCES)
$(JSCORE_VM_SOURCES)
@@ -53,14 +55,18 @@ JavaScriptCore Bakefile project file.
<include>$(SRCDIR)</include>
<include>$(SRCDIR)/..</include>
<include>$(SRCDIR)/API</include>
+ <include>$(SRCDIR)/bytecompiler</include>
<include>$(SRCDIR)/DerivedSources/JavaScriptCore</include>
<include>$(SRCDIR)/ForwardingHeaders</include>
<include>$(SRCDIR)/debugger</include>
- <include>$(SRCDIR)/kjs</include>
+ <include>$(SRCDIR)/parser</include>
<include>$(SRCDIR)/pcre</include>
<include>$(SRCDIR)/profiler</include>
<include>$(SRCDIR)/runtime</include>
- <include>$(SRCDIR)/VM</include>
+ <include>$(SRCDIR)/interpreter</include>
+ <include>$(SRCDIR)/bytecode</include>
+ <include>$(SRCDIR)/wrec</include>
+ <include>$(SRCDIR)/jit</include>
<include>$(SRCDIR)/wtf</include>
<include>$(SRCDIR)/wtf/unicode</include>
@@ -82,22 +88,26 @@ JavaScriptCore Bakefile project file.
</template>
- <exe id="jsc" template="icu,jscore,pthreads">
+ <exe id="jsc" template="icu,jscore,pthreads,wxwk">
<cxx-rtti>off</cxx-rtti>
<cxx-exceptions>off</cxx-exceptions>
<debug-info>on</debug-info>
<depends>jscore</depends>
<include>$(SRCDIR)</include>
<include>$(WK_ROOT)/JavaScriptCore</include>
+ <include>$(WK_ROOT)/JavaScriptCore/bytecompiler</include>
<include>$(WK_ROOT)/JavaScriptCore/debugger</include>
- <include>$(WK_ROOT)/JavaScriptCore/kjs</include>
+ <include>$(WK_ROOT)/JavaScriptCore/parser</include>
<include>$(WK_ROOT)/JavaScriptCore/pcre</include>
<include>$(WK_ROOT)/JavaScriptCore/profiler</include>
<include>$(WK_ROOT)/JavaScriptCore/runtime</include>
- <include>$(WK_ROOT)/JavaScriptCore/VM</include>
+ <include>$(WK_ROOT)/JavaScriptCore/interpreter</include>
+ <include>$(WK_ROOT)/JavaScriptCore/bytecode</include>
+ <include>$(WK_ROOT)/JavaScriptCore/jit</include>
+ <include>$(WK_ROOT)/JavaScriptCore/wrec</include>
<include>$(WK_ROOT)/JavaScriptCore/wtf</include>
<dirname>$(WKOUTPUTDIR)</dirname>
- <sources>$(SRCDIR)/kjs/Shell.cpp</sources>
+ <sources>$(SRCDIR)/jsc.cpp</sources>
<if cond="FORMAT=='gnu'">
<ldflags>$(WKOUTPUTDIR)/libjscore.a</ldflags>
</if>
@@ -120,7 +130,7 @@ JavaScriptCore Bakefile project file.
<command>bash make-generated-sources.sh</command>
</action>
- <lib id="jscore" template="jscore_base">
+ <lib id="jscore" template="jscore_base,wx-lib">
</lib>
</makefile>
diff --git a/JavaScriptCore/kjs/interpreter.h b/JavaScriptCore/kjs/interpreter.h
deleted file mode 100644
index 0366063..0000000
--- a/JavaScriptCore/kjs/interpreter.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2007 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 KJS_Interpreter_h
-#define KJS_Interpreter_h
-
-#include "JSValue.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/unicode/Unicode.h>
-
-namespace JSC {
-
- class Completion;
- class ExecState;
- class ScopeChain;
- class SourceCode;
-
- class Interpreter {
- public:
- /**
- * Parses the supplied ECMAScript code and checks for syntax errors.
- *
- * @param code The code to check
- * @return A normal completion if there were no syntax errors in the code,
- * otherwise a throw completion with the syntax error as its value.
- */
- static Completion checkSyntax(ExecState*, const SourceCode&);
-
- /**
- * Evaluates the supplied ECMAScript code.
- *
- * Since this method returns a Completion, you should check the type of
- * completion to detect an error or before attempting to access the returned
- * value. For example, if an error occurs during script execution and is not
- * caught by the script, the completion type will be Throw.
- *
- * If the supplied code is invalid, a SyntaxError will be thrown.
- *
- * @param code The code to evaluate
- * @param thisValue The value to pass in as the "this" value for the script
- * execution. This should either be jsNull() or an Object.
- * @return A completion object representing the result of the execution.
- */
- static Completion evaluate(ExecState*, ScopeChain&, const SourceCode&, JSValue* thisValue = noValue());
- };
-
-} // namespace JSC
-
-#endif // KJS_Interpreter_h
diff --git a/JavaScriptCore/kjs/nodes2string.cpp b/JavaScriptCore/kjs/nodes2string.cpp
deleted file mode 100644
index 4afefe0..0000000
--- a/JavaScriptCore/kjs/nodes2string.cpp
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * Copyright (C) 2002 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *
- * This library is free software; you can redistribute it and/or
- * 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 "nodes.h"
-
-#include <wtf/MathExtras.h>
-#include <wtf/StringExtras.h>
-#include <wtf/unicode/Unicode.h>
-
-using namespace WTF;
-using namespace Unicode;
-
-namespace JSC {
-
-// A simple text streaming class that helps with code indentation.
-
-enum EndlType { Endl };
-enum IndentType { Indent };
-enum UnindentType { Unindent };
-enum DotExprType { DotExpr };
-
-class SourceStream {
-public:
- SourceStream()
- : m_numberNeedsParens(false)
- , m_atStartOfStatement(true)
- , m_precedence(PrecExpression)
- {
- }
-
- UString toString() const { return m_string; }
-
- SourceStream& operator<<(const Identifier&);
- SourceStream& operator<<(const UString&);
- SourceStream& operator<<(const char*);
- SourceStream& operator<<(double);
- SourceStream& operator<<(char);
- SourceStream& operator<<(EndlType);
- SourceStream& operator<<(IndentType);
- SourceStream& operator<<(UnindentType);
- SourceStream& operator<<(DotExprType);
- SourceStream& operator<<(Precedence);
- SourceStream& operator<<(const Node*);
- template <typename T> SourceStream& operator<<(const RefPtr<T>& n) { return *this << n.get(); }
-
-private:
- UString m_string;
- UString m_spacesForIndentation;
- bool m_numberNeedsParens;
- bool m_atStartOfStatement;
- Precedence m_precedence;
-};
-
-// --------
-
-static UString escapeStringForPrettyPrinting(const UString& s)
-{
- UString escapedString;
-
- for (int i = 0; i < s.size(); i++) {
- UChar c = s.data()[i];
- switch (c) {
- case '\"':
- escapedString += "\\\"";
- break;
- case '\n':
- escapedString += "\\n";
- break;
- case '\r':
- escapedString += "\\r";
- break;
- case '\t':
- escapedString += "\\t";
- break;
- case '\\':
- escapedString += "\\\\";
- break;
- default:
- if (c < 128 && isPrintableChar(c))
- escapedString.append(c);
- else {
- char hexValue[7];
- snprintf(hexValue, 7, "\\u%04x", c);
- escapedString += hexValue;
- }
- }
- }
-
- return escapedString;
-}
-
-static const char* operatorString(Operator oper)
-{
- switch (oper) {
- case OpEqual:
- return "=";
- case OpMultEq:
- return "*=";
- case OpDivEq:
- return "/=";
- case OpPlusEq:
- return "+=";
- case OpMinusEq:
- return "-=";
- case OpLShift:
- return "<<=";
- case OpRShift:
- return ">>=";
- case OpURShift:
- return ">>>=";
- case OpAndEq:
- return "&=";
- case OpXOrEq:
- return "^=";
- case OpOrEq:
- return "|=";
- case OpModEq:
- return "%=";
- case OpPlusPlus:
- return "++";
- case OpMinusMinus:
- return "--";
- }
- ASSERT_NOT_REACHED();
- return "???";
-}
-
-static bool isParserRoundTripNumber(const UString& string)
-{
- double number = string.toDouble(false, false);
- if (isnan(number) || isinf(number))
- return false;
- return string == UString::from(number);
-}
-
-// --------
-
-SourceStream& SourceStream::operator<<(char c)
-{
- m_numberNeedsParens = false;
- m_atStartOfStatement = false;
- // use unsigned char to zero-extend instead of sign-extend
- UChar ch(static_cast<unsigned char>(c));
- m_string.append(ch);
- return *this;
-}
-
-SourceStream& SourceStream::operator<<(const char* s)
-{
- m_numberNeedsParens = false;
- m_atStartOfStatement = false;
- m_string += s;
- return *this;
-}
-
-SourceStream& SourceStream::operator<<(double value)
-{
- bool needParens = m_numberNeedsParens;
- m_numberNeedsParens = false;
- m_atStartOfStatement = false;
-
- if (needParens)
- m_string.append('(');
- m_string += UString::from(value);
- if (needParens)
- m_string.append(')');
-
- return *this;
-}
-
-SourceStream& SourceStream::operator<<(const UString& s)
-{
- m_numberNeedsParens = false;
- m_atStartOfStatement = false;
- m_string += s;
- return *this;
-}
-
-SourceStream& SourceStream::operator<<(const Identifier& s)
-{
- m_numberNeedsParens = false;
- m_atStartOfStatement = false;
- m_string += s.ustring();
- return *this;
-}
-
-SourceStream& SourceStream::operator<<(const Node* n)
-{
- bool needParens = (m_precedence != PrecExpression && n->precedence() > m_precedence) || (m_atStartOfStatement && n->needsParensIfLeftmost());
- m_precedence = PrecExpression;
- if (!n)
- return *this;
- if (needParens) {
- m_numberNeedsParens = false;
- m_string.append('(');
- }
- n->streamTo(*this);
- if (needParens)
- m_string.append(')');
- return *this;
-}
-
-SourceStream& SourceStream::operator<<(EndlType)
-{
- m_numberNeedsParens = false;
- m_atStartOfStatement = true;
- m_string.append('\n');
- m_string.append(m_spacesForIndentation);
- return *this;
-}
-
-SourceStream& SourceStream::operator<<(IndentType)
-{
- m_numberNeedsParens = false;
- m_atStartOfStatement = false;
- m_spacesForIndentation += " ";
- return *this;
-}
-
-SourceStream& SourceStream::operator<<(UnindentType)
-{
- m_numberNeedsParens = false;
- m_atStartOfStatement = false;
- m_spacesForIndentation = m_spacesForIndentation.substr(0, m_spacesForIndentation.size() - 2);
- return *this;
-}
-
-inline SourceStream& SourceStream::operator<<(DotExprType)
-{
- m_numberNeedsParens = true;
- return *this;
-}
-
-inline SourceStream& SourceStream::operator<<(Precedence precedence)
-{
- m_precedence = precedence;
- return *this;
-}
-
-static void streamLeftAssociativeBinaryOperator(SourceStream& s, Precedence precedence,
- const char* operatorString, const Node* left, const Node* right)
-{
- s << precedence << left
- << ' ' << operatorString << ' '
- << static_cast<Precedence>(precedence - 1) << right;
-}
-
-template <typename T> static inline void streamLeftAssociativeBinaryOperator(SourceStream& s,
- Precedence p, const char* o, const RefPtr<T>& l, const RefPtr<T>& r)
-{
- streamLeftAssociativeBinaryOperator(s, p, o, l.get(), r.get());
-}
-
-static inline void bracketNodeStreamTo(SourceStream& s, const RefPtr<ExpressionNode>& base, const RefPtr<ExpressionNode>& subscript)
-{
- s << PrecCall << base.get() << "[" << subscript.get() << "]";
-}
-
-static inline void dotNodeStreamTo(SourceStream& s, const RefPtr<ExpressionNode>& base, const Identifier& ident)
-{
- s << DotExpr << PrecCall << base.get() << "." << ident;
-}
-
-// --------
-
-UString Node::toString() const
-{
- SourceStream stream;
- streamTo(stream);
- return stream.toString();
-}
-
-// --------
-
-void NullNode::streamTo(SourceStream& s) const
-{
- s << "null";
-}
-
-void BooleanNode::streamTo(SourceStream& s) const
-{
- s << (m_value ? "true" : "false");
-}
-
-void NumberNode::streamTo(SourceStream& s) const
-{
- s << value();
-}
-
-void StringNode::streamTo(SourceStream& s) const
-{
- s << '"' << escapeStringForPrettyPrinting(m_value.ustring()) << '"';
-}
-
-void RegExpNode::streamTo(SourceStream& s) const
-{
- s << '/' << m_pattern << '/' << m_flags;
-}
-
-void ThisNode::streamTo(SourceStream& s) const
-{
- s << "this";
-}
-
-void ResolveNode::streamTo(SourceStream& s) const
-{
- s << m_ident;
-}
-
-void ElementNode::streamTo(SourceStream& s) const
-{
- for (const ElementNode* n = this; n; n = n->m_next.get()) {
- for (int i = 0; i < n->m_elision; i++)
- s << ',';
- s << PrecAssignment << n->m_node;
- if (n->m_next)
- s << ',';
- }
-}
-
-void ArrayNode::streamTo(SourceStream& s) const
-{
- s << '[' << m_element;
- for (int i = 0; i < m_elision; i++)
- s << ',';
- // Parser consumes one elision comma if there's array elements
- // present in the expression.
- if (m_optional && m_element)
- s << ',';
- s << ']';
-}
-
-void ObjectLiteralNode::streamTo(SourceStream& s) const
-{
- if (m_list)
- s << "{ " << m_list << " }";
- else
- s << "{ }";
-}
-
-void PropertyListNode::streamTo(SourceStream& s) const
-{
- s << m_node;
- for (const PropertyListNode* n = m_next.get(); n; n = n->m_next.get())
- s << ", " << n->m_node;
-}
-
-void PropertyNode::streamTo(SourceStream& s) const
-{
- switch (m_type) {
- case Constant: {
- UString propertyName = name().ustring();
- if (isParserRoundTripNumber(propertyName))
- s << propertyName;
- else
- s << '"' << escapeStringForPrettyPrinting(propertyName) << '"';
- s << ": " << PrecAssignment << m_assign;
- break;
- }
- case Getter:
- case Setter: {
- const FuncExprNode* func = static_cast<const FuncExprNode*>(m_assign.get());
- if (m_type == Getter)
- s << "get ";
- else
- s << "set ";
- s << escapeStringForPrettyPrinting(name().ustring())
- << "(" << func->m_parameter << ')' << func->m_body;
- break;
- }
- }
-}
-
-void BracketAccessorNode::streamTo(SourceStream& s) const
-{
- bracketNodeStreamTo(s, m_base, m_subscript);
-}
-
-void DotAccessorNode::streamTo(SourceStream& s) const
-{
- dotNodeStreamTo(s, m_base, m_ident);
-}
-
-void ArgumentListNode::streamTo(SourceStream& s) const
-{
- s << PrecAssignment << m_expr;
- for (ArgumentListNode* n = m_next.get(); n; n = n->m_next.get())
- s << ", " << PrecAssignment << n->m_expr;
-}
-
-void ArgumentsNode::streamTo(SourceStream& s) const
-{
- s << '(' << m_listNode << ')';
-}
-
-void NewExprNode::streamTo(SourceStream& s) const
-{
- s << "new " << PrecMember << m_expr << m_args;
-}
-
-void EvalFunctionCallNode::streamTo(SourceStream& s) const
-{
- s << "eval" << m_args;
-}
-
-void FunctionCallValueNode::streamTo(SourceStream& s) const
-{
- s << PrecCall << m_expr << m_args;
-}
-
-void FunctionCallResolveNode::streamTo(SourceStream& s) const
-{
- s << m_ident << m_args;
-}
-
-void FunctionCallBracketNode::streamTo(SourceStream& s) const
-{
- bracketNodeStreamTo(s, m_base, m_subscript);
- s << m_args;
-}
-
-void FunctionCallDotNode::streamTo(SourceStream& s) const
-{
- dotNodeStreamTo(s, m_base, m_ident);
- s << m_args;
-}
-
-void PostfixResolveNode::streamTo(SourceStream& s) const
-{
- s << m_ident << operatorString(m_operator);
-}
-
-void PostfixBracketNode::streamTo(SourceStream& s) const
-{
- bracketNodeStreamTo(s, m_base, m_subscript);
- s << operatorString(m_operator);
-}
-
-void PostfixDotNode::streamTo(SourceStream& s) const
-{
- dotNodeStreamTo(s, m_base, m_ident);
- s << operatorString(m_operator);
-}
-
-void PostfixErrorNode::streamTo(SourceStream& s) const
-{
- s << PrecLeftHandSide << m_expr;
- if (m_operator == OpPlusPlus)
- s << "++";
- else
- s << "--";
-}
-
-void DeleteResolveNode::streamTo(SourceStream& s) const
-{
- s << "delete " << m_ident;
-}
-
-void DeleteBracketNode::streamTo(SourceStream& s) const
-{
- s << "delete ";
- bracketNodeStreamTo(s, m_base, m_subscript);
-}
-
-void DeleteDotNode::streamTo(SourceStream& s) const
-{
- s << "delete ";
- dotNodeStreamTo(s, m_base, m_ident);
-}
-
-void DeleteValueNode::streamTo(SourceStream& s) const
-{
- s << "delete " << PrecUnary << m_expr;
-}
-
-void VoidNode::streamTo(SourceStream& s) const
-{
- s << "void " << PrecUnary << m_expr;
-}
-
-void TypeOfValueNode::streamTo(SourceStream& s) const
-{
- s << "typeof " << PrecUnary << m_expr;
-}
-
-void TypeOfResolveNode::streamTo(SourceStream& s) const
-{
- s << "typeof " << m_ident;
-}
-
-void PrefixResolveNode::streamTo(SourceStream& s) const
-{
- s << operatorString(m_operator) << m_ident;
-}
-
-void PrefixBracketNode::streamTo(SourceStream& s) const
-{
- s << operatorString(m_operator);
- bracketNodeStreamTo(s, m_base, m_subscript);
-}
-
-void PrefixDotNode::streamTo(SourceStream& s) const
-{
- s << operatorString(m_operator);
- dotNodeStreamTo(s, m_base, m_ident);
-}
-
-void PrefixErrorNode::streamTo(SourceStream& s) const
-{
- if (m_operator == OpPlusPlus)
- s << "++" << PrecUnary << m_expr;
- else
- s << "--" << PrecUnary << m_expr;
-}
-
-void UnaryPlusNode::streamTo(SourceStream& s) const
-{
- s << "+ " << PrecUnary << m_expr;
-}
-
-void NegateNode::streamTo(SourceStream& s) const
-{
- s << "- " << PrecUnary << m_expr;
-}
-
-void BitwiseNotNode::streamTo(SourceStream& s) const
-{
- s << "~" << PrecUnary << m_expr;
-}
-
-void LogicalNotNode::streamTo(SourceStream& s) const
-{
- s << "!" << PrecUnary << m_expr;
-}
-
-void MultNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "*", m_expr1, m_expr2);
-}
-
-void DivNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "/", m_expr1, m_expr2);
-}
-
-void ModNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "%", m_expr1, m_expr2);
-}
-
-void AddNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "+", m_expr1, m_expr2);
-}
-
-void SubNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "-", m_expr1, m_expr2);
-}
-
-void LeftShiftNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "<<", m_expr1, m_expr2);
-}
-
-void RightShiftNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), ">>", m_expr1, m_expr2);
-}
-
-void UnsignedRightShiftNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), ">>>", m_expr1, m_expr2);
-}
-
-void LessNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "<", m_expr1, m_expr2);
-}
-
-void GreaterNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), ">", m_expr1, m_expr2);
-}
-
-void LessEqNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "<=", m_expr1, m_expr2);
-}
-
-void GreaterEqNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), ">=", m_expr1, m_expr2);
-}
-
-void InstanceOfNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "instanceof", m_expr1, m_expr2);
-}
-
-void InNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "in", m_expr1, m_expr2);
-}
-
-void EqualNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "==", m_expr1, m_expr2);
-}
-
-void NotEqualNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "!=", m_expr1, m_expr2);
-}
-
-void StrictEqualNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "===", m_expr1, m_expr2);
-}
-
-void NotStrictEqualNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "!==", m_expr1, m_expr2);
-}
-
-void BitAndNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "&", m_expr1, m_expr2);
-}
-
-void BitXOrNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "^", m_expr1, m_expr2);
-}
-
-void BitOrNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), "|", m_expr1, m_expr2);
-}
-
-void LogicalOpNode::streamTo(SourceStream& s) const
-{
- streamLeftAssociativeBinaryOperator(s, precedence(), (m_operator == OpLogicalAnd) ? "&&" : "||", m_expr1, m_expr2);
-}
-
-void ConditionalNode::streamTo(SourceStream& s) const
-{
- s << PrecLogicalOr << m_logical
- << " ? " << PrecAssignment << m_expr1
- << " : " << PrecAssignment << m_expr2;
-}
-
-void ReadModifyResolveNode::streamTo(SourceStream& s) const
-{
- s << m_ident << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
-}
-
-void AssignResolveNode::streamTo(SourceStream& s) const
-{
- s << m_ident << " = " << PrecAssignment << m_right;
-}
-
-void ReadModifyBracketNode::streamTo(SourceStream& s) const
-{
- bracketNodeStreamTo(s, m_base, m_subscript);
- s << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
-}
-
-void AssignBracketNode::streamTo(SourceStream& s) const
-{
- bracketNodeStreamTo(s, m_base, m_subscript);
- s << " = " << PrecAssignment << m_right;
-}
-
-void ReadModifyDotNode::streamTo(SourceStream& s) const
-{
- dotNodeStreamTo(s, m_base, m_ident);
- s << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
-}
-
-void AssignDotNode::streamTo(SourceStream& s) const
-{
- dotNodeStreamTo(s, m_base, m_ident);
- s << " = " << PrecAssignment << m_right;
-}
-
-void AssignErrorNode::streamTo(SourceStream& s) const
-{
- s << PrecLeftHandSide << m_left << ' '
- << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
-}
-
-void CommaNode::streamTo(SourceStream& s) const
-{
- s << PrecAssignment << m_expr1 << ", " << PrecAssignment << m_expr2;
-}
-
-void ConstDeclNode::streamTo(SourceStream& s) const
-{
- s << m_ident;
- if (m_init)
- s << " = " << PrecAssignment << m_init;
- for (ConstDeclNode* n = m_next.get(); n; n = n->m_next.get()) {
- s << ", " << n->m_ident;
- if (n->m_init)
- s << " = " << PrecAssignment << n->m_init;
- }
-}
-
-void ConstStatementNode::streamTo(SourceStream& s) const
-{
- s << Endl << "const " << m_next << ';';
-}
-
-static inline void statementListStreamTo(const Vector<RefPtr<StatementNode> >& nodes, SourceStream& s)
-{
- for (Vector<RefPtr<StatementNode> >::const_iterator ptr = nodes.begin(); ptr != nodes.end(); ptr++)
- s << *ptr;
-}
-
-void BlockNode::streamTo(SourceStream& s) const
-{
- s << Endl << "{" << Indent;
- statementListStreamTo(m_children, s);
- s << Unindent << Endl << "}";
-}
-
-void ScopeNode::streamTo(SourceStream& s) const
-{
- s << Endl << "{" << Indent;
-
- bool printedVar = false;
- for (size_t i = 0; i < m_varStack.size(); ++i) {
- if (m_varStack[i].second == 0) {
- if (!printedVar) {
- s << Endl << "var ";
- printedVar = true;
- } else
- s << ", ";
- s << m_varStack[i].first;
- }
- }
- if (printedVar)
- s << ';';
-
- statementListStreamTo(m_children, s);
- s << Unindent << Endl << "}";
-}
-
-void EmptyStatementNode::streamTo(SourceStream& s) const
-{
- s << Endl << ';';
-}
-
-void DebuggerStatementNode::streamTo(SourceStream& s) const
-{
- s << Endl << "debugger;";
-}
-
-void ExprStatementNode::streamTo(SourceStream& s) const
-{
- s << Endl << m_expr << ';';
-}
-
-void VarStatementNode::streamTo(SourceStream& s) const
-{
- s << Endl << "var " << m_expr << ';';
-}
-
-void IfNode::streamTo(SourceStream& s) const
-{
- s << Endl << "if (" << m_condition << ')' << Indent << m_ifBlock << Unindent;
-}
-
-void IfElseNode::streamTo(SourceStream& s) const
-{
- IfNode::streamTo(s);
- s << Endl << "else" << Indent << m_elseBlock << Unindent;
-}
-
-void DoWhileNode::streamTo(SourceStream& s) const
-{
- s << Endl << "do " << Indent << m_statement << Unindent << Endl
- << "while (" << m_expr << ");";
-}
-
-void WhileNode::streamTo(SourceStream& s) const
-{
- s << Endl << "while (" << m_expr << ')' << Indent << m_statement << Unindent;
-}
-
-void ForNode::streamTo(SourceStream& s) const
-{
- s << Endl << "for ("
- << (m_expr1WasVarDecl ? "var " : "")
- << m_expr1
- << "; " << m_expr2
- << "; " << m_expr3
- << ')' << Indent << m_statement << Unindent;
-}
-
-void ForInNode::streamTo(SourceStream& s) const
-{
- s << Endl << "for (";
- if (m_identIsVarDecl) {
- s << "var ";
- if (m_init)
- s << m_init;
- else
- s << PrecLeftHandSide << m_lexpr;
- } else
- s << PrecLeftHandSide << m_lexpr;
-
- s << " in " << m_expr << ')' << Indent << m_statement << Unindent;
-}
-
-void ContinueNode::streamTo(SourceStream& s) const
-{
- s << Endl << "continue";
- if (!m_ident.isNull())
- s << ' ' << m_ident;
- s << ';';
-}
-
-void BreakNode::streamTo(SourceStream& s) const
-{
- s << Endl << "break";
- if (!m_ident.isNull())
- s << ' ' << m_ident;
- s << ';';
-}
-
-void ReturnNode::streamTo(SourceStream& s) const
-{
- s << Endl << "return";
- if (m_value)
- s << ' ' << m_value;
- s << ';';
-}
-
-void WithNode::streamTo(SourceStream& s) const
-{
- s << Endl << "with (" << m_expr << ") " << m_statement;
-}
-
-void CaseClauseNode::streamTo(SourceStream& s) const
-{
- s << Endl;
- if (m_expr)
- s << "case " << m_expr;
- else
- s << "default";
- s << ":" << Indent;
- statementListStreamTo(m_children, s);
- s << Unindent;
-}
-
-void ClauseListNode::streamTo(SourceStream& s) const
-{
- for (const ClauseListNode* n = this; n; n = n->getNext())
- s << n->getClause();
-}
-
-void CaseBlockNode::streamTo(SourceStream& s) const
-{
- for (const ClauseListNode* n = m_list1.get(); n; n = n->getNext())
- s << n->getClause();
- s << m_defaultClause;
- for (const ClauseListNode* n = m_list2.get(); n; n = n->getNext())
- s << n->getClause();
-}
-
-void SwitchNode::streamTo(SourceStream& s) const
-{
- s << Endl << "switch (" << m_expr << ") {"
- << Indent << m_block << Unindent
- << Endl << "}";
-}
-
-void LabelNode::streamTo(SourceStream& s) const
-{
- s << Endl << m_name << ":" << Indent << m_statement << Unindent;
-}
-
-void ThrowNode::streamTo(SourceStream& s) const
-{
- s << Endl << "throw " << m_expr << ';';
-}
-
-void TryNode::streamTo(SourceStream& s) const
-{
- s << Endl << "try " << m_tryBlock;
- if (m_catchBlock)
- s << Endl << "catch (" << m_exceptionIdent << ')' << m_catchBlock;
- if (m_finallyBlock)
- s << Endl << "finally " << m_finallyBlock;
-}
-
-void ParameterNode::streamTo(SourceStream& s) const
-{
- s << m_ident;
- for (ParameterNode* n = m_next.get(); n; n = n->m_next.get())
- s << ", " << n->m_ident;
-}
-
-void FuncDeclNode::streamTo(SourceStream& s) const
-{
- s << Endl << "function " << m_ident << '(' << m_parameter << ')' << m_body;
-}
-
-void FuncExprNode::streamTo(SourceStream& s) const
-{
- s << "function " << m_ident << '(' << m_parameter << ')' << m_body;
-}
-
-} // namespace JSC
diff --git a/JavaScriptCore/kjs/operations.h b/JavaScriptCore/kjs/operations.h
deleted file mode 100644
index fad9720..0000000
--- a/JavaScriptCore/kjs/operations.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * This file is part of the KDE libraries
- * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *
- * 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 _KJS_OPERATIONS_H_
-#define _KJS_OPERATIONS_H_
-
-#include "JSImmediate.h"
-#include "JSNumberCell.h"
-#include "JSString.h"
-
-namespace JSC {
-
- // ECMA 11.9.3
- bool equal(ExecState*, JSValue*, JSValue*);
- bool equalSlowCase(ExecState*, JSValue*, JSValue*);
-
- ALWAYS_INLINE bool equalSlowCaseInline(ExecState* exec, JSValue* v1, JSValue* v2)
- {
- ASSERT(!JSImmediate::areBothImmediateNumbers(v1, v2));
-
- do {
- if (v1->isNumber() && v2->isNumber())
- return v1->uncheckedGetNumber() == v2->uncheckedGetNumber();
-
- bool s1 = v1->isString();
- bool s2 = v2->isString();
- if (s1 && s2)
- return asString(v1)->value() == asString(v2)->value();
-
- if (v1->isUndefinedOrNull()) {
- if (v2->isUndefinedOrNull())
- return true;
- if (JSImmediate::isImmediate(v2))
- return false;
- return v2->asCell()->structureID()->typeInfo().masqueradesAsUndefined();
- }
-
- if (v2->isUndefinedOrNull()) {
- if (JSImmediate::isImmediate(v1))
- return false;
- return v1->asCell()->structureID()->typeInfo().masqueradesAsUndefined();
- }
-
- if (v1->isObject()) {
- if (v2->isObject())
- return v1 == v2;
- JSValue* p1 = v1->toPrimitive(exec);
- if (exec->hadException())
- return false;
- v1 = p1;
- if (JSImmediate::areBothImmediateNumbers(v1, v2))
- return v1 == v2;
- continue;
- }
-
- if (v2->isObject()) {
- JSValue* p2 = v2->toPrimitive(exec);
- if (exec->hadException())
- return false;
- v2 = p2;
- if (JSImmediate::areBothImmediateNumbers(v1, v2))
- return v1 == v2;
- continue;
- }
-
- if (s1 || s2) {
- double d1 = v1->toNumber(exec);
- double d2 = v2->toNumber(exec);
- return d1 == d2;
- }
-
- if (v1->isBoolean()) {
- if (v2->isNumber())
- return static_cast<double>(v1->getBoolean()) == v2->uncheckedGetNumber();
- } else if (v2->isBoolean()) {
- if (v1->isNumber())
- return v1->uncheckedGetNumber() == static_cast<double>(v2->getBoolean());
- }
-
- return v1 == v2;
- } while (true);
- }
-
-
- bool strictEqual(JSValue*, JSValue*);
- bool strictEqualSlowCase(JSValue*, JSValue*);
-
- inline bool strictEqualSlowCaseInline(JSValue* v1, JSValue* v2)
- {
- ASSERT(!JSImmediate::areBothImmediate(v1, v2));
-
- if (JSImmediate::isEitherImmediate(v1, v2)) {
- ASSERT(v1 == JSImmediate::zeroImmediate() || v2 == JSImmediate::zeroImmediate());
- ASSERT(v1 != v2);
-
- // The reason we can't just return false here is that 0 === -0,
- // and while the former is an immediate number, the latter is not.
- if (v1 == JSImmediate::zeroImmediate())
- return asCell(v2)->isNumber() && asNumberCell(v2)->value() == 0;
- return asCell(v1)->isNumber() && asNumberCell(v1)->value() == 0;
- }
-
- if (asCell(v1)->isNumber()) {
- return asCell(v2)->isNumber()
- && asNumberCell(v1)->value() == asNumberCell(v2)->value();
- }
-
- if (asCell(v1)->isString()) {
- return asCell(v2)->isString()
- && asString(v1)->value() == asString(v2)->value();
- }
-
- return v1 == v2;
- }
-
- JSValue* throwOutOfMemoryError(ExecState*);
-}
-
-#endif
diff --git a/JavaScriptCore/kjs/protect.h b/JavaScriptCore/kjs/protect.h
deleted file mode 100644
index b317424..0000000
--- a/JavaScriptCore/kjs/protect.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2004, 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 protect_h
-#define protect_h
-
-#include "JSCell.h"
-#include "collector.h"
-
-namespace JSC {
-
- inline void gcProtect(JSCell* val)
- {
- Heap::heap(val)->protect(val);
- }
-
- inline void gcUnprotect(JSCell* val)
- {
- Heap::heap(val)->unprotect(val);
- }
-
- inline void gcProtectNullTolerant(JSCell* val)
- {
- if (val)
- gcProtect(val);
- }
-
- inline void gcUnprotectNullTolerant(JSCell* val)
- {
- if (val)
- gcUnprotect(val);
- }
-
- inline void gcProtect(JSValue* value)
- {
- if (JSImmediate::isImmediate(value))
- return;
- gcProtect(asCell(value));
- }
-
- inline void gcUnprotect(JSValue* value)
- {
- if (JSImmediate::isImmediate(value))
- return;
- gcUnprotect(asCell(value));
- }
-
- inline void gcProtectNullTolerant(JSValue* value)
- {
- if (!value || JSImmediate::isImmediate(value))
- return;
- gcProtect(asCell(value));
- }
-
- inline void gcUnprotectNullTolerant(JSValue* value)
- {
- if (!value || JSImmediate::isImmediate(value))
- return;
- gcUnprotect(asCell(value));
- }
-
- // FIXME: Share more code with RefPtr template? The only differences are the ref/deref operation
- // and the implicit conversion to raw pointer
- template <class T> class ProtectedPtr {
- public:
- ProtectedPtr() : m_ptr(0) { }
- ProtectedPtr(T* ptr);
- ProtectedPtr(const ProtectedPtr&);
- ~ProtectedPtr();
-
- template <class U> ProtectedPtr(const ProtectedPtr<U>&);
-
- T* get() const { return m_ptr; }
- operator T*() const { return m_ptr; }
- T* operator->() const { return m_ptr; }
-
- bool operator!() const { return !m_ptr; }
-
- ProtectedPtr& operator=(const ProtectedPtr&);
- ProtectedPtr& operator=(T*);
-
- private:
- T* m_ptr;
- };
-
- template <class T> ProtectedPtr<T>::ProtectedPtr(T* ptr)
- : m_ptr(ptr)
- {
- gcProtectNullTolerant(m_ptr);
- }
-
- template <class T> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr& o)
- : m_ptr(o.get())
- {
- gcProtectNullTolerant(m_ptr);
- }
-
- template <class T> ProtectedPtr<T>::~ProtectedPtr()
- {
- gcUnprotectNullTolerant(m_ptr);
- }
-
- template <class T> template <class U> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U>& o)
- : m_ptr(o.get())
- {
- gcProtectNullTolerant(m_ptr);
- }
-
- template <class T> ProtectedPtr<T>& ProtectedPtr<T>::operator=(const ProtectedPtr<T>& o)
- {
- T* optr = o.m_ptr;
- gcProtectNullTolerant(optr);
- gcUnprotectNullTolerant(m_ptr);
- m_ptr = optr;
- return *this;
- }
-
- template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(T* optr)
- {
- gcProtectNullTolerant(optr);
- gcUnprotectNullTolerant(m_ptr);
- m_ptr = optr;
- return *this;
- }
-
- template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() == b.get(); }
- template <class T> inline bool operator==(const ProtectedPtr<T>& a, const T* b) { return a.get() == b; }
- template <class T> inline bool operator==(const T* a, const ProtectedPtr<T>& b) { return a == b.get(); }
-
- template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() != b.get(); }
- template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const T* b) { return a.get() != b; }
- template <class T> inline bool operator!=(const T* a, const ProtectedPtr<T>& b) { return a != b.get(); }
-
-} // namespace JSC
-
-#endif // protect_h
diff --git a/JavaScriptCore/make-generated-sources.sh b/JavaScriptCore/make-generated-sources.sh
index e1e247b..943a7cc 100755
--- a/JavaScriptCore/make-generated-sources.sh
+++ b/JavaScriptCore/make-generated-sources.sh
@@ -2,7 +2,7 @@
export SRCROOT=$PWD
export WebCore=$PWD
-export CREATE_HASH_TABLE="$SRCROOT/kjs/create_hash_table"
+export CREATE_HASH_TABLE="$SRCROOT/create_hash_table"
mkdir -p DerivedSources/JavaScriptCore
cd DerivedSources/JavaScriptCore
diff --git a/JavaScriptCore/masm/X86Assembler.h b/JavaScriptCore/masm/X86Assembler.h
deleted file mode 100644
index 547c94e..0000000
--- a/JavaScriptCore/masm/X86Assembler.h
+++ /dev/null
@@ -1,1262 +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 X86Assembler_h
-#define X86Assembler_h
-
-#if ENABLE(MASM) && PLATFORM(X86)
-
-#include <wtf/Assertions.h>
-#include <wtf/AlwaysInline.h>
-#include <wtf/FastMalloc.h>
-
-#if HAVE(MMAN)
-#include <sys/mman.h>
-#endif
-
-#include <string.h>
-
-namespace JSC {
-
-class JITCodeBuffer {
-public:
- JITCodeBuffer(int size)
- : m_buffer(static_cast<char*>(fastMalloc(size)))
- , m_size(size)
- , m_index(0)
- {
- }
-
- ~JITCodeBuffer()
- {
- fastFree(m_buffer);
- }
-
- void ensureSpace(int space)
- {
- if (m_index > m_size - space)
- growBuffer();
- }
-
- void putByteUnchecked(int value)
- {
- m_buffer[m_index] = value;
- m_index++;
- }
-
- void putByte(int value)
- {
- if (m_index > m_size - 4)
- growBuffer();
- putByteUnchecked(value);
- }
-
- void putShortUnchecked(int value)
- {
- *(short*)(&m_buffer[m_index]) = value;
- m_index += 2;
- }
-
- void putShort(int value)
- {
- if (m_index > m_size - 4)
- growBuffer();
- putShortUnchecked(value);
- }
-
- void putIntUnchecked(int value)
- {
- *reinterpret_cast<int*>(&m_buffer[m_index]) = value;
- m_index += 4;
- }
-
- void putInt(int value)
- {
- if (m_index > m_size - 4)
- growBuffer();
- putIntUnchecked(value);
- }
-
- void* getEIP()
- {
- return m_buffer + m_index;
- }
-
- void* start()
- {
- return m_buffer;
- }
-
- int getOffset()
- {
- return m_index;
- }
-
- JITCodeBuffer* reset()
- {
- m_index = 0;
- return this;
- }
-
- void* copy()
- {
- if (!m_index)
- return 0;
-
- void* result = WTF::fastMallocExecutable(m_index);
-
- if (!result)
- return 0;
-
- return memcpy(result, m_buffer, m_index);
- }
-
-private:
- void growBuffer()
- {
- m_size += m_size / 2;
- m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_size));
- }
-
- char* m_buffer;
- int m_size;
- int m_index;
-};
-
-#define MODRM(type, reg, rm) ((type << 6) | (reg << 3) | (rm))
-#define SIB(type, reg, rm) MODRM(type, reg, rm)
-#define CAN_SIGN_EXTEND_8_32(value) (value == ((int)(signed char)value))
-
-namespace X86 {
- typedef enum {
- eax,
- ecx,
- edx,
- ebx,
- esp,
- ebp,
- esi,
- edi,
-
- noBase = ebp,
- hasSib = esp,
- noScale = esp,
- } RegisterID;
-
- typedef enum {
- xmm0,
- xmm1,
- xmm2,
- xmm3,
- xmm4,
- xmm5,
- xmm6,
- xmm7,
- } XMMRegisterID;
-}
-
-class X86Assembler {
-public:
- typedef X86::RegisterID RegisterID;
- typedef X86::XMMRegisterID XMMRegisterID;
- typedef enum {
- OP_ADD_EvGv = 0x01,
- OP_ADD_GvEv = 0x03,
- OP_OR_EvGv = 0x09,
- OP_OR_GvEv = 0x0B,
- OP_2BYTE_ESCAPE = 0x0F,
- OP_AND_EvGv = 0x21,
- OP_SUB_EvGv = 0x29,
- OP_SUB_GvEv = 0x2B,
- PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
- OP_XOR_EvGv = 0x31,
- OP_CMP_EvGv = 0x39,
- OP_CMP_GvEv = 0x3B,
- OP_PUSH_EAX = 0x50,
- OP_POP_EAX = 0x58,
- PRE_OPERAND_SIZE = 0x66,
- PRE_SSE_66 = 0x66,
- OP_PUSH_Iz = 0x68,
- OP_IMUL_GvEvIz = 0x69,
- OP_GROUP1_EvIz = 0x81,
- OP_GROUP1_EvIb = 0x83,
- OP_TEST_EvGv = 0x85,
- OP_MOV_EvGv = 0x89,
- OP_MOV_GvEv = 0x8B,
- OP_LEA = 0x8D,
- OP_GROUP1A_Ev = 0x8F,
- OP_CDQ = 0x99,
- OP_SETE = 0x94,
- OP_SETNE = 0x95,
- OP_GROUP2_EvIb = 0xC1,
- OP_RET = 0xC3,
- OP_GROUP11_EvIz = 0xC7,
- OP_INT3 = 0xCC,
- OP_GROUP2_Ev1 = 0xD1,
- OP_GROUP2_EvCL = 0xD3,
- OP_CALL_rel32 = 0xE8,
- OP_JMP_rel32 = 0xE9,
- PRE_SSE_F2 = 0xF2,
- OP_GROUP3_Ev = 0xF7,
- OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
- OP_GROUP5_Ev = 0xFF,
-
- OP2_MOVSD_VsdWsd = 0x10,
- OP2_MOVSD_WsdVsd = 0x11,
- OP2_CVTSI2SD_VsdEd = 0x2A,
- OP2_CVTTSD2SI_GdWsd = 0x2C,
- OP2_UCOMISD_VsdWsd = 0x2E,
- OP2_XORPD_VsdWsd = 0x57,
- OP2_ADDSD_VsdWsd = 0x58,
- OP2_MULSD_VsdWsd = 0x59,
- OP2_SUBSD_VsdWsd = 0x5C,
- OP2_MOVD_EdVd = 0x7E,
- OP2_JO_rel32 = 0x80,
- OP2_JB_rel32 = 0x82,
- OP2_JAE_rel32 = 0x83,
- OP2_JE_rel32 = 0x84,
- OP2_JNE_rel32 = 0x85,
- OP2_JBE_rel32 = 0x86,
- OP2_JA_rel32 = 0x87,
- OP2_JS_rel32 = 0x88,
- OP2_JP_rel32 = 0x8A,
- OP2_JL_rel32 = 0x8C,
- OP2_JGE_rel32 = 0x8D,
- OP2_JLE_rel32 = 0x8E,
- OP2_JG_rel32 = 0x8F,
- OP2_IMUL_GvEv = 0xAF,
- OP2_MOVZX_GvEb = 0xB6,
- OP2_MOVZX_GvEw = 0xB7,
- OP2_PEXTRW_GdUdIb = 0xC5,
-
- GROUP1_OP_ADD = 0,
- GROUP1_OP_OR = 1,
- GROUP1_OP_AND = 4,
- GROUP1_OP_SUB = 5,
- GROUP1_OP_XOR = 6,
- GROUP1_OP_CMP = 7,
-
- GROUP1A_OP_POP = 0,
-
- GROUP2_OP_SHL = 4,
- GROUP2_OP_SAR = 7,
-
- GROUP3_OP_TEST = 0,
- GROUP3_OP_NEG = 3,
- GROUP3_OP_IDIV = 7,
-
- GROUP5_OP_CALLN = 2,
- GROUP5_OP_JMPN = 4,
- GROUP5_OP_PUSH = 6,
-
- GROUP11_MOV = 0,
- } OpcodeID;
-
- static const int MAX_INSTRUCTION_SIZE = 16;
-
- X86Assembler(JITCodeBuffer* m_buffer)
- : m_buffer(m_buffer)
- {
- m_buffer->reset();
- }
-
- void emitInt3()
- {
- m_buffer->putByte(OP_INT3);
- }
-
- void pushl_r(RegisterID reg)
- {
- m_buffer->putByte(OP_PUSH_EAX + reg);
- }
-
- void pushl_m(int offset, RegisterID base)
- {
- m_buffer->putByte(OP_GROUP5_Ev);
- emitModRm_opm(GROUP5_OP_PUSH, base, offset);
- }
-
- void pushl_i32(int imm)
- {
- m_buffer->putByte(OP_PUSH_Iz);
- m_buffer->putInt(imm);
- }
-
- void popl_r(RegisterID reg)
- {
- m_buffer->putByte(OP_POP_EAX + reg);
- }
-
- void popl_m(int offset, RegisterID base)
- {
- m_buffer->putByte(OP_GROUP1A_Ev);
- emitModRm_opm(GROUP1A_OP_POP, base, offset);
- }
-
- void movl_rr(RegisterID src, RegisterID dst)
- {
- m_buffer->putByte(OP_MOV_EvGv);
- emitModRm_rr(src, dst);
- }
-
- void addl_rr(RegisterID src, RegisterID dst)
- {
- m_buffer->putByte(OP_ADD_EvGv);
- emitModRm_rr(src, dst);
- }
-
- void addl_i8r(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIb);
- emitModRm_opr(GROUP1_OP_ADD, dst);
- m_buffer->putByte(imm);
- }
-
- void addl_i8m(int imm, void* addr)
- {
- m_buffer->putByte(OP_GROUP1_EvIb);
- emitModRm_opm(GROUP1_OP_ADD, addr);
- m_buffer->putByte(imm);
- }
-
- void addl_i32r(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIz);
- emitModRm_opr(GROUP1_OP_ADD, dst);
- m_buffer->putInt(imm);
- }
-
- void addl_mr(int offset, RegisterID base, RegisterID dst)
- {
- m_buffer->putByte(OP_ADD_GvEv);
- emitModRm_rm(dst, base, offset);
- }
-
- void andl_rr(RegisterID src, RegisterID dst)
- {
- m_buffer->putByte(OP_AND_EvGv);
- emitModRm_rr(src, dst);
- }
-
- void andl_i32r(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIz);
- emitModRm_opr(GROUP1_OP_AND, dst);
- m_buffer->putInt(imm);
- }
-
- void cmpl_i8r(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIb);
- emitModRm_opr(GROUP1_OP_CMP, dst);
- m_buffer->putByte(imm);
- }
-
- void cmpl_rr(RegisterID src, RegisterID dst)
- {
- m_buffer->putByte(OP_CMP_EvGv);
- emitModRm_rr(src, dst);
- }
-
- void cmpl_rm(RegisterID src, int offset, RegisterID base)
- {
- m_buffer->putByte(OP_CMP_EvGv);
- emitModRm_rm(src, base, offset);
- }
-
- void cmpl_mr(int offset, RegisterID base, RegisterID dst)
- {
- m_buffer->putByte(OP_CMP_GvEv);
- emitModRm_rm(dst, base, offset);
- }
-
- void cmpl_i32r(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIz);
- emitModRm_opr(GROUP1_OP_CMP, dst);
- m_buffer->putInt(imm);
- }
-
- void cmpl_i32m(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIz);
- emitModRm_opm(GROUP1_OP_CMP, dst);
- m_buffer->putInt(imm);
- }
-
- void cmpl_i32m(int imm, int offset, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIz);
- emitModRm_opm(GROUP1_OP_CMP, dst, offset);
- m_buffer->putInt(imm);
- }
-
- void cmpl_i32m(int imm, void* addr)
- {
- m_buffer->putByte(OP_GROUP1_EvIz);
- emitModRm_opm(GROUP1_OP_CMP, addr);
- m_buffer->putInt(imm);
- }
-
- void cmpl_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
- {
- m_buffer->putByte(OP_GROUP1_EvIb);
- emitModRm_opmsib(GROUP1_OP_CMP, base, index, scale, offset);
- m_buffer->putByte(imm);
- }
-
- void cmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale)
- {
- m_buffer->putByte(PRE_OPERAND_SIZE);
- m_buffer->putByte(OP_CMP_EvGv);
- emitModRm_rmsib(src, base, index, scale);
- }
-
- void sete_r(RegisterID dst)
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP_SETE);
- m_buffer->putByte(MODRM(3, 0, dst));
- }
-
- void setz_r(RegisterID dst)
- {
- sete_r(dst);
- }
-
- void setne_r(RegisterID dst)
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP_SETNE);
- m_buffer->putByte(MODRM(3, 0, dst));
- }
-
- void setnz_r(RegisterID dst)
- {
- setne_r(dst);
- }
-
- void orl_rr(RegisterID src, RegisterID dst)
- {
- m_buffer->putByte(OP_OR_EvGv);
- emitModRm_rr(src, dst);
- }
-
- void orl_mr(int offset, RegisterID base, RegisterID dst)
- {
- m_buffer->putByte(OP_OR_GvEv);
- emitModRm_rm(dst, base, offset);
- }
-
- void orl_i32r(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIb);
- emitModRm_opr(GROUP1_OP_OR, dst);
- m_buffer->putByte(imm);
- }
-
- void subl_rr(RegisterID src, RegisterID dst)
- {
- m_buffer->putByte(OP_SUB_EvGv);
- emitModRm_rr(src, dst);
- }
-
- void subl_i8r(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIb);
- emitModRm_opr(GROUP1_OP_SUB, dst);
- m_buffer->putByte(imm);
- }
-
- void subl_i8m(int imm, void* addr)
- {
- m_buffer->putByte(OP_GROUP1_EvIb);
- emitModRm_opm(GROUP1_OP_SUB, addr);
- m_buffer->putByte(imm);
- }
-
- void subl_i32r(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIz);
- emitModRm_opr(GROUP1_OP_SUB, dst);
- m_buffer->putInt(imm);
- }
-
- void subl_mr(int offset, RegisterID base, RegisterID dst)
- {
- m_buffer->putByte(OP_SUB_GvEv);
- emitModRm_rm(dst, base, offset);
- }
-
- void testl_i32r(int imm, RegisterID dst)
- {
- m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
- m_buffer->putByteUnchecked(OP_GROUP3_EvIz);
- emitModRm_opr_Unchecked(GROUP3_OP_TEST, dst);
- m_buffer->putIntUnchecked(imm);
- }
-
- void testl_i32m(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP3_EvIz);
- emitModRm_opm(GROUP3_OP_TEST, dst);
- m_buffer->putInt(imm);
- }
-
- void testl_i32m(int imm, int offset, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP3_EvIz);
- emitModRm_opm(GROUP3_OP_TEST, dst, offset);
- m_buffer->putInt(imm);
- }
-
- void testl_rr(RegisterID src, RegisterID dst)
- {
- m_buffer->putByte(OP_TEST_EvGv);
- emitModRm_rr(src, dst);
- }
-
- void xorl_i8r(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP1_EvIb);
- emitModRm_opr(GROUP1_OP_XOR, dst);
- m_buffer->putByte(imm);
- }
-
- void xorl_rr(RegisterID src, RegisterID dst)
- {
- m_buffer->putByte(OP_XOR_EvGv);
- emitModRm_rr(src, dst);
- }
-
- void sarl_i8r(int imm, RegisterID dst)
- {
- if (imm == 1) {
- m_buffer->putByte(OP_GROUP2_Ev1);
- emitModRm_opr(GROUP2_OP_SAR, dst);
- } else {
- m_buffer->putByte(OP_GROUP2_EvIb);
- emitModRm_opr(GROUP2_OP_SAR, dst);
- m_buffer->putByte(imm);
- }
- }
-
- void sarl_CLr(RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP2_EvCL);
- emitModRm_opr(GROUP2_OP_SAR, dst);
- }
-
- void shl_i8r(int imm, RegisterID dst)
- {
- if (imm == 1) {
- m_buffer->putByte(OP_GROUP2_Ev1);
- emitModRm_opr(GROUP2_OP_SHL, dst);
- } else {
- m_buffer->putByte(OP_GROUP2_EvIb);
- emitModRm_opr(GROUP2_OP_SHL, dst);
- m_buffer->putByte(imm);
- }
- }
-
- void shll_CLr(RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP2_EvCL);
- emitModRm_opr(GROUP2_OP_SHL, dst);
- }
-
- void imull_rr(RegisterID src, RegisterID dst)
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_IMUL_GvEv);
- emitModRm_rr(dst, src);
- }
-
- void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
- {
- m_buffer->putByte(OP_IMUL_GvEvIz);
- emitModRm_rr(dst, src);
- m_buffer->putInt(value);
- }
-
- void idivl_r(RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP3_Ev);
- emitModRm_opr(GROUP3_OP_IDIV, dst);
- }
-
- void negl_r(RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP3_Ev);
- emitModRm_opr(GROUP3_OP_NEG, dst);
- }
-
- void cdq()
- {
- m_buffer->putByte(OP_CDQ);
- }
-
- void movl_mr(RegisterID base, RegisterID dst)
- {
- m_buffer->putByte(OP_MOV_GvEv);
- emitModRm_rm(dst, base);
- }
-
- void movl_mr(int offset, RegisterID base, RegisterID dst)
- {
- m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
- m_buffer->putByteUnchecked(OP_MOV_GvEv);
- emitModRm_rm_Unchecked(dst, base, offset);
- }
-
- void movl_mr(void* addr, RegisterID dst)
- {
- m_buffer->putByte(OP_MOV_GvEv);
- emitModRm_rm(dst, addr);
- }
-
- void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
- {
- m_buffer->putByte(OP_MOV_GvEv);
- emitModRm_rmsib(dst, base, index, scale, offset);
- }
-
- void movzbl_rr(RegisterID src, RegisterID dst)
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_MOVZX_GvEb);
- emitModRm_rr(dst, src);
- }
-
- void movzwl_mr(int offset, RegisterID base, RegisterID dst)
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_MOVZX_GvEw);
- emitModRm_rm(dst, base, offset);
- }
-
- void movzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst)
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_MOVZX_GvEw);
- emitModRm_rmsib(dst, base, index, scale);
- }
-
- void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_MOVZX_GvEw);
- emitModRm_rmsib(dst, base, index, scale, offset);
- }
-
- void movl_rm(RegisterID src, RegisterID base)
- {
- m_buffer->putByte(OP_MOV_EvGv);
- emitModRm_rm(src, base);
- }
-
- void movl_rm(RegisterID src, int offset, RegisterID base)
- {
- m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
- m_buffer->putByteUnchecked(OP_MOV_EvGv);
- emitModRm_rm_Unchecked(src, base, offset);
- }
-
- void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
- {
- m_buffer->putByte(OP_MOV_EvGv);
- emitModRm_rmsib(src, base, index, scale, offset);
- }
-
- void movl_i32r(int imm, RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP11_EvIz);
- emitModRm_opr(GROUP11_MOV, dst);
- m_buffer->putInt(imm);
- }
-
- void movl_i32m(int imm, int offset, RegisterID base)
- {
- m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
- m_buffer->putByteUnchecked(OP_GROUP11_EvIz);
- emitModRm_opm_Unchecked(GROUP11_MOV, base, offset);
- m_buffer->putIntUnchecked(imm);
- }
-
- void movl_i32m(int imm, void* addr)
- {
- m_buffer->putByte(OP_GROUP11_EvIz);
- emitModRm_opm(GROUP11_MOV, addr);
- m_buffer->putInt(imm);
- }
-
- void leal_mr(int offset, RegisterID base, RegisterID dst)
- {
- m_buffer->putByte(OP_LEA);
- emitModRm_rm(dst, base, offset);
- }
-
- void leal_mr(int offset, RegisterID index, int scale, RegisterID dst)
- {
- m_buffer->putByte(OP_LEA);
- emitModRm_rmsib(dst, X86::noBase, index, scale, offset);
- }
-
- void ret()
- {
- m_buffer->putByte(OP_RET);
- }
-
- void jmp_r(RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP5_Ev);
- emitModRm_opr(GROUP5_OP_JMPN, dst);
- }
-
- void jmp_m(int offset, RegisterID base)
- {
- m_buffer->putByte(OP_GROUP5_Ev);
- emitModRm_opm(GROUP5_OP_JMPN, base, offset);
- }
-
- void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_F2);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_MOVSD_VsdWsd);
- emitModRm_rm((RegisterID)dst, base, offset);
- }
-
- void xorpd_mr(void* addr, XMMRegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_66);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_XORPD_VsdWsd);
- emitModRm_rm((RegisterID)dst, addr);
- }
-
- void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
- {
- m_buffer->putByte(PRE_SSE_F2);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_MOVSD_WsdVsd);
- emitModRm_rm((RegisterID)src, base, offset);
- }
-
- void movd_rr(XMMRegisterID src, RegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_66);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_MOVD_EdVd);
- emitModRm_rr((RegisterID)src, dst);
- }
-
- void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_F2);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_CVTSI2SD_VsdEd);
- emitModRm_rr((RegisterID)dst, src);
- }
-
- void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_F2);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_CVTTSD2SI_GdWsd);
- emitModRm_rr(dst, (RegisterID)src);
- }
-
- void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_F2);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_ADDSD_VsdWsd);
- emitModRm_rm((RegisterID)dst, base, offset);
- }
-
- void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_F2);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_SUBSD_VsdWsd);
- emitModRm_rm((RegisterID)dst, base, offset);
- }
-
- void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_F2);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_MULSD_VsdWsd);
- emitModRm_rm((RegisterID)dst, base, offset);
- }
-
- void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_F2);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_ADDSD_VsdWsd);
- emitModRm_rr((RegisterID)dst, (RegisterID)src);
- }
-
- void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_F2);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_SUBSD_VsdWsd);
- emitModRm_rr((RegisterID)dst, (RegisterID)src);
- }
-
- void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_F2);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_MULSD_VsdWsd);
- emitModRm_rr((RegisterID)dst, (RegisterID)src);
- }
-
- void ucomis_rr(XMMRegisterID src, XMMRegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_66);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_UCOMISD_VsdWsd);
- emitModRm_rr((RegisterID)dst, (RegisterID)src);
- }
-
- void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
- {
- m_buffer->putByte(PRE_SSE_66);
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_PEXTRW_GdUdIb);
- emitModRm_rr(dst, (RegisterID)src);
- m_buffer->putByte(whichWord);
- }
-
- // Opaque label types
-
- class JmpSrc {
- friend class X86Assembler;
- public:
- JmpSrc()
- : m_offset(-1)
- {
- }
-
- private:
- JmpSrc(int offset)
- : m_offset(offset)
- {
- }
-
- int m_offset;
- };
-
- class JmpDst {
- friend class X86Assembler;
- public:
- JmpDst()
- : m_offset(-1)
- {
- }
-
- private:
- JmpDst(int offset)
- : m_offset(offset)
- {
- }
-
- int m_offset;
- };
-
- // FIXME: make this point to a global label, linked later.
- JmpSrc emitCall()
- {
- m_buffer->putByte(OP_CALL_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitCall(RegisterID dst)
- {
- m_buffer->putByte(OP_GROUP5_Ev);
- emitModRm_opr(GROUP5_OP_CALLN, dst);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpDst label()
- {
- return JmpDst(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJmp()
- {
- m_buffer->putByte(OP_JMP_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJne()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JNE_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJnz()
- {
- return emitUnlinkedJne();
- }
-
- JmpSrc emitUnlinkedJe()
- {
- m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
- m_buffer->putByteUnchecked(OP_2BYTE_ESCAPE);
- m_buffer->putByteUnchecked(OP2_JE_rel32);
- m_buffer->putIntUnchecked(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJl()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JL_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJb()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JB_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJle()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JLE_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJbe()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JBE_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJge()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JGE_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJg()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JG_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJa()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JA_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJae()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JAE_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJo()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JO_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJp()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JP_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- JmpSrc emitUnlinkedJs()
- {
- m_buffer->putByte(OP_2BYTE_ESCAPE);
- m_buffer->putByte(OP2_JS_rel32);
- m_buffer->putInt(0);
- return JmpSrc(m_buffer->getOffset());
- }
-
- void emitPredictionNotTaken()
- {
- m_buffer->putByte(PRE_PREDICT_BRANCH_NOT_TAKEN);
- }
-
- void link(JmpSrc from, JmpDst to)
- {
- ASSERT(to.m_offset != -1);
- ASSERT(from.m_offset != -1);
-
- reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_buffer->start()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
- }
-
- static void linkAbsoluteAddress(void* code, JmpDst useOffset, JmpDst address)
- {
- ASSERT(useOffset.m_offset != -1);
- ASSERT(address.m_offset != -1);
-
- reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + useOffset.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(code) + address.m_offset;
- }
-
- static void link(void* code, JmpSrc from, void* to)
- {
- ASSERT(from.m_offset != -1);
-
- reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
- }
-
- static void* getRelocatedAddress(void* code, JmpSrc jump)
- {
- return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
- }
-
- static void* getRelocatedAddress(void* code, JmpDst jump)
- {
- return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
- }
-
- static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
- {
- return dst.m_offset - src.m_offset;
- }
-
- static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
- {
- return dst.m_offset - src.m_offset;
- }
-
- static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)
- {
- return dst.m_offset - src.m_offset;
- }
-
- static void repatchImmediate(intptr_t where, int32_t value)
- {
- reinterpret_cast<int32_t*>(where)[-1] = value;
- }
-
- static void repatchDisplacement(intptr_t where, intptr_t value)
- {
- reinterpret_cast<intptr_t*>(where)[-1] = value;
- }
-
- static void repatchBranchOffset(intptr_t where, void* destination)
- {
- reinterpret_cast<intptr_t*>(where)[-1] = (reinterpret_cast<intptr_t>(destination) - where);
- }
-
- void* copy()
- {
- return m_buffer->copy();
- }
-
-#if COMPILER(MSVC)
- void emitConvertToFastCall()
- {
- movl_mr(4, X86::esp, X86::eax);
- movl_mr(8, X86::esp, X86::edx);
- movl_mr(12, X86::esp, X86::ecx);
- }
-#else
- void emitConvertToFastCall() {}
-#endif
-
-#if USE(CTI_ARGUMENT)
- void emitRestoreArgumentReference()
- {
-#if USE(FAST_CALL_CTI_ARGUMENT)
- movl_rr(X86::esp, X86::ecx);
-#else
- movl_rm(X86::esp, 0, X86::esp);
-#endif
- }
-
- void emitRestoreArgumentReferenceForTrampoline()
- {
-#if USE(FAST_CALL_CTI_ARGUMENT)
- movl_rr(X86::esp, X86::ecx);
- addl_i32r(4, X86::ecx);
-#endif
- }
-#else
- void emitRestoreArgumentReference() {}
- void emitRestoreArgumentReferenceForTrampoline() {}
-#endif
-
-private:
- void emitModRm_rr(RegisterID reg, RegisterID rm)
- {
- m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
- emitModRm_rr_Unchecked(reg, rm);
- }
-
- void emitModRm_rr_Unchecked(RegisterID reg, RegisterID rm)
- {
- m_buffer->putByteUnchecked(MODRM(3, reg, rm));
- }
-
- void emitModRm_rm(RegisterID reg, void* addr)
- {
- m_buffer->putByte(MODRM(0, reg, X86::noBase));
- m_buffer->putInt((int)addr);
- }
-
- void emitModRm_rm(RegisterID reg, RegisterID base)
- {
- if (base == X86::esp) {
- m_buffer->putByte(MODRM(0, reg, X86::hasSib));
- m_buffer->putByte(SIB(0, X86::noScale, X86::esp));
- } else
- m_buffer->putByte(MODRM(0, reg, base));
- }
-
- void emitModRm_rm_Unchecked(RegisterID reg, RegisterID base, int offset)
- {
- if (base == X86::esp) {
- if (CAN_SIGN_EXTEND_8_32(offset)) {
- m_buffer->putByteUnchecked(MODRM(1, reg, X86::hasSib));
- m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
- m_buffer->putByteUnchecked(offset);
- } else {
- m_buffer->putByteUnchecked(MODRM(2, reg, X86::hasSib));
- m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
- m_buffer->putIntUnchecked(offset);
- }
- } else {
- if (CAN_SIGN_EXTEND_8_32(offset)) {
- m_buffer->putByteUnchecked(MODRM(1, reg, base));
- m_buffer->putByteUnchecked(offset);
- } else {
- m_buffer->putByteUnchecked(MODRM(2, reg, base));
- m_buffer->putIntUnchecked(offset);
- }
- }
- }
-
- void emitModRm_rm(RegisterID reg, RegisterID base, int offset)
- {
- m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
- emitModRm_rm_Unchecked(reg, base, offset);
- }
-
- void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale)
- {
- int shift = 0;
- while (scale >>= 1)
- shift++;
-
- m_buffer->putByte(MODRM(0, reg, X86::hasSib));
- m_buffer->putByte(SIB(shift, index, base));
- }
-
- void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale, int offset)
- {
- int shift = 0;
- while (scale >>= 1)
- shift++;
-
- if (CAN_SIGN_EXTEND_8_32(offset)) {
- m_buffer->putByte(MODRM(1, reg, X86::hasSib));
- m_buffer->putByte(SIB(shift, index, base));
- m_buffer->putByte(offset);
- } else {
- m_buffer->putByte(MODRM(2, reg, X86::hasSib));
- m_buffer->putByte(SIB(shift, index, base));
- m_buffer->putInt(offset);
- }
- }
-
- void emitModRm_opr(OpcodeID opcode, RegisterID rm)
- {
- m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
- emitModRm_opr_Unchecked(opcode, rm);
- }
-
- void emitModRm_opr_Unchecked(OpcodeID opcode, RegisterID rm)
- {
- emitModRm_rr_Unchecked(static_cast<RegisterID>(opcode), rm);
- }
-
- void emitModRm_opm(OpcodeID opcode, RegisterID base)
- {
- emitModRm_rm(static_cast<RegisterID>(opcode), base);
- }
-
- void emitModRm_opm_Unchecked(OpcodeID opcode, RegisterID base, int offset)
- {
- emitModRm_rm_Unchecked(static_cast<RegisterID>(opcode), base, offset);
- }
-
- void emitModRm_opm(OpcodeID opcode, RegisterID base, int offset)
- {
- emitModRm_rm(static_cast<RegisterID>(opcode), base, offset);
- }
-
- void emitModRm_opm(OpcodeID opcode, void* addr)
- {
- emitModRm_rm(static_cast<RegisterID>(opcode), addr);
- }
-
- void emitModRm_opmsib(OpcodeID opcode, RegisterID base, RegisterID index, int scale, int offset)
- {
- emitModRm_rmsib(static_cast<RegisterID>(opcode), base, index, scale, offset);
- }
-
- JITCodeBuffer* m_buffer;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(MASM) && PLATFORM(X86)
-
-#endif // X86Assembler_h
diff --git a/JavaScriptCore/kjs/grammar.y b/JavaScriptCore/parser/Grammar.y
index 370798d..ae787f6 100644
--- a/JavaScriptCore/kjs/grammar.y
+++ b/JavaScriptCore/parser/Grammar.y
@@ -4,7 +4,7 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
*
* This library is free software; you can redistribute it and/or
@@ -29,8 +29,8 @@
#include <stdlib.h>
#include "JSValue.h"
#include "JSObject.h"
-#include "nodes.h"
-#include "lexer.h"
+#include "Nodes.h"
+#include "Lexer.h"
#include "JSString.h"
#include "JSGlobalData.h"
#include "CommonIdentifiers.h"
@@ -43,14 +43,14 @@
/* default values for bison */
#define YYDEBUG 0 // Set to 1 to debug a parse error.
-#define kjsyydebug 0 // Set to 1 to debug a parse error.
+#define jscyydebug 0 // Set to 1 to debug a parse error.
#if !PLATFORM(DARWIN)
// avoid triggering warnings in older bison
#define YYERROR_VERBOSE
#endif
-int kjsyylex(void* lvalp, void* llocp, void* globalPtr);
-int kjsyyerror(const char*);
+int jscyylex(void* lvalp, void* llocp, void* globalPtr);
+int jscyyerror(const char*);
static inline bool allowAutomaticSemicolon(JSC::Lexer&, int);
#define GLOBAL_DATA static_cast<JSGlobalData*>(globalPtr)
@@ -260,10 +260,9 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserRefCountedD
%type <statementNode> SwitchStatement LabelledStatement
%type <statementNode> ThrowStatement TryStatement
%type <statementNode> DebuggerStatement
-%type <statementNode> SourceElement
%type <expressionNode> Initializer InitializerNoIn
-%type <funcDeclNode> FunctionDeclaration
+%type <statementNode> FunctionDeclaration
%type <funcExprNode> FunctionExpr
%type <functionBodyNode> FunctionBody
%type <sourceElements> SourceElements
@@ -283,6 +282,10 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserRefCountedD
%type <propertyList> PropertyList
%%
+// FIXME: There are currently two versions of the grammar in this file, the normal one, and the NoNodes version used for
+// lazy recompilation of FunctionBodyNodes. We should move to generating the two versions from a script to avoid bugs.
+// In the mean time, make sure to make any changes to the grammar in both versions.
+
Literal:
NULLTOKEN { $$ = createNodeInfo<ExpressionNode*>(new NullNode(GLOBAL_DATA), 0, 1); }
| TRUETOKEN { $$ = createNodeInfo<ExpressionNode*>(new BooleanNode(GLOBAL_DATA, true), 0, 1); }
@@ -792,6 +795,7 @@ Statement:
Block
| VariableStatement
| ConstStatement
+ | FunctionDeclaration
| EmptyStatement
| ExprStatement
| IfStatement
@@ -1135,20 +1139,20 @@ ThrowStatement:
;
TryStatement:
- TRY Block FINALLY Block { $$ = createNodeDeclarationInfo<StatementNode*>(new TryNode(GLOBAL_DATA, $2.m_node, GLOBAL_DATA->propertyNames->nullIdentifier, 0, $4.m_node),
+ TRY Block FINALLY Block { $$ = createNodeDeclarationInfo<StatementNode*>(new TryNode(GLOBAL_DATA, $2.m_node, GLOBAL_DATA->propertyNames->nullIdentifier, false, 0, $4.m_node),
mergeDeclarationLists($2.m_varDeclarations, $4.m_varDeclarations),
mergeDeclarationLists($2.m_funcDeclarations, $4.m_funcDeclarations),
$2.m_features | $4.m_features,
$2.m_numConstants + $4.m_numConstants);
DBG($$.m_node, @1, @2); }
- | TRY Block CATCH '(' IDENT ')' Block { $$ = createNodeDeclarationInfo<StatementNode*>(new TryNode(GLOBAL_DATA, $2.m_node, *$5, $7.m_node, 0),
+ | TRY Block CATCH '(' IDENT ')' Block { $$ = createNodeDeclarationInfo<StatementNode*>(new TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, 0),
mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations),
mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations),
$2.m_features | $7.m_features | CatchFeature,
$2.m_numConstants + $7.m_numConstants);
DBG($$.m_node, @1, @2); }
| TRY Block CATCH '(' IDENT ')' Block FINALLY Block
- { $$ = createNodeDeclarationInfo<StatementNode*>(new TryNode(GLOBAL_DATA, $2.m_node, *$5, $7.m_node, $9.m_node),
+ { $$ = createNodeDeclarationInfo<StatementNode*>(new TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, $9.m_node),
mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations), $9.m_varDeclarations),
mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations), $9.m_funcDeclarations),
$2.m_features | $7.m_features | $9.m_features | CatchFeature,
@@ -1164,13 +1168,14 @@ DebuggerStatement:
;
FunctionDeclaration:
- FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new FuncDeclNode(GLOBAL_DATA, *$2, $6, LEXER->sourceCode($5, $7, @5.first_line)), ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); DBG($6, @5, @7); }
+ FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *$2, $6, LEXER->sourceCode($5, $7, @5.first_line)), 0, new ParserRefCountedData<DeclarationStacks::FunctionStack>(GLOBAL_DATA), ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); DBG($6, @5, @7); $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)); }
| FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
{
- $$ = createNodeInfo(new FuncDeclNode(GLOBAL_DATA, *$2, $7, LEXER->sourceCode($6, $8, @6.first_line), $4.m_node.head), ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features | ClosureFeature, 0);
+ $$ = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *$2, $7, LEXER->sourceCode($6, $8, @6.first_line), $4.m_node.head), 0, new ParserRefCountedData<DeclarationStacks::FunctionStack>(GLOBAL_DATA), ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features | ClosureFeature, 0);
if ($4.m_features & ArgumentsFeature)
$7->setUsesArguments();
- DBG($7, @6, @8);
+ DBG($7, @6, @8);
+ $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node));
}
;
@@ -1203,21 +1208,8 @@ FormalParameterList:
;
FunctionBody:
- /* not in spec */ { $$ = FunctionBodyNode::create(GLOBAL_DATA, 0, 0, 0, NoFeatures, 0); }
- | SourceElements { $$ = FunctionBodyNode::create(GLOBAL_DATA, $1.m_node, $1.m_varDeclarations ? &$1.m_varDeclarations->data : 0,
- $1.m_funcDeclarations ? &$1.m_funcDeclarations->data : 0,
- $1.m_features, $1.m_numConstants);
- // As in mergeDeclarationLists() we have to ref/deref to safely get rid of
- // the declaration lists.
- if ($1.m_varDeclarations) {
- $1.m_varDeclarations->ref();
- $1.m_varDeclarations->deref();
- }
- if ($1.m_funcDeclarations) {
- $1.m_funcDeclarations->ref();
- $1.m_funcDeclarations->deref();
- }
- }
+ /* not in spec */ { $$ = FunctionBodyNode::create(GLOBAL_DATA); }
+ | SourceElements_NoNode { $$ = FunctionBodyNode::create(GLOBAL_DATA); }
;
Program:
@@ -1227,26 +1219,610 @@ Program:
;
SourceElements:
- SourceElement { $$.m_node = new SourceElements(GLOBAL_DATA);
+ Statement { $$.m_node = new SourceElements(GLOBAL_DATA);
$$.m_node->append($1.m_node);
$$.m_varDeclarations = $1.m_varDeclarations;
$$.m_funcDeclarations = $1.m_funcDeclarations;
$$.m_features = $1.m_features;
$$.m_numConstants = $1.m_numConstants;
}
- | SourceElements SourceElement { $$.m_node->append($2.m_node);
+ | SourceElements Statement { $$.m_node->append($2.m_node);
$$.m_varDeclarations = mergeDeclarationLists($1.m_varDeclarations, $2.m_varDeclarations);
$$.m_funcDeclarations = mergeDeclarationLists($1.m_funcDeclarations, $2.m_funcDeclarations);
$$.m_features = $1.m_features | $2.m_features;
$$.m_numConstants = $1.m_numConstants + $2.m_numConstants;
}
;
+
+// Start NoNodes
-SourceElement:
- FunctionDeclaration { $$ = createNodeDeclarationInfo<StatementNode*>($1.m_node, 0, new ParserRefCountedData<DeclarationStacks::FunctionStack>(GLOBAL_DATA), $1.m_features, 0); $$.m_funcDeclarations->data.append($1.m_node); }
- | Statement { $$ = $1; }
+Literal_NoNode:
+ NULLTOKEN
+ | TRUETOKEN
+ | FALSETOKEN
+ | NUMBER { }
+ | STRING { }
+ | '/' /* regexp */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; }
+ | DIVEQUAL /* regexp with /= */ { Lexer& l = *LEXER; if (!l.scanRegExp()) YYABORT; }
;
-
+
+Property_NoNode:
+ IDENT ':' AssignmentExpr_NoNode { }
+ | STRING ':' AssignmentExpr_NoNode { }
+ | NUMBER ':' AssignmentExpr_NoNode { }
+ | IDENT IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; }
+ | IDENT IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE { if (*$1 != "get" && *$1 != "set") YYABORT; }
+;
+
+PropertyList_NoNode:
+ Property_NoNode
+ | PropertyList_NoNode ',' Property_NoNode
+;
+
+PrimaryExpr_NoNode:
+ PrimaryExprNoBrace_NoNode
+ | OPENBRACE CLOSEBRACE { }
+ | OPENBRACE PropertyList_NoNode CLOSEBRACE { }
+ /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */
+ | OPENBRACE PropertyList_NoNode ',' CLOSEBRACE { }
+;
+
+PrimaryExprNoBrace_NoNode:
+ THISTOKEN
+ | Literal_NoNode
+ | ArrayLiteral_NoNode
+ | IDENT { }
+ | '(' Expr_NoNode ')'
+;
+
+ArrayLiteral_NoNode:
+ '[' ElisionOpt_NoNode ']'
+ | '[' ElementList_NoNode ']'
+ | '[' ElementList_NoNode ',' ElisionOpt_NoNode ']'
+;
+
+ElementList_NoNode:
+ ElisionOpt_NoNode AssignmentExpr_NoNode
+ | ElementList_NoNode ',' ElisionOpt_NoNode AssignmentExpr_NoNode
+;
+
+ElisionOpt_NoNode:
+ /* nothing */
+ | Elision_NoNode
+;
+
+Elision_NoNode:
+ ','
+ | Elision_NoNode ','
+;
+
+MemberExpr_NoNode:
+ PrimaryExpr_NoNode
+ | FunctionExpr_NoNode
+ | MemberExpr_NoNode '[' Expr_NoNode ']'
+ | MemberExpr_NoNode '.' IDENT
+ | NEW MemberExpr_NoNode Arguments_NoNode
+;
+
+MemberExprNoBF_NoNode:
+ PrimaryExprNoBrace_NoNode
+ | MemberExprNoBF_NoNode '[' Expr_NoNode ']'
+ | MemberExprNoBF_NoNode '.' IDENT
+ | NEW MemberExpr_NoNode Arguments_NoNode
+;
+
+NewExpr_NoNode:
+ MemberExpr_NoNode
+ | NEW NewExpr_NoNode
+;
+
+NewExprNoBF_NoNode:
+ MemberExprNoBF_NoNode
+ | NEW NewExpr_NoNode
+;
+
+CallExpr_NoNode:
+ MemberExpr_NoNode Arguments_NoNode
+ | CallExpr_NoNode Arguments_NoNode
+ | CallExpr_NoNode '[' Expr_NoNode ']'
+ | CallExpr_NoNode '.' IDENT
+;
+
+CallExprNoBF_NoNode:
+ MemberExprNoBF_NoNode Arguments_NoNode
+ | CallExprNoBF_NoNode Arguments_NoNode
+ | CallExprNoBF_NoNode '[' Expr_NoNode ']'
+ | CallExprNoBF_NoNode '.' IDENT
+;
+
+Arguments_NoNode:
+ '(' ')'
+ | '(' ArgumentList_NoNode ')'
+;
+
+ArgumentList_NoNode:
+ AssignmentExpr_NoNode
+ | ArgumentList_NoNode ',' AssignmentExpr_NoNode
+;
+
+LeftHandSideExpr_NoNode:
+ NewExpr_NoNode
+ | CallExpr_NoNode
+;
+
+LeftHandSideExprNoBF_NoNode:
+ NewExprNoBF_NoNode
+ | CallExprNoBF_NoNode
+;
+
+PostfixExpr_NoNode:
+ LeftHandSideExpr_NoNode
+ | LeftHandSideExpr_NoNode PLUSPLUS
+ | LeftHandSideExpr_NoNode MINUSMINUS
+;
+
+PostfixExprNoBF_NoNode:
+ LeftHandSideExprNoBF_NoNode
+ | LeftHandSideExprNoBF_NoNode PLUSPLUS
+ | LeftHandSideExprNoBF_NoNode MINUSMINUS
+;
+
+UnaryExprCommon_NoNode:
+ DELETETOKEN UnaryExpr_NoNode
+ | VOIDTOKEN UnaryExpr_NoNode
+ | TYPEOF UnaryExpr_NoNode
+ | PLUSPLUS UnaryExpr_NoNode
+ | AUTOPLUSPLUS UnaryExpr_NoNode
+ | MINUSMINUS UnaryExpr_NoNode
+ | AUTOMINUSMINUS UnaryExpr_NoNode
+ | '+' UnaryExpr_NoNode
+ | '-' UnaryExpr_NoNode
+ | '~' UnaryExpr_NoNode
+ | '!' UnaryExpr_NoNode
+
+UnaryExpr_NoNode:
+ PostfixExpr_NoNode
+ | UnaryExprCommon_NoNode
+;
+
+UnaryExprNoBF_NoNode:
+ PostfixExprNoBF_NoNode
+ | UnaryExprCommon_NoNode
+;
+
+MultiplicativeExpr_NoNode:
+ UnaryExpr_NoNode
+ | MultiplicativeExpr_NoNode '*' UnaryExpr_NoNode
+ | MultiplicativeExpr_NoNode '/' UnaryExpr_NoNode
+ | MultiplicativeExpr_NoNode '%' UnaryExpr_NoNode
+;
+
+MultiplicativeExprNoBF_NoNode:
+ UnaryExprNoBF_NoNode
+ | MultiplicativeExprNoBF_NoNode '*' UnaryExpr_NoNode
+ | MultiplicativeExprNoBF_NoNode '/' UnaryExpr_NoNode
+ | MultiplicativeExprNoBF_NoNode '%' UnaryExpr_NoNode
+;
+
+AdditiveExpr_NoNode:
+ MultiplicativeExpr_NoNode
+ | AdditiveExpr_NoNode '+' MultiplicativeExpr_NoNode
+ | AdditiveExpr_NoNode '-' MultiplicativeExpr_NoNode
+;
+
+AdditiveExprNoBF_NoNode:
+ MultiplicativeExprNoBF_NoNode
+ | AdditiveExprNoBF_NoNode '+' MultiplicativeExpr_NoNode
+ | AdditiveExprNoBF_NoNode '-' MultiplicativeExpr_NoNode
+;
+
+ShiftExpr_NoNode:
+ AdditiveExpr_NoNode
+ | ShiftExpr_NoNode LSHIFT AdditiveExpr_NoNode
+ | ShiftExpr_NoNode RSHIFT AdditiveExpr_NoNode
+ | ShiftExpr_NoNode URSHIFT AdditiveExpr_NoNode
+;
+
+ShiftExprNoBF_NoNode:
+ AdditiveExprNoBF_NoNode
+ | ShiftExprNoBF_NoNode LSHIFT AdditiveExpr_NoNode
+ | ShiftExprNoBF_NoNode RSHIFT AdditiveExpr_NoNode
+ | ShiftExprNoBF_NoNode URSHIFT AdditiveExpr_NoNode
+;
+
+RelationalExpr_NoNode:
+ ShiftExpr_NoNode
+ | RelationalExpr_NoNode '<' ShiftExpr_NoNode
+ | RelationalExpr_NoNode '>' ShiftExpr_NoNode
+ | RelationalExpr_NoNode LE ShiftExpr_NoNode
+ | RelationalExpr_NoNode GE ShiftExpr_NoNode
+ | RelationalExpr_NoNode INSTANCEOF ShiftExpr_NoNode
+ | RelationalExpr_NoNode INTOKEN ShiftExpr_NoNode
+;
+
+RelationalExprNoIn_NoNode:
+ ShiftExpr_NoNode
+ | RelationalExprNoIn_NoNode '<' ShiftExpr_NoNode
+ | RelationalExprNoIn_NoNode '>' ShiftExpr_NoNode
+ | RelationalExprNoIn_NoNode LE ShiftExpr_NoNode
+ | RelationalExprNoIn_NoNode GE ShiftExpr_NoNode
+ | RelationalExprNoIn_NoNode INSTANCEOF ShiftExpr_NoNode
+;
+
+RelationalExprNoBF_NoNode:
+ ShiftExprNoBF_NoNode
+ | RelationalExprNoBF_NoNode '<' ShiftExpr_NoNode
+ | RelationalExprNoBF_NoNode '>' ShiftExpr_NoNode
+ | RelationalExprNoBF_NoNode LE ShiftExpr_NoNode
+ | RelationalExprNoBF_NoNode GE ShiftExpr_NoNode
+ | RelationalExprNoBF_NoNode INSTANCEOF ShiftExpr_NoNode
+ | RelationalExprNoBF_NoNode INTOKEN ShiftExpr_NoNode
+;
+
+EqualityExpr_NoNode:
+ RelationalExpr_NoNode
+ | EqualityExpr_NoNode EQEQ RelationalExpr_NoNode
+ | EqualityExpr_NoNode NE RelationalExpr_NoNode
+ | EqualityExpr_NoNode STREQ RelationalExpr_NoNode
+ | EqualityExpr_NoNode STRNEQ RelationalExpr_NoNode
+;
+
+EqualityExprNoIn_NoNode:
+ RelationalExprNoIn_NoNode
+ | EqualityExprNoIn_NoNode EQEQ RelationalExprNoIn_NoNode
+ | EqualityExprNoIn_NoNode NE RelationalExprNoIn_NoNode
+ | EqualityExprNoIn_NoNode STREQ RelationalExprNoIn_NoNode
+ | EqualityExprNoIn_NoNode STRNEQ RelationalExprNoIn_NoNode
+;
+
+EqualityExprNoBF_NoNode:
+ RelationalExprNoBF_NoNode
+ | EqualityExprNoBF_NoNode EQEQ RelationalExpr_NoNode
+ | EqualityExprNoBF_NoNode NE RelationalExpr_NoNode
+ | EqualityExprNoBF_NoNode STREQ RelationalExpr_NoNode
+ | EqualityExprNoBF_NoNode STRNEQ RelationalExpr_NoNode
+;
+
+BitwiseANDExpr_NoNode:
+ EqualityExpr_NoNode
+ | BitwiseANDExpr_NoNode '&' EqualityExpr_NoNode
+;
+
+BitwiseANDExprNoIn_NoNode:
+ EqualityExprNoIn_NoNode
+ | BitwiseANDExprNoIn_NoNode '&' EqualityExprNoIn_NoNode
+;
+
+BitwiseANDExprNoBF_NoNode:
+ EqualityExprNoBF_NoNode
+ | BitwiseANDExprNoBF_NoNode '&' EqualityExpr_NoNode
+;
+
+BitwiseXORExpr_NoNode:
+ BitwiseANDExpr_NoNode
+ | BitwiseXORExpr_NoNode '^' BitwiseANDExpr_NoNode
+;
+
+BitwiseXORExprNoIn_NoNode:
+ BitwiseANDExprNoIn_NoNode
+ | BitwiseXORExprNoIn_NoNode '^' BitwiseANDExprNoIn_NoNode
+;
+
+BitwiseXORExprNoBF_NoNode:
+ BitwiseANDExprNoBF_NoNode
+ | BitwiseXORExprNoBF_NoNode '^' BitwiseANDExpr_NoNode
+;
+
+BitwiseORExpr_NoNode:
+ BitwiseXORExpr_NoNode
+ | BitwiseORExpr_NoNode '|' BitwiseXORExpr_NoNode
+;
+
+BitwiseORExprNoIn_NoNode:
+ BitwiseXORExprNoIn_NoNode
+ | BitwiseORExprNoIn_NoNode '|' BitwiseXORExprNoIn_NoNode
+;
+
+BitwiseORExprNoBF_NoNode:
+ BitwiseXORExprNoBF_NoNode
+ | BitwiseORExprNoBF_NoNode '|' BitwiseXORExpr_NoNode
+;
+
+LogicalANDExpr_NoNode:
+ BitwiseORExpr_NoNode
+ | LogicalANDExpr_NoNode AND BitwiseORExpr_NoNode
+;
+
+LogicalANDExprNoIn_NoNode:
+ BitwiseORExprNoIn_NoNode
+ | LogicalANDExprNoIn_NoNode AND BitwiseORExprNoIn_NoNode
+;
+
+LogicalANDExprNoBF_NoNode:
+ BitwiseORExprNoBF_NoNode
+ | LogicalANDExprNoBF_NoNode AND BitwiseORExpr_NoNode
+;
+
+LogicalORExpr_NoNode:
+ LogicalANDExpr_NoNode
+ | LogicalORExpr_NoNode OR LogicalANDExpr_NoNode
+;
+
+LogicalORExprNoIn_NoNode:
+ LogicalANDExprNoIn_NoNode
+ | LogicalORExprNoIn_NoNode OR LogicalANDExprNoIn_NoNode
+;
+
+LogicalORExprNoBF_NoNode:
+ LogicalANDExprNoBF_NoNode
+ | LogicalORExprNoBF_NoNode OR LogicalANDExpr_NoNode
+;
+
+ConditionalExpr_NoNode:
+ LogicalORExpr_NoNode
+ | LogicalORExpr_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode
+;
+
+ConditionalExprNoIn_NoNode:
+ LogicalORExprNoIn_NoNode
+ | LogicalORExprNoIn_NoNode '?' AssignmentExprNoIn_NoNode ':' AssignmentExprNoIn_NoNode
+;
+
+ConditionalExprNoBF_NoNode:
+ LogicalORExprNoBF_NoNode
+ | LogicalORExprNoBF_NoNode '?' AssignmentExpr_NoNode ':' AssignmentExpr_NoNode
+;
+
+AssignmentExpr_NoNode:
+ ConditionalExpr_NoNode
+ | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode
+;
+
+AssignmentExprNoIn_NoNode:
+ ConditionalExprNoIn_NoNode
+ | LeftHandSideExpr_NoNode AssignmentOperator_NoNode AssignmentExprNoIn_NoNode
+;
+
+AssignmentExprNoBF_NoNode:
+ ConditionalExprNoBF_NoNode
+ | LeftHandSideExprNoBF_NoNode AssignmentOperator_NoNode AssignmentExpr_NoNode
+;
+
+AssignmentOperator_NoNode:
+ '='
+ | PLUSEQUAL
+ | MINUSEQUAL
+ | MULTEQUAL
+ | DIVEQUAL
+ | LSHIFTEQUAL
+ | RSHIFTEQUAL
+ | URSHIFTEQUAL
+ | ANDEQUAL
+ | XOREQUAL
+ | OREQUAL
+ | MODEQUAL
+;
+
+Expr_NoNode:
+ AssignmentExpr_NoNode
+ | Expr_NoNode ',' AssignmentExpr_NoNode
+;
+
+ExprNoIn_NoNode:
+ AssignmentExprNoIn_NoNode
+ | ExprNoIn_NoNode ',' AssignmentExprNoIn_NoNode
+;
+
+ExprNoBF_NoNode:
+ AssignmentExprNoBF_NoNode
+ | ExprNoBF_NoNode ',' AssignmentExpr_NoNode
+;
+
+Statement_NoNode:
+ Block_NoNode
+ | VariableStatement_NoNode
+ | ConstStatement_NoNode
+ | FunctionDeclaration_NoNode
+ | EmptyStatement_NoNode
+ | ExprStatement_NoNode
+ | IfStatement_NoNode
+ | IterationStatement_NoNode
+ | ContinueStatement_NoNode
+ | BreakStatement_NoNode
+ | ReturnStatement_NoNode
+ | WithStatement_NoNode
+ | SwitchStatement_NoNode
+ | LabelledStatement_NoNode
+ | ThrowStatement_NoNode
+ | TryStatement_NoNode
+ | DebuggerStatement_NoNode
+;
+
+Block_NoNode:
+ OPENBRACE CLOSEBRACE { }
+ | OPENBRACE SourceElements_NoNode CLOSEBRACE { }
+;
+
+VariableStatement_NoNode:
+ VAR VariableDeclarationList_NoNode ';'
+ | VAR VariableDeclarationList_NoNode error { AUTO_SEMICOLON; }
+;
+
+VariableDeclarationList_NoNode:
+ IDENT { }
+ | IDENT Initializer_NoNode { }
+ | VariableDeclarationList_NoNode ',' IDENT
+ | VariableDeclarationList_NoNode ',' IDENT Initializer_NoNode
+;
+
+VariableDeclarationListNoIn_NoNode:
+ IDENT { }
+ | IDENT InitializerNoIn_NoNode { }
+ | VariableDeclarationListNoIn_NoNode ',' IDENT
+ | VariableDeclarationListNoIn_NoNode ',' IDENT InitializerNoIn_NoNode
+;
+
+ConstStatement_NoNode:
+ CONSTTOKEN ConstDeclarationList_NoNode ';'
+ | CONSTTOKEN ConstDeclarationList_NoNode error { AUTO_SEMICOLON; }
+;
+
+ConstDeclarationList_NoNode:
+ ConstDeclaration_NoNode
+ | ConstDeclarationList_NoNode ',' ConstDeclaration_NoNode
+;
+
+ConstDeclaration_NoNode:
+ IDENT { }
+ | IDENT Initializer_NoNode { }
+;
+
+Initializer_NoNode:
+ '=' AssignmentExpr_NoNode
+;
+
+InitializerNoIn_NoNode:
+ '=' AssignmentExprNoIn_NoNode
+;
+
+EmptyStatement_NoNode:
+ ';'
+;
+
+ExprStatement_NoNode:
+ ExprNoBF_NoNode ';'
+ | ExprNoBF_NoNode error { AUTO_SEMICOLON; }
+;
+
+IfStatement_NoNode:
+ IF '(' Expr_NoNode ')' Statement_NoNode %prec IF_WITHOUT_ELSE
+ | IF '(' Expr_NoNode ')' Statement_NoNode ELSE Statement_NoNode
+;
+
+IterationStatement_NoNode:
+ DO Statement_NoNode WHILE '(' Expr_NoNode ')' ';'
+ | DO Statement_NoNode WHILE '(' Expr_NoNode ')' error // Always performs automatic semicolon insertion
+ | WHILE '(' Expr_NoNode ')' Statement_NoNode
+ | FOR '(' ExprNoInOpt_NoNode ';' ExprOpt_NoNode ';' ExprOpt_NoNode ')' Statement_NoNode
+ | FOR '(' VAR VariableDeclarationListNoIn_NoNode ';' ExprOpt_NoNode ';' ExprOpt_NoNode ')' Statement_NoNode
+ | FOR '(' LeftHandSideExpr_NoNode INTOKEN Expr_NoNode ')' Statement_NoNode
+ | FOR '(' VAR IDENT INTOKEN Expr_NoNode ')' Statement_NoNode
+ | FOR '(' VAR IDENT InitializerNoIn_NoNode INTOKEN Expr_NoNode ')' Statement_NoNode
+;
+
+ExprOpt_NoNode:
+ /* nothing */
+ | Expr_NoNode
+;
+
+ExprNoInOpt_NoNode:
+ /* nothing */
+ | ExprNoIn_NoNode
+;
+
+ContinueStatement_NoNode:
+ CONTINUE ';'
+ | CONTINUE error { AUTO_SEMICOLON; }
+ | CONTINUE IDENT ';'
+ | CONTINUE IDENT error { AUTO_SEMICOLON; }
+;
+
+BreakStatement_NoNode:
+ BREAK ';'
+ | BREAK error { AUTO_SEMICOLON; }
+ | BREAK IDENT ';'
+ | BREAK IDENT error { AUTO_SEMICOLON; }
+;
+
+ReturnStatement_NoNode:
+ RETURN ';'
+ | RETURN error { AUTO_SEMICOLON; }
+ | RETURN Expr_NoNode ';'
+ | RETURN Expr_NoNode error { AUTO_SEMICOLON; }
+;
+
+WithStatement_NoNode:
+ WITH '(' Expr_NoNode ')' Statement_NoNode
+;
+
+SwitchStatement_NoNode:
+ SWITCH '(' Expr_NoNode ')' CaseBlock_NoNode
+;
+
+CaseBlock_NoNode:
+ OPENBRACE CaseClausesOpt_NoNode CLOSEBRACE { }
+ | OPENBRACE CaseClausesOpt_NoNode DefaultClause_NoNode CaseClausesOpt_NoNode CLOSEBRACE { }
+;
+
+CaseClausesOpt_NoNode:
+ /* nothing */
+ | CaseClauses_NoNode
+;
+
+CaseClauses_NoNode:
+ CaseClause_NoNode
+ | CaseClauses_NoNode CaseClause_NoNode
+;
+
+CaseClause_NoNode:
+ CASE Expr_NoNode ':'
+ | CASE Expr_NoNode ':' SourceElements_NoNode
+;
+
+DefaultClause_NoNode:
+ DEFAULT ':'
+ | DEFAULT ':' SourceElements_NoNode
+;
+
+LabelledStatement_NoNode:
+ IDENT ':' Statement_NoNode { }
+;
+
+ThrowStatement_NoNode:
+ THROW Expr_NoNode ';'
+ | THROW Expr_NoNode error { AUTO_SEMICOLON; }
+;
+
+TryStatement_NoNode:
+ TRY Block_NoNode FINALLY Block_NoNode
+ | TRY Block_NoNode CATCH '(' IDENT ')' Block_NoNode
+ | TRY Block_NoNode CATCH '(' IDENT ')' Block_NoNode FINALLY Block_NoNode
+;
+
+DebuggerStatement_NoNode:
+ DEBUGGER ';'
+ | DEBUGGER error { AUTO_SEMICOLON; }
+;
+
+FunctionDeclaration_NoNode:
+ FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+ | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+;
+
+FunctionExpr_NoNode:
+ FUNCTION '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+ | FUNCTION '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+ | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+ | FUNCTION IDENT '(' FormalParameterList_NoNode ')' OPENBRACE FunctionBody_NoNode CLOSEBRACE
+;
+
+FormalParameterList_NoNode:
+ IDENT { }
+ | FormalParameterList_NoNode ',' IDENT
+;
+
+FunctionBody_NoNode:
+ /* not in spec */
+ | SourceElements_NoNode
+;
+
+SourceElements_NoNode:
+ Statement_NoNode
+ | SourceElements_NoNode Statement_NoNode
+;
+
+// End NoNodes
+
%%
static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end)
@@ -1408,9 +1984,6 @@ static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n)
static NumberNode* makeNumberNode(void* globalPtr, double d)
{
- JSValue* value = JSImmediate::from(d);
- if (value)
- return new ImmediateNumberNode(GLOBAL_DATA, value, d);
return new NumberNode(GLOBAL_DATA, d);
}
diff --git a/JavaScriptCore/kjs/keywords.table b/JavaScriptCore/parser/Keywords.table
index 490c1cc..490c1cc 100644
--- a/JavaScriptCore/kjs/keywords.table
+++ b/JavaScriptCore/parser/Keywords.table
diff --git a/JavaScriptCore/kjs/lexer.cpp b/JavaScriptCore/parser/Lexer.cpp
index 7313b12..22de4a0 100644
--- a/JavaScriptCore/kjs/lexer.cpp
+++ b/JavaScriptCore/parser/Lexer.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All Rights Reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
*
* This library is free software; you can redistribute it and/or
@@ -21,16 +21,17 @@
*/
#include "config.h"
-#include "lexer.h"
+#include "Lexer.h"
-#include "dtoa.h"
#include "JSFunction.h"
-#include "nodes.h"
-#include "NodeInfo.h"
#include "JSGlobalObjectFunctions.h"
+#include "NodeInfo.h"
+#include "Nodes.h"
+#include "dtoa.h"
#include <ctype.h>
#include <limits.h>
#include <string.h>
+#include <wtf/ASCIICType.h>
#include <wtf/Assertions.h>
#include <wtf/unicode/Unicode.h>
@@ -41,14 +42,14 @@ using namespace Unicode;
using namespace JSC;
#ifndef KDE_USE_FINAL
-#include "grammar.h"
+#include "Grammar.h"
#endif
-#include "lookup.h"
-#include "lexer.lut.h"
+#include "Lookup.h"
+#include "Lexer.lut.h"
// a bridge for yacc from the C world to C++
-int kjsyylex(void* lvalp, void* llocp, void* globalData)
+int jscyylex(void* lvalp, void* llocp, void* globalData)
{
return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp);
}
@@ -57,9 +58,6 @@ namespace JSC {
static bool isDecimalDigit(int);
-static const size_t initialReadBufferCapacity = 32;
-static const size_t initialStringTableCapacity = 64;
-
Lexer::Lexer(JSGlobalData* globalData)
: yylineno(1)
, m_restrKeyword(false)
@@ -69,6 +67,7 @@ Lexer::Lexer(JSGlobalData* globalData)
, m_position(0)
, m_code(0)
, m_length(0)
+ , m_isReparsing(false)
, m_atLineStart(true)
, m_current(0)
, m_next1(0)
@@ -83,8 +82,6 @@ Lexer::Lexer(JSGlobalData* globalData)
{
m_buffer8.reserveCapacity(initialReadBufferCapacity);
m_buffer16.reserveCapacity(initialReadBufferCapacity);
- m_strings.reserveCapacity(initialStringTableCapacity);
- m_identifiers.reserveCapacity(initialStringTableCapacity);
}
Lexer::~Lexer()
@@ -101,10 +98,10 @@ void Lexer::setCode(const SourceCode& source)
m_stackToken = -1;
m_lastToken = -1;
- m_position = 0;
+ m_position = source.startOffset();
m_source = &source;
- m_code = source.data();
- m_length = source.length();
+ m_code = source.provider()->data();
+ m_length = source.endOffset();
m_skipLF = false;
m_skipCR = false;
m_error = false;
@@ -196,7 +193,7 @@ int Lexer::lex(void* p1, void* p2)
shift(1);
m_state = InMultiLineComment;
} else if (m_current == -1) {
- if (!m_terminator && !m_delimited) {
+ if (!m_terminator && !m_delimited && !m_isReparsing) {
// automatic semicolon insertion if program incomplete
token = ';';
m_stackToken = 0;
@@ -469,7 +466,7 @@ int Lexer::lex(void* p1, void* p2)
// terminate string
m_buffer8.append('\0');
-#ifdef KJS_DEBUG_LEX
+#ifdef JSC_DEBUG_LEX
fprintf(stderr, "line: %d ", lineNo());
fprintf(stderr, "yytext (%x): ", m_buffer8[0]);
fprintf(stderr, "%s ", m_buffer8.data());
@@ -477,7 +474,7 @@ int Lexer::lex(void* p1, void* p2)
double dval = 0;
if (m_state == Number)
- dval = strtod(m_buffer8.data(), 0L);
+ dval = WTF::strtod(m_buffer8.data(), 0L);
else if (m_state == Hex) { // scan hex numbers
const char* p = m_buffer8.data() + 2;
while (char c = *p++) {
@@ -502,7 +499,7 @@ int Lexer::lex(void* p1, void* p2)
m_state = Number;
}
-#ifdef KJS_DEBUG_LEX
+#ifdef JSC_DEBUG_LEX
switch (m_state) {
case Eof:
printf("(EOF)\n");
@@ -576,7 +573,7 @@ int Lexer::lex(void* p1, void* p2)
token = NUMBER;
break;
case Bad:
-#ifdef KJS_DEBUG_LEX
+#ifdef JSC_DEBUG_LEX
fprintf(stderr, "yylex: ERROR.\n");
#endif
m_error = true;
@@ -608,32 +605,28 @@ bool Lexer::isLineTerminator()
bool Lexer::isIdentStart(int c)
{
- return (category(c) & (Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other))
- || c == '$' || c == '_';
+ return isASCIIAlpha(c) || c == '$' || c == '_' || (!isASCII(c) && (category(c) & (Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other)));
}
bool Lexer::isIdentPart(int c)
{
- return (category(c) & (Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other
- | Mark_NonSpacing | Mark_SpacingCombining | Number_DecimalDigit | Punctuation_Connector))
- || c == '$' || c == '_';
+ return isASCIIAlphanumeric(c) || c == '$' || c == '_' || (!isASCII(c) && (category(c) & (Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other
+ | Mark_NonSpacing | Mark_SpacingCombining | Number_DecimalDigit | Punctuation_Connector)));
}
static bool isDecimalDigit(int c)
{
- return (c >= '0' && c <= '9');
+ return isASCIIDigit(c);
}
bool Lexer::isHexDigit(int c)
{
- return (c >= '0' && c <= '9'
- || c >= 'a' && c <= 'f'
- || c >= 'A' && c <= 'F');
+ return isASCIIHexDigit(c);
}
bool Lexer::isOctalDigit(int c)
{
- return (c >= '0' && c <= '7');
+ return isASCIIOctalDigit(c);
}
int Lexer::matchPunctuator(int& charPos, int c1, int c2, int c3, int c4)
@@ -765,11 +758,11 @@ int Lexer::matchPunctuator(int& charPos, int c1, int c2, int c3, int c4)
shift(1);
return static_cast<int>(c1);
case '{':
- charPos = m_position - 4;
+ charPos = m_currentOffset;
shift(1);
return OPENBRACE;
case '}':
- charPos = m_position - 4;
+ charPos = m_currentOffset;
shift(1);
return CLOSEBRACE;
default:
@@ -888,15 +881,7 @@ bool Lexer::scanRegExp()
void Lexer::clear()
{
- deleteAllValues(m_strings);
- Vector<UString*> newStrings;
- newStrings.reserveCapacity(initialStringTableCapacity);
- m_strings.swap(newStrings);
-
- deleteAllValues(m_identifiers);
- Vector<JSC::Identifier*> newIdentifiers;
- newIdentifiers.reserveCapacity(initialStringTableCapacity);
- m_identifiers.swap(newIdentifiers);
+ m_identifiers.clear();
Vector<char> newBuffer8;
newBuffer8.reserveCapacity(initialReadBufferCapacity);
@@ -906,15 +891,10 @@ void Lexer::clear()
newBuffer16.reserveCapacity(initialReadBufferCapacity);
m_buffer16.swap(newBuffer16);
+ m_isReparsing = false;
+
m_pattern = 0;
m_flags = 0;
}
-Identifier* Lexer::makeIdentifier(const Vector<UChar>& buffer)
-{
- JSC::Identifier* identifier = new JSC::Identifier(m_globalData, buffer.data(), buffer.size());
- m_identifiers.append(identifier);
- return identifier;
-}
-
} // namespace JSC
diff --git a/JavaScriptCore/kjs/lexer.h b/JavaScriptCore/parser/Lexer.h
index 16bc4b6..63d3892 100644
--- a/JavaScriptCore/kjs/lexer.h
+++ b/JavaScriptCore/parser/Lexer.h
@@ -1,7 +1,6 @@
/*
- * This file is part of the KDE libraries
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2007 Apple Inc.
+ * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,19 +22,20 @@
#ifndef Lexer_h
#define Lexer_h
-#include "lookup.h"
-#include "ustring.h"
-#include <wtf/Vector.h>
+#include "Identifier.h"
+#include "Lookup.h"
+#include "SegmentedVector.h"
#include "SourceCode.h"
+#include <wtf/Vector.h>
namespace JSC {
- class Identifier;
class RegExp;
class Lexer : Noncopyable {
public:
void setCode(const SourceCode&);
+ void setIsReparsing() { m_isReparsing = true; }
int lex(void* lvalp, void* llocp);
int lineNo() const { return yylineno; }
@@ -88,7 +88,7 @@ namespace JSC {
bool sawError() const { return m_error; }
void clear();
- SourceCode sourceCode(int openBrace, int closeBrace, int firstLine) { return SourceCode(m_source->provider(), m_source->startOffset() + openBrace + 1, m_source->startOffset() + closeBrace, firstLine); }
+ SourceCode sourceCode(int openBrace, int closeBrace, int firstLine) { return SourceCode(m_source->provider(), openBrace, closeBrace + 1, firstLine); }
private:
friend class JSGlobalData;
@@ -104,7 +104,7 @@ namespace JSC {
bool isLineTerminator();
static bool isOctalDigit(int);
- int matchPunctuator(int& charPos, int c1, int c2, int c3, int c4);
+ ALWAYS_INLINE int matchPunctuator(int& charPos, int c1, int c2, int c3, int c4);
static unsigned short singleEscape(unsigned short);
static unsigned short convertOctal(int c1, int c2, int c3);
@@ -112,7 +112,14 @@ namespace JSC {
void record16(int);
void record16(UChar);
- JSC::Identifier* makeIdentifier(const Vector<UChar>& buffer);
+ JSC::Identifier* makeIdentifier(const Vector<UChar>& buffer)
+ {
+ m_identifiers.append(JSC::Identifier(m_globalData, buffer.data(), buffer.size()));
+ return &m_identifiers.last();
+ }
+
+ static const size_t initialReadBufferCapacity = 32;
+ static const size_t initialIdentifierTableCapacity = 64;
int yylineno;
int yycolumn;
@@ -134,6 +141,7 @@ namespace JSC {
const SourceCode* m_source;
const UChar* m_code;
unsigned int m_length;
+ bool m_isReparsing;
int m_atLineStart;
bool m_error;
@@ -148,8 +156,7 @@ namespace JSC {
int m_nextOffset2;
int m_nextOffset3;
- Vector<UString*> m_strings;
- Vector<JSC::Identifier*> m_identifiers;
+ SegmentedVector<JSC::Identifier, initialIdentifierTableCapacity> m_identifiers;
JSGlobalData* m_globalData;
diff --git a/JavaScriptCore/kjs/NodeInfo.h b/JavaScriptCore/parser/NodeInfo.h
index 2d11dc2..a518b23 100644
--- a/JavaScriptCore/kjs/NodeInfo.h
+++ b/JavaScriptCore/parser/NodeInfo.h
@@ -20,7 +20,7 @@
#ifndef NodeInfo_h
#define NodeInfo_h
-#include "nodes.h"
+#include "Nodes.h"
#include "Parser.h"
namespace JSC {
diff --git a/JavaScriptCore/kjs/nodes.cpp b/JavaScriptCore/parser/Nodes.cpp
index b4aeb28..96fe50b 100644
--- a/JavaScriptCore/kjs/nodes.cpp
+++ b/JavaScriptCore/parser/Nodes.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
-* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -24,10 +24,10 @@
*/
#include "config.h"
-#include "nodes.h"
+#include "Nodes.h"
-#include "CodeGenerator.h"
-#include "ExecState.h"
+#include "BytecodeGenerator.h"
+#include "CallFrame.h"
#include "JSGlobalObject.h"
#include "JSStaticScopeObject.h"
#include "LabelScope.h"
@@ -36,8 +36,8 @@
#include "RegExpObject.h"
#include "SamplingTool.h"
#include "Debugger.h"
-#include "lexer.h"
-#include "operations.h"
+#include "Lexer.h"
+#include "Operations.h"
#include <math.h>
#include <wtf/Assertions.h>
#include <wtf/HashCountedSet.h>
@@ -50,7 +50,73 @@ using namespace WTF;
namespace JSC {
-// ------------------------------ Node -----------------------------------------
+static void substitute(UString& string, const UString& substring) JSC_FAST_CALL;
+
+// ------------------------------ NodeReleaser --------------------------------
+
+class NodeReleaser : Noncopyable {
+public:
+ // Call this function inside the destructor of a class derived from Node.
+ // This will traverse the tree below this node, destroying all of those nodes,
+ // but without relying on recursion.
+ static void releaseAllNodes(ParserRefCounted* root);
+
+ // Call this on each node in a the releaseNodes virtual function.
+ // It gives the node to the NodeReleaser, which will then release the
+ // node later at the end of the releaseAllNodes process.
+ template <typename T> void release(RefPtr<T>& node) { if (node) adopt(node.release()); }
+ void release(RefPtr<FunctionBodyNode>& node) { if (node) adoptFunctionBodyNode(node); }
+
+private:
+ NodeReleaser() { }
+ ~NodeReleaser() { }
+
+ void adopt(PassRefPtr<ParserRefCounted>);
+ void adoptFunctionBodyNode(RefPtr<FunctionBodyNode>&);
+
+ typedef Vector<RefPtr<ParserRefCounted> > NodeReleaseVector;
+ OwnPtr<NodeReleaseVector> m_vector;
+};
+
+void NodeReleaser::releaseAllNodes(ParserRefCounted* root)
+{
+ ASSERT(root);
+ NodeReleaser releaser;
+ root->releaseNodes(releaser);
+ if (!releaser.m_vector)
+ return;
+ // Note: The call to release.m_vector->size() is intentionally inside
+ // the loop, since calls to releaseNodes are expected to increase the size.
+ for (size_t i = 0; i < releaser.m_vector->size(); ++i) {
+ ParserRefCounted* node = (*releaser.m_vector)[i].get();
+ if (node->hasOneRef())
+ node->releaseNodes(releaser);
+ }
+}
+
+void NodeReleaser::adopt(PassRefPtr<ParserRefCounted> node)
+{
+ ASSERT(node);
+ if (!node->hasOneRef())
+ return;
+ if (!m_vector)
+ m_vector.set(new NodeReleaseVector);
+ m_vector->append(node);
+}
+
+void NodeReleaser::adoptFunctionBodyNode(RefPtr<FunctionBodyNode>& functionBodyNode)
+{
+ // This sidesteps a problem where if you assign a PassRefPtr<FunctionBodyNode>
+ // to a PassRefPtr<Node> we leave the two reference counts (FunctionBodyNode
+ // and ParserRefCounted) unbalanced. It would be nice to fix this problem in
+ // a cleaner way -- perhaps we could remove the FunctionBodyNode reference
+ // count at some point.
+ RefPtr<Node> node = functionBodyNode;
+ functionBodyNode = 0;
+ adopt(node.release());
+}
+
+// ------------------------------ ParserRefCounted -----------------------------------------
#ifndef NDEBUG
static RefCountedLeakCounter parserRefCountedCounter("JSC::Node");
@@ -75,6 +141,10 @@ ParserRefCounted::~ParserRefCounted()
#endif
}
+void ParserRefCounted::releaseNodes(NodeReleaser&)
+{
+}
+
void ParserRefCounted::ref()
{
// bumping from 0 to 1 is just removing from the new nodes set
@@ -140,13 +210,16 @@ void ParserRefCounted::deleteNewObjects(JSGlobalData* globalData)
globalData->newParserObjects = 0;
}
+// ------------------------------ Node --------------------------------
+
Node::Node(JSGlobalData* globalData)
: ParserRefCounted(globalData)
{
m_line = globalData->lexer->lineNo();
}
-static void substitute(UString& string, const UString& substring) JSC_FAST_CALL;
+// ------------------------------ ThrowableExpressionData --------------------------------
+
static void substitute(UString& string, const UString& substring)
{
int position = string.find("%s");
@@ -157,19 +230,19 @@ static void substitute(UString& string, const UString& substring)
string = newString;
}
-RegisterID* ThrowableExpressionData::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
+RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg)
{
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), msg));
generator.emitThrow(exception);
return exception;
}
-RegisterID* ThrowableExpressionData::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label)
+RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label)
{
UString message = msg;
substitute(message, label.ustring());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalData(), message));
generator.emitThrow(exception);
return exception;
@@ -201,72 +274,72 @@ void SourceElements::append(PassRefPtr<StatementNode> statement)
// ------------------------------ NullNode -------------------------------------
-RegisterID* NullNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.emitLoad(dst, jsNull());
}
// ------------------------------ BooleanNode ----------------------------------
-RegisterID* BooleanNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.emitLoad(dst, m_value);
}
// ------------------------------ NumberNode -----------------------------------
-RegisterID* NumberNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.emitLoad(dst, m_double);
}
// ------------------------------ StringNode -----------------------------------
-RegisterID* StringNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.emitLoad(dst, m_value);
}
// ------------------------------ RegExpNode -----------------------------------
-RegisterID* RegExpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern, m_flags);
if (!regExp->isValid())
return emitThrowError(generator, SyntaxError, ("Invalid regular expression: " + UString(regExp->errorMessage())).UTF8String().c_str());
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
}
// ------------------------------ ThisNode -------------------------------------
-RegisterID* ThisNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
}
// ------------------------------ ResolveNode ----------------------------------
-bool ResolveNode::isPure(CodeGenerator& generator) const
+bool ResolveNode::isPure(BytecodeGenerator& generator) const
{
return generator.isLocal(m_ident);
}
-RegisterID* ResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (RegisterID* local = generator.registerFor(m_ident)) {
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.moveToDestinationIfNeeded(dst, local);
}
@@ -275,9 +348,32 @@ RegisterID* ResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
return generator.emitResolve(generator.finalDestination(dst), m_ident);
}
+// ------------------------------ ElementNode ------------------------------------
+
+ElementNode::~ElementNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ElementNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_next);
+ releaser.release(m_node);
+}
+
// ------------------------------ ArrayNode ------------------------------------
-RegisterID* ArrayNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+ArrayNode::~ArrayNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ArrayNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_element);
+}
+
+RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
// FIXME: Should we put all of this code into emitNewArray?
@@ -308,12 +404,34 @@ RegisterID* ArrayNode::emitCode(CodeGenerator& generator, RegisterID* dst)
return generator.moveToDestinationIfNeeded(dst, array.get());
}
+// ------------------------------ PropertyNode ----------------------------
+
+PropertyNode::~PropertyNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void PropertyNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_assign);
+}
+
// ------------------------------ ObjectLiteralNode ----------------------------
-RegisterID* ObjectLiteralNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+ObjectLiteralNode::~ObjectLiteralNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ObjectLiteralNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_list);
+}
+
+RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (!m_list) {
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.emitNewObject(generator.finalDestination(dst));
}
@@ -322,7 +440,18 @@ RegisterID* ObjectLiteralNode::emitCode(CodeGenerator& generator, RegisterID* ds
// ------------------------------ PropertyListNode -----------------------------
-RegisterID* PropertyListNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+PropertyListNode::~PropertyListNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void PropertyListNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_node);
+ releaser.release(m_next);
+}
+
+RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> newObj = generator.tempDestination(dst);
@@ -354,113 +483,239 @@ RegisterID* PropertyListNode::emitCode(CodeGenerator& generator, RegisterID* dst
// ------------------------------ BracketAccessorNode --------------------------------
-RegisterID* BracketAccessorNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+BracketAccessorNode::~BracketAccessorNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void BracketAccessorNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+ releaser.release(m_subscript);
+}
+
+RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments, m_subscript->isPure(generator));
RegisterID* property = generator.emitNode(m_subscript.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
}
// ------------------------------ DotAccessorNode --------------------------------
-RegisterID* DotAccessorNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+DotAccessorNode::~DotAccessorNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void DotAccessorNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+}
+
+RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RegisterID* base = generator.emitNode(m_base.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
}
// ------------------------------ ArgumentListNode -----------------------------
-RegisterID* ArgumentListNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+ArgumentListNode::~ArgumentListNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ArgumentListNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_next);
+ releaser.release(m_expr);
+}
+
+RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
ASSERT(m_expr);
return generator.emitNode(dst, m_expr.get());
}
+// ------------------------------ ArgumentsNode -----------------------------
+
+ArgumentsNode::~ArgumentsNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ArgumentsNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_listNode);
+}
+
// ------------------------------ NewExprNode ----------------------------------
-RegisterID* NewExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+NewExprNode::~NewExprNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void NewExprNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+ releaser.release(m_args);
+}
+
+RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
- return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
+ return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args.get(), divot(), startOffset(), endOffset());
+}
+
+// ------------------------------ EvalFunctionCallNode ----------------------------------
+
+EvalFunctionCallNode::~EvalFunctionCallNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void EvalFunctionCallNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_args);
}
-RegisterID* EvalFunctionCallNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<RegisterID> base = generator.tempDestination(dst);
- RefPtr<RegisterID> func = generator.newTemporary();
- generator.emitResolveWithBase(base.get(), func.get(), generator.propertyNames().eval);
- return generator.emitCallEval(generator.finalDestination(dst, base.get()), func.get(), base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
+ RefPtr<RegisterID> func = generator.tempDestination(dst);
+ RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
+ generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
+ return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
}
-RegisterID* FunctionCallValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+// ------------------------------ FunctionCallValueNode ----------------------------------
+
+FunctionCallValueNode::~FunctionCallValueNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void FunctionCallValueNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+ releaser.release(m_args);
+}
+
+RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
- return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
+ RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
+ return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+}
+
+// ------------------------------ FunctionCallResolveNode ----------------------------------
+
+FunctionCallResolveNode::~FunctionCallResolveNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void FunctionCallResolveNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_args);
}
-RegisterID* FunctionCallResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (RefPtr<RegisterID> local = generator.registerFor(m_ident))
- return generator.emitCall(generator.finalDestination(dst), local.get(), 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
+ if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
+ RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
+ return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+ }
int index = 0;
size_t depth = 0;
JSObject* globalObject = 0;
if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
- return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
+ RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
+ return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
}
- RefPtr<RegisterID> base = generator.tempDestination(dst);
- RefPtr<RegisterID> func = generator.newTemporary();
- int identifierStart = m_divot - m_startOffset;
+ RefPtr<RegisterID> func = generator.tempDestination(dst);
+ RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ int identifierStart = divot() - startOffset();
generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
- generator.emitResolveFunction(base.get(), func.get(), m_ident);
- return generator.emitCall(generator.finalDestination(dst, base.get()), func.get(), base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
+ generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident);
+ return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+}
+
+// ------------------------------ FunctionCallBracketNode ----------------------------------
+
+FunctionCallBracketNode::~FunctionCallBracketNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void FunctionCallBracketNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+ releaser.release(m_subscript);
+ releaser.release(m_args);
}
-RegisterID* FunctionCallBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNode(m_base.get());
RegisterID* property = generator.emitNode(m_subscript.get());
- generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
- RefPtr<RegisterID> function = generator.emitGetByVal(generator.newTemporary(), base.get(), property);
- return generator.emitCall(generator.finalDestination(dst, base.get()), function.get(), base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
+ RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
+ return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+}
+
+// ------------------------------ FunctionCallDotNode ----------------------------------
+
+FunctionCallDotNode::~FunctionCallDotNode()
+{
+ NodeReleaser::releaseAllNodes(this);
}
-RegisterID* FunctionCallDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+void FunctionCallDotNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+ releaser.release(m_args);
+}
+
+RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNode(m_base.get());
- generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
- RefPtr<RegisterID> function = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
- return generator.emitCall(generator.finalDestination(dst, base.get()), function.get(), base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
+ RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
+ return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
}
// ------------------------------ PostfixResolveNode ----------------------------------
-static RegisterID* emitPreIncOrDec(CodeGenerator& generator, RegisterID* srcDst, Operator oper)
+static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
{
return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
}
-static RegisterID* emitPostIncOrDec(CodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
+static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
{
return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
}
-RegisterID* PostfixResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (RegisterID* local = generator.registerFor(m_ident)) {
if (generator.isLocalConstant(m_ident)) {
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.emitToJSNumber(generator.finalDestination(dst), local);
}
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return emitPreIncOrDec(generator, local, m_operator);
return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
}
@@ -471,7 +726,7 @@ RegisterID* PostfixResolveNode::emitCode(CodeGenerator& generator, RegisterID* d
if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
RegisterID* oldValue;
- if (dst == ignoredResult()) {
+ if (dst == generator.ignoredResult()) {
oldValue = 0;
emitPreIncOrDec(generator, value.get(), m_operator);
} else {
@@ -481,11 +736,11 @@ RegisterID* PostfixResolveNode::emitCode(CodeGenerator& generator, RegisterID* d
return oldValue;
}
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
RefPtr<RegisterID> value = generator.newTemporary();
RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
RegisterID* oldValue;
- if (dst == ignoredResult()) {
+ if (dst == generator.ignoredResult()) {
oldValue = 0;
emitPreIncOrDec(generator, value.get(), m_operator);
} else {
@@ -497,15 +752,26 @@ RegisterID* PostfixResolveNode::emitCode(CodeGenerator& generator, RegisterID* d
// ------------------------------ PostfixBracketNode ----------------------------------
-RegisterID* PostfixBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+PostfixBracketNode::~PostfixBracketNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void PostfixBracketNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+ releaser.release(m_subscript);
+}
+
+RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNode(m_base.get());
RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
- generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
RegisterID* oldValue;
- if (dst == ignoredResult()) {
+ if (dst == generator.ignoredResult()) {
oldValue = 0;
if (m_operator == OpPlusPlus)
generator.emitPreInc(value.get());
@@ -514,21 +780,31 @@ RegisterID* PostfixBracketNode::emitCode(CodeGenerator& generator, RegisterID* d
} else {
oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
}
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutByVal(base.get(), property.get(), value.get());
return oldValue;
}
// ------------------------------ PostfixDotNode ----------------------------------
-RegisterID* PostfixDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+PostfixDotNode::~PostfixDotNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void PostfixDotNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+}
+
+RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNode(m_base.get());
- generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
RegisterID* oldValue;
- if (dst == ignoredResult()) {
+ if (dst == generator.ignoredResult()) {
oldValue = 0;
if (m_operator == OpPlusPlus)
generator.emitPreInc(value.get());
@@ -537,56 +813,97 @@ RegisterID* PostfixDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
} else {
oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
}
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutById(base.get(), m_ident, value.get());
return oldValue;
}
// ------------------------------ PostfixErrorNode -----------------------------------
-RegisterID* PostfixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
+PostfixErrorNode::~PostfixErrorNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void PostfixErrorNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+}
+
+RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
}
// ------------------------------ DeleteResolveNode -----------------------------------
-RegisterID* DeleteResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (generator.registerFor(m_ident))
return generator.emitUnexpectedLoad(generator.finalDestination(dst), false);
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
}
// ------------------------------ DeleteBracketNode -----------------------------------
-RegisterID* DeleteBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+DeleteBracketNode::~DeleteBracketNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void DeleteBracketNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+ releaser.release(m_subscript);
+}
+
+RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
RegisterID* r1 = generator.emitNode(m_subscript.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
}
// ------------------------------ DeleteDotNode -----------------------------------
-RegisterID* DeleteDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+DeleteDotNode::~DeleteDotNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void DeleteDotNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+}
+
+RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RegisterID* r0 = generator.emitNode(m_base.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
}
// ------------------------------ DeleteValueNode -----------------------------------
-RegisterID* DeleteValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+DeleteValueNode::~DeleteValueNode()
{
- generator.emitNode(ignoredResult(), m_expr.get());
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void DeleteValueNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+}
+
+RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitNode(generator.ignoredResult(), m_expr.get());
// delete on a non-location expression ignores the value and returns true
return generator.emitUnexpectedLoad(generator.finalDestination(dst), true);
@@ -594,10 +911,20 @@ RegisterID* DeleteValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ VoidNode -------------------------------------
-RegisterID* VoidNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+VoidNode::~VoidNode()
{
- if (dst == ignoredResult()) {
- generator.emitNode(ignoredResult(), m_expr.get());
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void VoidNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+}
+
+RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (dst == generator.ignoredResult()) {
+ generator.emitNode(generator.ignoredResult(), m_expr.get());
return 0;
}
RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
@@ -606,27 +933,37 @@ RegisterID* VoidNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ TypeOfValueNode -----------------------------------
-RegisterID* TypeOfResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (RegisterID* local = generator.registerFor(m_ident)) {
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.emitTypeOf(generator.finalDestination(dst), local);
}
RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
generator.emitGetById(scratch.get(), scratch.get(), m_ident);
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
}
// ------------------------------ TypeOfValueNode -----------------------------------
-RegisterID* TypeOfValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+TypeOfValueNode::~TypeOfValueNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void TypeOfValueNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+}
+
+RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (dst == ignoredResult()) {
- generator.emitNode(ignoredResult(), m_expr.get());
+ if (dst == generator.ignoredResult()) {
+ generator.emitNode(generator.ignoredResult(), m_expr.get());
return 0;
}
RefPtr<RegisterID> src = generator.emitNode(m_expr.get());
@@ -635,11 +972,11 @@ RegisterID* TypeOfValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ PrefixResolveNode ----------------------------------
-RegisterID* PrefixResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (RegisterID* local = generator.registerFor(m_ident)) {
if (generator.isLocalConstant(m_ident)) {
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
return 0;
RefPtr<RegisterID> r0 = generator.emitUnexpectedLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
@@ -659,7 +996,7 @@ RegisterID* PrefixResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
RefPtr<RegisterID> propDst = generator.tempDestination(dst);
RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
emitPreIncOrDec(generator, propDst.get(), m_operator);
@@ -669,78 +1006,132 @@ RegisterID* PrefixResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
// ------------------------------ PrefixBracketNode ----------------------------------
-RegisterID* PrefixBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+PrefixBracketNode::~PrefixBracketNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void PrefixBracketNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+ releaser.release(m_subscript);
+}
+
+RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNode(m_base.get());
RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
RefPtr<RegisterID> propDst = generator.tempDestination(dst);
- generator.emitExpressionInfo(m_divot + m_subexpressionDivotOffset, m_subexpressionStartOffset, m_endOffset - m_subexpressionDivotOffset);
+ generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
if (m_operator == OpPlusPlus)
generator.emitPreInc(value);
else
generator.emitPreDec(value);
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutByVal(base.get(), property.get(), value);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
// ------------------------------ PrefixDotNode ----------------------------------
-RegisterID* PrefixDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+PrefixDotNode::~PrefixDotNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void PrefixDotNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+}
+
+RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNode(m_base.get());
RefPtr<RegisterID> propDst = generator.tempDestination(dst);
- generator.emitExpressionInfo(m_divot + m_subexpressionDivotOffset, m_subexpressionStartOffset, m_endOffset - m_subexpressionDivotOffset);
+ generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
if (m_operator == OpPlusPlus)
generator.emitPreInc(value);
else
generator.emitPreDec(value);
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutById(base.get(), m_ident, value);
return generator.moveToDestinationIfNeeded(dst, propDst.get());
}
// ------------------------------ PrefixErrorNode -----------------------------------
-RegisterID* PrefixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
+PrefixErrorNode::~PrefixErrorNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void PrefixErrorNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+}
+
+RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
}
// ------------------------------ Unary Operation Nodes -----------------------------------
-RegisterID* UnaryOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+UnaryOpNode::~UnaryOpNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void UnaryOpNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+}
+
+RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RegisterID* src = generator.emitNode(m_expr.get());
- return generator.emitUnaryOp(opcode(), generator.finalDestination(dst), src, m_expr->resultDescriptor());
+ return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
}
// ------------------------------ Binary Operation Nodes -----------------------------------
-RegisterID* BinaryOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+BinaryOpNode::~BinaryOpNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void BinaryOpNode::releaseNodes(NodeReleaser& releaser)
{
- OpcodeID opcode = this->opcode();
- if (opcode == op_neq) {
+ releaser.release(m_expr1);
+ releaser.release(m_expr2);
+}
+
+RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ OpcodeID opcodeID = this->opcodeID();
+ if (opcodeID == op_neq) {
if (m_expr1->isNull() || m_expr2->isNull()) {
- RefPtr<RegisterID> src = generator.emitNode(dst, m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
- return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get(), ResultType::unknown());
+ RefPtr<RegisterID> src = generator.tempDestination(dst);
+ generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
+ return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
}
}
RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
RegisterID* src2 = generator.emitNode(m_expr2.get());
- return generator.emitBinaryOp(opcode, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
+ return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
}
-RegisterID* EqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (m_expr1->isNull() || m_expr2->isNull()) {
- RefPtr<RegisterID> src = generator.emitNode(dst, m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
- return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get(), ResultType::unknown());
+ RefPtr<RegisterID> src = generator.tempDestination(dst);
+ generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
+ return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
}
RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
@@ -748,46 +1139,58 @@ RegisterID* EqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
}
-RegisterID* StrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
RegisterID* src2 = generator.emitNode(m_expr2.get());
return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
}
-RegisterID* ReverseBinaryOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
RegisterID* src2 = generator.emitNode(m_expr2.get());
- return generator.emitBinaryOp(opcode(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));
+ return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));
}
-RegisterID* ThrowableBinaryOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
RegisterID* src2 = generator.emitNode(m_expr2.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
- return generator.emitBinaryOp(opcode(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
}
-RegisterID* InstanceOfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
RefPtr<RegisterID> src2 = generator.emitNode(m_expr2.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitGetByIdExceptionInfo(op_instanceof);
RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
}
-// ------------------------------ Binary Logical Nodes ----------------------------
+// ------------------------------ LogicalOpNode ----------------------------
-RegisterID* LogicalOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+LogicalOpNode::~LogicalOpNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void LogicalOpNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr1);
+ releaser.release(m_expr2);
+}
+
+RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> temp = generator.tempDestination(dst);
- RefPtr<LabelID> target = generator.newLabel();
+ RefPtr<Label> target = generator.newLabel();
generator.emitNode(temp.get(), m_expr1.get());
if (m_operator == OpLogicalAnd)
@@ -802,11 +1205,23 @@ RegisterID* LogicalOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ ConditionalNode ------------------------------
-RegisterID* ConditionalNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+ConditionalNode::~ConditionalNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ConditionalNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_logical);
+ releaser.release(m_expr1);
+ releaser.release(m_expr2);
+}
+
+RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> newDst = generator.finalDestination(dst);
- RefPtr<LabelID> beforeElse = generator.newLabel();
- RefPtr<LabelID> afterElse = generator.newLabel();
+ RefPtr<Label> beforeElse = generator.newLabel();
+ RefPtr<Label> afterElse = generator.newLabel();
RegisterID* cond = generator.emitNode(m_logical.get());
generator.emitJumpIfFalse(cond, beforeElse.get());
@@ -824,71 +1239,81 @@ RegisterID* ConditionalNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ ReadModifyResolveNode -----------------------------------
-// FIXME: should this be moved to be a method on CodeGenerator?
-static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(CodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper, OperandTypes types)
+ReadModifyResolveNode::~ReadModifyResolveNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ReadModifyResolveNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_right);
+}
+
+// FIXME: should this be moved to be a method on BytecodeGenerator?
+static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper, OperandTypes types)
{
- OpcodeID opcode;
+ OpcodeID opcodeID;
switch (oper) {
case OpMultEq:
- opcode = op_mul;
+ opcodeID = op_mul;
break;
case OpDivEq:
- opcode = op_div;
+ opcodeID = op_div;
break;
case OpPlusEq:
- opcode = op_add;
+ opcodeID = op_add;
break;
case OpMinusEq:
- opcode = op_sub;
+ opcodeID = op_sub;
break;
case OpLShift:
- opcode = op_lshift;
+ opcodeID = op_lshift;
break;
case OpRShift:
- opcode = op_rshift;
+ opcodeID = op_rshift;
break;
case OpURShift:
- opcode = op_urshift;
+ opcodeID = op_urshift;
break;
case OpAndEq:
- opcode = op_bitand;
+ opcodeID = op_bitand;
break;
case OpXOrEq:
- opcode = op_bitxor;
+ opcodeID = op_bitxor;
break;
case OpOrEq:
- opcode = op_bitor;
+ opcodeID = op_bitor;
break;
case OpModEq:
- opcode = op_mod;
+ opcodeID = op_mod;
break;
default:
ASSERT_NOT_REACHED();
return dst;
}
- return generator.emitBinaryOp(opcode, dst, src1, src2, types);
+ return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
}
-RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (RegisterID* local = generator.registerFor(m_ident)) {
if (generator.isLocalConstant(m_ident)) {
RegisterID* src2 = generator.emitNode(m_right.get());
- return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
+ return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
}
if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
RefPtr<RegisterID> result = generator.newTemporary();
generator.emitMove(result.get(), local);
RegisterID* src2 = generator.emitNode(m_right.get());
- emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
+ emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
generator.emitMove(local, result.get());
return generator.moveToDestinationIfNeeded(dst, result.get());
}
RegisterID* src2 = generator.emitNode(m_right.get());
- RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
+ RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
return generator.moveToDestinationIfNeeded(dst, result);
}
@@ -898,23 +1323,33 @@ RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID
if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
RegisterID* src2 = generator.emitNode(m_right.get());
- RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
+ RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
generator.emitPutScopedVar(depth, index, result, globalObject);
return result;
}
RefPtr<RegisterID> src1 = generator.tempDestination(dst);
- generator.emitExpressionInfo(m_divot - m_startOffset + m_ident.size(), m_ident.size(), 0);
+ generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0);
RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
RegisterID* src2 = generator.emitNode(m_right.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
- RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
return generator.emitPutById(base.get(), m_ident, result);
}
// ------------------------------ AssignResolveNode -----------------------------------
-RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+AssignResolveNode::~AssignResolveNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void AssignResolveNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_right);
+}
+
+RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (RegisterID* local = generator.registerFor(m_ident)) {
if (generator.isLocalConstant(m_ident))
@@ -928,7 +1363,7 @@ RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
size_t depth = 0;
JSObject* globalObject = 0;
if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
dst = 0;
RegisterID* value = generator.emitNode(dst, m_right.get());
generator.emitPutScopedVar(depth, index, value, globalObject);
@@ -936,72 +1371,131 @@ RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
}
RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
dst = 0;
RegisterID* value = generator.emitNode(dst, m_right.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
return generator.emitPutById(base.get(), m_ident, value);
}
// ------------------------------ AssignDotNode -----------------------------------
-RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+AssignDotNode::~AssignDotNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void AssignDotNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+ releaser.release(m_right);
+}
+
+RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
RegisterID* result = generator.emitNode(value.get(), m_right.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutById(base.get(), m_ident, result);
return generator.moveToDestinationIfNeeded(dst, result);
}
// ------------------------------ ReadModifyDotNode -----------------------------------
-RegisterID* ReadModifyDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+ReadModifyDotNode::~ReadModifyDotNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ReadModifyDotNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+ releaser.release(m_right);
+}
+
+RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
- generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
RegisterID* change = generator.emitNode(m_right.get());
- RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
+ RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
return generator.emitPutById(base.get(), m_ident, updatedValue);
}
// ------------------------------ AssignErrorNode -----------------------------------
-RegisterID* AssignErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
+AssignErrorNode::~AssignErrorNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void AssignErrorNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_left);
+ releaser.release(m_right);
+}
+
+RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
}
// ------------------------------ AssignBracketNode -----------------------------------
-RegisterID* AssignBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+AssignBracketNode::~AssignBracketNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void AssignBracketNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+ releaser.release(m_subscript);
+ releaser.release(m_right);
+}
+
+RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
RegisterID* result = generator.emitNode(value.get(), m_right.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutByVal(base.get(), property.get(), result);
return generator.moveToDestinationIfNeeded(dst, result);
}
-RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+// ------------------------------ ReadModifyBracketNode -----------------------------------
+
+ReadModifyBracketNode::~ReadModifyBracketNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ReadModifyBracketNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_base);
+ releaser.release(m_subscript);
+ releaser.release(m_right);
+}
+
+RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
- generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
RegisterID* change = generator.emitNode(m_right.get());
- RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknown(), m_right->resultDescriptor()));
+ RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutByVal(base.get(), property.get(), updatedValue);
return updatedValue;
@@ -1009,13 +1503,35 @@ RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator& generator, RegisterID
// ------------------------------ CommaNode ------------------------------------
-RegisterID* CommaNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+CommaNode::~CommaNode()
{
- generator.emitNode(ignoredResult(), m_expr1.get());
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void CommaNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr1);
+ releaser.release(m_expr2);
+}
+
+RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitNode(generator.ignoredResult(), m_expr1.get());
return generator.emitNode(dst, m_expr2.get());
}
-// ------------------------------ ConstDeclNode ----------------------------------
+// ------------------------------ ConstDeclNode ------------------------------------
+
+ConstDeclNode::~ConstDeclNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ConstDeclNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_next);
+ releaser.release(m_init);
+}
ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* init)
: ExpressionNode(globalData)
@@ -1024,7 +1540,7 @@ ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident,
{
}
-RegisterID* ConstDeclNode::emitCodeSingle(CodeGenerator& generator)
+RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
{
if (RegisterID* local = generator.constRegisterFor(m_ident)) {
if (!m_init)
@@ -1040,7 +1556,7 @@ RegisterID* ConstDeclNode::emitCodeSingle(CodeGenerator& generator)
return generator.emitPutById(base.get(), m_ident, value);
}
-RegisterID* ConstDeclNode::emitCode(CodeGenerator& generator, RegisterID*)
+RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
RegisterID* result = 0;
for (ConstDeclNode* n = this; n; n = n->m_next.get())
@@ -1051,17 +1567,27 @@ RegisterID* ConstDeclNode::emitCode(CodeGenerator& generator, RegisterID*)
// ------------------------------ ConstStatementNode -----------------------------
-RegisterID* ConstStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
+ConstStatementNode::~ConstStatementNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ConstStatementNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_next);
+}
+
+RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
return generator.emitNode(m_next.get());
}
// ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
-static inline RegisterID* statementListEmitCode(StatementVector& statements, CodeGenerator& generator, RegisterID* dst)
+static inline RegisterID* statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst)
{
- StatementVector::iterator end = statements.end();
- for (StatementVector::iterator it = statements.begin(); it != end; ++it) {
+ StatementVector::const_iterator end = statements.end();
+ for (StatementVector::const_iterator it = statements.begin(); it != end; ++it) {
StatementNode* n = it->get();
if (!n->isLoop())
generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
@@ -1070,17 +1596,19 @@ static inline RegisterID* statementListEmitCode(StatementVector& statements, Cod
return 0;
}
-static inline void statementListPushFIFO(StatementVector& statements, DeclarationStacks::NodeStack& stack)
+// ------------------------------ BlockNode ------------------------------------
+
+BlockNode::~BlockNode()
{
- StatementVector::iterator it = statements.end();
- StatementVector::iterator begin = statements.begin();
- while (it != begin) {
- --it;
- stack.append((*it).get());
- }
+ NodeReleaser::releaseAllNodes(this);
}
-// ------------------------------ BlockNode ------------------------------------
+void BlockNode::releaseNodes(NodeReleaser& releaser)
+{
+ size_t size = m_children.size();
+ for (size_t i = 0; i < size; ++i)
+ releaser.release(m_children[i]);
+}
BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
: StatementNode(globalData)
@@ -1089,21 +1617,21 @@ BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
children->releaseContentsIntoVector(m_children);
}
-RegisterID* BlockNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
return statementListEmitCode(m_children, generator, dst);
}
// ------------------------------ EmptyStatementNode ---------------------------
-RegisterID* EmptyStatementNode::emitCode(CodeGenerator&, RegisterID* dst)
+RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID* dst)
{
return dst;
}
// ------------------------------ DebuggerStatementNode ---------------------------
-RegisterID* DebuggerStatementNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
return dst;
@@ -1111,7 +1639,7 @@ RegisterID* DebuggerStatementNode::emitCode(CodeGenerator& generator, RegisterID
// ------------------------------ ExprStatementNode ----------------------------
-RegisterID* ExprStatementNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
ASSERT(m_expr);
return generator.emitNode(dst, m_expr.get());
@@ -1119,7 +1647,17 @@ RegisterID* ExprStatementNode::emitCode(CodeGenerator& generator, RegisterID* ds
// ------------------------------ VarStatementNode ----------------------------
-RegisterID* VarStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
+VarStatementNode::~VarStatementNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void VarStatementNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+}
+
+RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
ASSERT(m_expr);
return generator.emitNode(m_expr.get());
@@ -1127,9 +1665,20 @@ RegisterID* VarStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
// ------------------------------ IfNode ---------------------------------------
-RegisterID* IfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+IfNode::~IfNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void IfNode::releaseNodes(NodeReleaser& releaser)
{
- RefPtr<LabelID> afterThen = generator.newLabel();
+ releaser.release(m_condition);
+ releaser.release(m_ifBlock);
+}
+
+RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<Label> afterThen = generator.newLabel();
RegisterID* cond = generator.emitNode(m_condition.get());
generator.emitJumpIfFalse(cond, afterThen.get());
@@ -1140,14 +1689,27 @@ RegisterID* IfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
generator.emitNode(dst, m_ifBlock.get());
generator.emitLabel(afterThen.get());
- // FIXME: This should return the last statement exectuted so that it can be returned as a Completion
+ // FIXME: This should return the last statement executed so that it can be returned as a Completion.
return 0;
}
-RegisterID* IfElseNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+// ------------------------------ IfElseNode ---------------------------------------
+
+IfElseNode::~IfElseNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void IfElseNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_elseBlock);
+ IfNode::releaseNodes(releaser);
+}
+
+RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<LabelID> beforeElse = generator.newLabel();
- RefPtr<LabelID> afterElse = generator.newLabel();
+ RefPtr<Label> beforeElse = generator.newLabel();
+ RefPtr<Label> afterElse = generator.newLabel();
RegisterID* cond = generator.emitNode(m_condition.get());
generator.emitJumpIfFalse(cond, beforeElse.get());
@@ -1167,17 +1729,28 @@ RegisterID* IfElseNode::emitCode(CodeGenerator& generator, RegisterID* dst)
generator.emitLabel(afterElse.get());
- // FIXME: This should return the last statement exectuted so that it can be returned as a Completion
+ // FIXME: This should return the last statement executed so that it can be returned as a Completion.
return 0;
}
// ------------------------------ DoWhileNode ----------------------------------
-RegisterID* DoWhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+DoWhileNode::~DoWhileNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void DoWhileNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_statement);
+ releaser.release(m_expr);
+}
+
+RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
- RefPtr<LabelID> topOfLoop = generator.newLabel();
+ RefPtr<Label> topOfLoop = generator.newLabel();
generator.emitLabel(topOfLoop.get());
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
@@ -1198,13 +1771,24 @@ RegisterID* DoWhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ WhileNode ------------------------------------
-RegisterID* WhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+WhileNode::~WhileNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void WhileNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+ releaser.release(m_statement);
+}
+
+RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
generator.emitJump(scope->continueTarget());
- RefPtr<LabelID> topOfLoop = generator.newLabel();
+ RefPtr<Label> topOfLoop = generator.newLabel();
generator.emitLabel(topOfLoop.get());
if (!m_statement->isBlock())
@@ -1225,9 +1809,22 @@ RegisterID* WhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ ForNode --------------------------------------
-RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+ForNode::~ForNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ForNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr1);
+ releaser.release(m_expr2);
+ releaser.release(m_expr3);
+ releaser.release(m_statement);
+}
+
+RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
dst = 0;
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
@@ -1235,12 +1832,12 @@ RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
if (m_expr1)
- generator.emitNode(ignoredResult(), m_expr1.get());
+ generator.emitNode(generator.ignoredResult(), m_expr1.get());
- RefPtr<LabelID> condition = generator.newLabel();
+ RefPtr<Label> condition = generator.newLabel();
generator.emitJump(condition.get());
- RefPtr<LabelID> topOfLoop = generator.newLabel();
+ RefPtr<Label> topOfLoop = generator.newLabel();
generator.emitLabel(topOfLoop.get());
if (!m_statement->isBlock())
@@ -1249,7 +1846,7 @@ RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
generator.emitLabel(scope->continueTarget());
if (m_expr3)
- generator.emitNode(ignoredResult(), m_expr3.get());
+ generator.emitNode(generator.ignoredResult(), m_expr3.get());
generator.emitLabel(condition.get());
if (m_expr2) {
@@ -1264,6 +1861,19 @@ RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ ForInNode ------------------------------------
+ForInNode::~ForInNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ForInNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_init);
+ releaser.release(m_lexpr);
+ releaser.release(m_expr);
+ releaser.release(m_statement);
+}
+
ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
: StatementNode(globalData)
, m_init(0L)
@@ -1290,24 +1900,24 @@ ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, Expressi
// for( var foo = bar in baz )
}
-RegisterID* ForInNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
if (!m_lexpr->isLocation())
return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference.");
- RefPtr<LabelID> continueTarget = generator.newLabel();
+ RefPtr<Label> continueTarget = generator.newLabel();
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
if (m_init)
- generator.emitNode(ignoredResult(), m_init.get());
+ generator.emitNode(generator.ignoredResult(), m_init.get());
RegisterID* forInBase = generator.emitNode(m_expr.get());
RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
generator.emitJump(scope->continueTarget());
- RefPtr<LabelID> loopStart = generator.newLabel();
+ RefPtr<Label> loopStart = generator.newLabel();
generator.emitLabel(loopStart.get());
RegisterID* propertyName;
@@ -1319,7 +1929,7 @@ RegisterID* ForInNode::emitCode(CodeGenerator& generator, RegisterID* dst)
RefPtr<RegisterID> protect = propertyName;
RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitPutById(base, ident, propertyName);
}
} else if (m_lexpr->isDotAccessorNode()) {
@@ -1356,7 +1966,7 @@ RegisterID* ForInNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ ContinueNode ---------------------------------
// ECMA 12.7
-RegisterID* ContinueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
LabelScope* scope = generator.continueTarget(m_ident);
@@ -1372,7 +1982,7 @@ RegisterID* ContinueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ BreakNode ------------------------------------
// ECMA 12.8
-RegisterID* BreakNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
LabelScope* scope = generator.breakTarget(m_ident);
@@ -1387,16 +1997,26 @@ RegisterID* BreakNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ ReturnNode -----------------------------------
-RegisterID* ReturnNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+ReturnNode::~ReturnNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ReturnNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_value);
+}
+
+RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (generator.codeType() != FunctionCode)
return emitThrowError(generator, SyntaxError, "Invalid return statement.");
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
dst = 0;
RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(dst, jsUndefined());
if (generator.scopeDepth()) {
- RefPtr<LabelID> l0 = generator.newLabel();
+ RefPtr<Label> l0 = generator.newLabel();
generator.emitJumpScopes(l0.get(), 0);
generator.emitLabel(l0.get());
}
@@ -1406,9 +2026,21 @@ RegisterID* ReturnNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ WithNode -------------------------------------
-RegisterID* WithNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+WithNode::~WithNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void WithNode::releaseNodes(NodeReleaser& releaser)
{
- RefPtr<RegisterID> scope = generator.emitNode(m_expr.get()); // scope must be protected until popped
+ releaser.release(m_expr);
+ releaser.release(m_statement);
+}
+
+RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> scope = generator.newTemporary();
+ generator.emitNode(scope.get(), m_expr.get()); // scope must be protected until popped
generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
generator.emitPushScope(scope.get());
RegisterID* result = generator.emitNode(dst, m_statement.get());
@@ -1416,7 +2048,45 @@ RegisterID* WithNode::emitCode(CodeGenerator& generator, RegisterID* dst)
return result;
}
+// ------------------------------ CaseClauseNode --------------------------------
+
+CaseClauseNode::~CaseClauseNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void CaseClauseNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+}
+
+// ------------------------------ ClauseListNode --------------------------------
+
+ClauseListNode::~ClauseListNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ClauseListNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_clause);
+ releaser.release(m_next);
+}
+
// ------------------------------ CaseBlockNode --------------------------------
+
+CaseBlockNode::~CaseBlockNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void CaseBlockNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_list1);
+ releaser.release(m_defaultClause);
+ releaser.release(m_list2);
+}
+
enum SwitchKind {
SwitchUnset = 0,
SwitchNumber = 1,
@@ -1431,7 +2101,8 @@ static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>&
literalVector.append(clauseExpression);
if (clauseExpression->isNumber()) {
double value = static_cast<NumberNode*>(clauseExpression)->value();
- if ((typeForTable & ~SwitchNumber) || !JSImmediate::from(value)) {
+ JSValuePtr jsValue = JSValuePtr::makeInt32Fast(static_cast<int32_t>(value));
+ if ((typeForTable & ~SwitchNumber) || !jsValue || (jsValue.getInt32Fast() != value)) {
typeForTable = SwitchNeither;
break;
}
@@ -1494,10 +2165,10 @@ SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*,
return SwitchInfo::SwitchString;
}
-RegisterID* CaseBlockNode::emitCodeForBlock(CodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
+RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
{
- RefPtr<LabelID> defaultLabel;
- Vector<RefPtr<LabelID>, 8> labelVector;
+ RefPtr<Label> defaultLabel;
+ Vector<RefPtr<Label>, 8> labelVector;
Vector<ExpressionNode*, 8> literalVector;
int32_t min_num = std::numeric_limits<int32_t>::max();
int32_t max_num = std::numeric_limits<int32_t>::min();
@@ -1560,12 +2231,23 @@ RegisterID* CaseBlockNode::emitCodeForBlock(CodeGenerator& generator, RegisterID
// ------------------------------ SwitchNode -----------------------------------
-RegisterID* SwitchNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+SwitchNode::~SwitchNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void SwitchNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+ releaser.release(m_block);
+}
+
+RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
- RegisterID* r1 = m_block->emitCodeForBlock(generator, r0.get(), dst);
+ RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
generator.emitLabel(scope->breakTarget());
return r1;
@@ -1573,7 +2255,17 @@ RegisterID* SwitchNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ LabelNode ------------------------------------
-RegisterID* LabelNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+LabelNode::~LabelNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void LabelNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_statement);
+}
+
+RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
if (generator.breakTarget(m_name))
return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
@@ -1587,23 +2279,45 @@ RegisterID* LabelNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ------------------------------ ThrowNode ------------------------------------
-RegisterID* ThrowNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+ThrowNode::~ThrowNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ThrowNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_expr);
+}
+
+RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (dst == ignoredResult())
+ if (dst == generator.ignoredResult())
dst = 0;
RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
- generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitThrow(expr.get());
return dst;
}
// ------------------------------ TryNode --------------------------------------
-RegisterID* TryNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+TryNode::~TryNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void TryNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_tryBlock);
+ releaser.release(m_catchBlock);
+ releaser.release(m_finallyBlock);
+}
+
+RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- RefPtr<LabelID> tryStartLabel = generator.newLabel();
- RefPtr<LabelID> tryEndLabel = generator.newLabel();
- RefPtr<LabelID> finallyStart;
+ RefPtr<Label> tryStartLabel = generator.newLabel();
+ RefPtr<Label> tryEndLabel = generator.newLabel();
+ RefPtr<Label> finallyStart;
RefPtr<RegisterID> finallyReturnAddr;
if (m_finallyBlock) {
finallyStart = generator.newLabel();
@@ -1615,10 +2329,16 @@ RegisterID* TryNode::emitCode(CodeGenerator& generator, RegisterID* dst)
generator.emitLabel(tryEndLabel.get());
if (m_catchBlock) {
- RefPtr<LabelID> handlerEndLabel = generator.newLabel();
+ RefPtr<Label> handlerEndLabel = generator.newLabel();
generator.emitJump(handlerEndLabel.get());
RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
- generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
+ if (m_catchHasEval) {
+ RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
+ generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
+ generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get());
+ generator.emitPushScope(exceptionRegister.get());
+ } else
+ generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
generator.emitNode(dst, m_catchBlock.get());
generator.emitPopScope();
generator.emitLabel(handlerEndLabel.get());
@@ -1631,7 +2351,7 @@ RegisterID* TryNode::emitCode(CodeGenerator& generator, RegisterID* dst)
// ref the highest register ever used as a conservative
// approach to not clobbering anything important
RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
- RefPtr<LabelID> finallyEndLabel = generator.newLabel();
+ RefPtr<Label> finallyEndLabel = generator.newLabel();
generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
// Use a label to record the subtle fact that sret will return to the
// next instruction. sret is the only way to jump without an explicit label.
@@ -1657,24 +2377,78 @@ RegisterID* TryNode::emitCode(CodeGenerator& generator, RegisterID* dst)
return dst;
}
+// ------------------------------ ParameterNode -----------------------------
-// ------------------------------ ScopeNode -----------------------------
+ParameterNode::~ParameterNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
-ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
- : BlockNode(globalData, children)
- , m_source(source)
- , m_features(features)
- , m_numConstants(numConstants)
+void ParameterNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_next);
+}
+
+// -----------------------------ScopeNodeData ---------------------------
+
+ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
+ : m_numConstants(numConstants)
{
if (varStack)
m_varStack = *varStack;
if (funcStack)
m_functionStack = *funcStack;
+ if (children)
+ children->releaseContentsIntoVector(m_children);
+}
+
+void ScopeNodeData::mark()
+{
+ FunctionStack::iterator end = m_functionStack.end();
+ for (FunctionStack::iterator ptr = m_functionStack.begin(); ptr != end; ++ptr) {
+ FunctionBodyNode* body = (*ptr)->body();
+ if (!body->isGenerated())
+ continue;
+ body->generatedBytecode().mark();
+ }
+}
+
+// ------------------------------ ScopeNode -----------------------------
+
+ScopeNode::ScopeNode(JSGlobalData* globalData)
+ : StatementNode(globalData)
+ , m_features(NoFeatures)
+{
#if ENABLE(OPCODE_SAMPLING)
- globalData->machine->sampler()->notifyOfScope(this);
+ globalData->interpreter->sampler()->notifyOfScope(this);
#endif
}
+ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
+ : StatementNode(globalData)
+ , m_data(new ScopeNodeData(children, varStack, funcStack, numConstants))
+ , m_features(features)
+ , m_source(source)
+{
+#if ENABLE(OPCODE_SAMPLING)
+ globalData->interpreter->sampler()->notifyOfScope(this);
+#endif
+}
+
+ScopeNode::~ScopeNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void ScopeNode::releaseNodes(NodeReleaser& releaser)
+{
+ if (!m_data)
+ return;
+ size_t size = m_data->m_children.size();
+ for (size_t i = 0; i < size; ++i)
+ releaser.release(m_data->m_children[i]);
+}
+
// ------------------------------ ProgramNode -----------------------------
ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
@@ -1687,6 +2461,32 @@ ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* child
return new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
}
+RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+ generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
+
+ RefPtr<RegisterID> dstRegister = generator.newTemporary();
+ generator.emitLoad(dstRegister.get(), jsUndefined());
+ statementListEmitCode(children(), generator, dstRegister.get());
+
+ generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
+ generator.emitEnd(dstRegister.get());
+ return 0;
+}
+
+void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode)
+{
+ ScopeChain scopeChain(scopeChainNode);
+ JSGlobalObject* globalObject = scopeChain.globalObject();
+
+ m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
+
+ BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
+ generator.generate();
+
+ destroyData();
+}
+
// ------------------------------ EvalNode -----------------------------
EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
@@ -1694,38 +2494,71 @@ EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack*
{
}
-RegisterID* EvalNode::emitCode(CodeGenerator& generator, RegisterID*)
+EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
+{
+ return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
+}
+
+RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
RefPtr<RegisterID> dstRegister = generator.newTemporary();
generator.emitLoad(dstRegister.get(), jsUndefined());
- statementListEmitCode(m_children, generator, dstRegister.get());
+ statementListEmitCode(children(), generator, dstRegister.get());
generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
generator.emitEnd(dstRegister.get());
return 0;
}
-void EvalNode::generateCode(ScopeChainNode* scopeChainNode)
+void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode)
{
ScopeChain scopeChain(scopeChainNode);
JSGlobalObject* globalObject = scopeChain.globalObject();
- SymbolTable symbolTable;
- m_code.set(new EvalCodeBlock(this, globalObject, source().provider()));
+ m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
- CodeGenerator generator(this, globalObject->debugger(), scopeChain, &symbolTable, m_code.get());
+ BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
generator.generate();
+
+ // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
+ // so the entire ScopeNodeData cannot be destoyed.
+ children().clear();
}
-EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
+EvalCodeBlock& EvalNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom)
{
- return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
+ ASSERT(!m_code);
+
+ ScopeChain scopeChain(scopeChainNode);
+ JSGlobalObject* globalObject = scopeChain.globalObject();
+
+ m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
+
+ BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
+ generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
+ generator.generate();
+
+ return *m_code;
+}
+
+void EvalNode::mark()
+{
+ // We don't need to mark our own CodeBlock as the JSGlobalObject takes care of that
+ data()->mark();
}
// ------------------------------ FunctionBodyNode -----------------------------
+FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
+ : ScopeNode(globalData)
+ , m_parameters(0)
+ , m_parameterCount(0)
+ , m_refCount(0)
+{
+}
+
FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
: ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
, m_parameters(0)
@@ -1736,8 +2569,10 @@ FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* chi
FunctionBodyNode::~FunctionBodyNode()
{
- if (m_parameters)
- fastFree(m_parameters);
+ ASSERT(!m_refCount);
+ for (size_t i = 0; i < m_parameterCount; ++i)
+ m_parameters[i].~Identifier();
+ fastFree(m_parameters);
}
void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter)
@@ -1764,9 +2599,9 @@ void FunctionBodyNode::mark()
m_code->mark();
}
-FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
+FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
{
- return new FunctionBodyNode(globalData, children, varStack, funcStack, SourceCode(), features, numConstants);
+ return new FunctionBodyNode(globalData);
}
FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
@@ -1774,51 +2609,55 @@ FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceEleme
return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
}
-void FunctionBodyNode::generateCode(ScopeChainNode* scopeChainNode)
+void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
{
+ // This branch is only necessary since you can still create a non-stub FunctionBodyNode by
+ // calling Parser::parse<FunctionBodyNode>().
+ if (!data())
+ scopeChainNode->globalData->parser->reparseInPlace(scopeChainNode->globalData, this);
+ ASSERT(data());
+
ScopeChain scopeChain(scopeChainNode);
JSGlobalObject* globalObject = scopeChain.globalObject();
m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
- CodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_symbolTable, m_code.get());
+ BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
generator.generate();
-}
-RegisterID* FunctionBodyNode::emitCode(CodeGenerator& generator, RegisterID*)
-{
- generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
- statementListEmitCode(m_children, generator, ignoredResult());
- if (!m_children.size() || !m_children.last()->isReturnNode()) {
- RegisterID* r0 = generator.emitLoad(0, jsUndefined());
- generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
- generator.emitReturn(r0);
- }
- return 0;
+ destroyData();
}
-RegisterID* ProgramNode::emitCode(CodeGenerator& generator, RegisterID*)
+CodeBlock& FunctionBodyNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom)
{
- generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
+ ASSERT(!m_code);
- RefPtr<RegisterID> dstRegister = generator.newTemporary();
- generator.emitLoad(dstRegister.get(), jsUndefined());
- statementListEmitCode(m_children, generator, dstRegister.get());
+ ScopeChain scopeChain(scopeChainNode);
+ JSGlobalObject* globalObject = scopeChain.globalObject();
- generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
- generator.emitEnd(dstRegister.get());
- return 0;
+ m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
+
+ BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
+ generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
+ generator.generate();
+
+ return *m_code;
}
-void ProgramNode::generateCode(ScopeChainNode* scopeChainNode)
+RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- ScopeChain scopeChain(scopeChainNode);
- JSGlobalObject* globalObject = scopeChain.globalObject();
-
- m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
-
- CodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get(), m_varStack, m_functionStack);
- generator.generate();
+ generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
+ statementListEmitCode(children(), generator, generator.ignoredResult());
+ if (children().size() && children().last()->isBlock()) {
+ BlockNode* blockNode = static_cast<BlockNode*>(children().last().get());
+ if (blockNode->children().size() && blockNode->children().last()->isReturnNode())
+ return 0;
+ }
+
+ RegisterID* r0 = generator.emitLoad(0, jsUndefined());
+ generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
+ generator.emitReturn(r0);
+ return 0;
}
UString FunctionBodyNode::paramString() const
@@ -1842,19 +2681,43 @@ Identifier* FunctionBodyNode::copyParameters()
// ------------------------------ FuncDeclNode ---------------------------------
+FuncDeclNode::~FuncDeclNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void FuncDeclNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_parameter);
+ releaser.release(m_body);
+}
+
JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
{
return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
}
-RegisterID* FuncDeclNode::emitCode(CodeGenerator&, RegisterID* dst)
+RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ if (dst == generator.ignoredResult())
+ dst = 0;
return dst;
}
// ------------------------------ FuncExprNode ---------------------------------
-RegisterID* FuncExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+FuncExprNode::~FuncExprNode()
+{
+ NodeReleaser::releaseAllNodes(this);
+}
+
+void FuncExprNode::releaseNodes(NodeReleaser& releaser)
+{
+ releaser.release(m_parameter);
+ releaser.release(m_body);
+}
+
+RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
}
@@ -1879,4 +2742,25 @@ JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeCha
return func;
}
+#ifdef ANDROID_INSTRUMENT
+static size_t nodesSize = 0;
+
+void* Node::operator new(size_t s) throw()
+{
+ nodesSize += s;
+ return ::operator new(s);
+}
+
+void Node::operator delete(void* ptr, size_t s)
+{
+ nodesSize -= s;
+ ::operator delete(ptr);
+}
+
+size_t Node::reportJavaScriptNodesSize()
+{
+ return nodesSize;
+}
+#endif
+
} // namespace JSC
diff --git a/JavaScriptCore/kjs/nodes.h b/JavaScriptCore/parser/Nodes.h
index a70d350..baa9984 100644
--- a/JavaScriptCore/kjs/nodes.h
+++ b/JavaScriptCore/parser/Nodes.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -27,18 +27,12 @@
#define NODES_H_
#include "Error.h"
-#include "JSString.h"
-#include "JSType.h"
#include "Opcode.h"
-#include "RegisterID.h"
#include "ResultType.h"
#include "SourceCode.h"
#include "SymbolTable.h"
-#include "regexp.h"
-#include <wtf/ListRefPtr.h>
#include <wtf/MathExtras.h>
#include <wtf/OwnPtr.h>
-#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
#if PLATFORM(X86) && COMPILER(GCC)
@@ -50,16 +44,17 @@
namespace JSC {
class CodeBlock;
- class CodeGenerator;
+ class BytecodeGenerator;
class FuncDeclNode;
- class Node;
class EvalCodeBlock;
class JSFunction;
+ class NodeReleaser;
class ProgramCodeBlock;
class PropertyListNode;
- class SourceStream;
+ class RegisterID;
+ class ScopeChainNode;
- typedef unsigned int CodeFeatures;
+ typedef unsigned CodeFeatures;
const CodeFeatures NoFeatures = 0;
const CodeFeatures EvalFeature = 1 << 0;
@@ -93,38 +88,15 @@ namespace JSC {
OpLogicalOr
};
- enum Precedence {
- PrecPrimary,
- PrecMember,
- PrecCall,
- PrecLeftHandSide,
- PrecPostfix,
- PrecUnary,
- PrecMultiplicative,
- PrecAdditive,
- PrecShift,
- PrecRelational,
- PrecEquality,
- PrecBitwiseAnd,
- PrecBitwiseXor,
- PrecBitwiseOr,
- PrecLogicalAnd,
- PrecLogicalOr,
- PrecConditional,
- PrecAssignment,
- PrecExpression
- };
-
namespace DeclarationStacks {
- typedef Vector<Node*, 16> NodeStack;
enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
- typedef Vector<std::pair<Identifier, unsigned>, 16> VarStack;
- typedef Vector<RefPtr<FuncDeclNode>, 16> FunctionStack;
+ typedef Vector<std::pair<Identifier, unsigned> > VarStack;
+ typedef Vector<RefPtr<FuncDeclNode> > FunctionStack;
}
struct SwitchInfo {
enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString };
- uint32_t opcodeOffset;
+ uint32_t bytecodeOffset;
SwitchType switchType;
};
@@ -132,24 +104,24 @@ namespace JSC {
protected:
ParserRefCounted(JSGlobalData*) JSC_FAST_CALL;
- JSGlobalData* m_globalData;
-
public:
+ virtual ~ParserRefCounted();
+
+ // Nonrecursive destruction.
+ virtual void releaseNodes(NodeReleaser&);
+
void ref() JSC_FAST_CALL;
void deref() JSC_FAST_CALL;
bool hasOneRef() JSC_FAST_CALL;
static void deleteNewObjects(JSGlobalData*) JSC_FAST_CALL;
- virtual ~ParserRefCounted();
+ private:
+ JSGlobalData* m_globalData;
};
class Node : public ParserRefCounted {
public:
- typedef DeclarationStacks::NodeStack NodeStack;
- typedef DeclarationStacks::VarStack VarStack;
- typedef DeclarationStacks::FunctionStack FunctionStack;
-
Node(JSGlobalData*) JSC_FAST_CALL;
/*
@@ -174,30 +146,27 @@ namespace JSC {
because the assignment node, "x =", passes r[x] as dst to the number
node, "1".
*/
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL
- {
- ASSERT_WITH_MESSAGE(0, "Don't know how to generate code for:\n%s\n", toString().ascii());
- UNUSED_PARAM(dst);
- return 0;
- } // FIXME: Make this pure virtual.
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL = 0;
- UString toString() const JSC_FAST_CALL;
int lineNo() const { return m_line; }
- virtual bool isReturnNode() const JSC_FAST_CALL { return false; }
+#ifdef ANDROID_INSTRUMENT
+ // Overridden to prevent the normal new from being called.
+ void* operator new(size_t) throw();
+
+ // Overridden to prevent the normal delete from being called.
+ void operator delete(void*, size_t);
+
+ static size_t reportJavaScriptNodesSize();
+#endif
- // Serialization.
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL = 0;
- virtual Precedence precedence() const = 0;
- virtual bool needsParensIfLeftmost() const { return false; }
-
protected:
int m_line;
};
class ExpressionNode : public Node {
public:
- ExpressionNode(JSGlobalData* globalData, ResultType resultDesc = ResultType::unknown()) JSC_FAST_CALL
+ ExpressionNode(JSGlobalData* globalData, ResultType resultDesc = ResultType::unknownType()) JSC_FAST_CALL
: Node(globalData)
, m_resultDesc(resultDesc)
{
@@ -206,11 +175,12 @@ namespace JSC {
virtual bool isNumber() const JSC_FAST_CALL { return false; }
virtual bool isString() const JSC_FAST_CALL { return false; }
virtual bool isNull() const JSC_FAST_CALL { return false; }
- virtual bool isPure(CodeGenerator&) const JSC_FAST_CALL { return false; }
+ virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return false; }
virtual bool isLocation() const JSC_FAST_CALL { return false; }
virtual bool isResolveNode() const JSC_FAST_CALL { return false; }
virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return false; }
virtual bool isDotAccessorNode() const JSC_FAST_CALL { return false; }
+ virtual bool isFuncExprNode() const JSC_FAST_CALL { return false; }
virtual ExpressionNode* stripUnaryPlus() { return this; }
@@ -230,8 +200,9 @@ namespace JSC {
int firstLine() const JSC_FAST_CALL { return lineNo(); }
int lastLine() const JSC_FAST_CALL { return m_lastLine; }
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
virtual bool isEmptyStatement() const JSC_FAST_CALL { return false; }
+ virtual bool isReturnNode() const JSC_FAST_CALL { return false; }
+ virtual bool isExprStatement() const JSC_FAST_CALL { return false; }
virtual bool isBlock() const JSC_FAST_CALL { return false; }
virtual bool isLoop() const JSC_FAST_CALL { return false; }
@@ -249,82 +220,57 @@ namespace JSC {
virtual bool isNull() const JSC_FAST_CALL { return true; }
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPrimary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
};
class BooleanNode : public ExpressionNode {
public:
BooleanNode(JSGlobalData* globalData, bool value) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::boolean())
+ : ExpressionNode(globalData, ResultType::booleanType())
, m_value(value)
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual bool isPure(CodeGenerator&) const JSC_FAST_CALL { return true; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPrimary; }
+ virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
- protected:
+ private:
bool m_value;
};
class NumberNode : public ExpressionNode {
public:
NumberNode(JSGlobalData* globalData, double v) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::constNumber())
+ : ExpressionNode(globalData, ResultType::numberType())
, m_double(v)
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
virtual bool isNumber() const JSC_FAST_CALL { return true; }
- virtual bool isPure(CodeGenerator&) const JSC_FAST_CALL { return true; }
+ virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
double value() const JSC_FAST_CALL { return m_double; }
- virtual void setValue(double d) JSC_FAST_CALL { m_double = d; }
-
- protected:
- double m_double;
- };
-
- class ImmediateNumberNode : public NumberNode {
- public:
- ImmediateNumberNode(JSGlobalData* globalData, JSValue* v, double d) JSC_FAST_CALL
- : NumberNode(globalData, d)
- , m_value(v)
- {
- ASSERT(v == JSImmediate::from(d));
- }
-
- virtual void setValue(double d) JSC_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
+ void setValue(double d) JSC_FAST_CALL { m_double = d; }
private:
- JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr
+ double m_double;
};
class StringNode : public ExpressionNode {
public:
StringNode(JSGlobalData* globalData, const Identifier& v) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::string())
+ : ExpressionNode(globalData, ResultType::stringType())
, m_value(v)
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
virtual bool isString() const JSC_FAST_CALL { return true; }
const Identifier& value() { return m_value; }
- virtual bool isPure(CodeGenerator&) const JSC_FAST_CALL { return true; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPrimary; }
+ virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
private:
Identifier m_value;
@@ -358,8 +304,10 @@ namespace JSC {
uint16_t endOffset() const { return m_endOffset; }
protected:
- RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg);
- RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg, const Identifier&);
+ RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg);
+ RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const Identifier&);
+
+ private:
uint32_t m_divot;
uint16_t m_startOffset;
uint16_t m_endOffset;
@@ -381,11 +329,12 @@ namespace JSC {
{
}
- void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) {
- ASSERT(subexpressionDivot <= m_divot);
- if ((m_divot - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+ void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+ {
+ ASSERT(subexpressionDivot <= divot());
+ if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
return;
- m_subexpressionDivotOffset = m_divot - subexpressionDivot;
+ m_subexpressionDivotOffset = divot() - subexpressionDivot;
m_subexpressionEndOffset = subexpressionOffset;
}
@@ -410,11 +359,12 @@ namespace JSC {
{
}
- void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) {
- ASSERT(subexpressionDivot >= m_divot);
- if ((subexpressionDivot - m_divot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+ void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+ {
+ ASSERT(subexpressionDivot >= divot());
+ if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
return;
- m_subexpressionDivotOffset = subexpressionDivot - m_divot;
+ m_subexpressionDivotOffset = subexpressionDivot - divot();
m_subexpressionStartOffset = subexpressionOffset;
}
@@ -432,10 +382,7 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPrimary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
UString m_pattern;
@@ -449,10 +396,7 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPrimary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
};
class ResolveNode : public ExpressionNode {
@@ -464,50 +408,45 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPrimary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual bool isPure(CodeGenerator&) const JSC_FAST_CALL;
+ virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL;
virtual bool isLocation() const JSC_FAST_CALL { return true; }
virtual bool isResolveNode() const JSC_FAST_CALL { return true; }
const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
- protected:
+ private:
Identifier m_ident;
int32_t m_startOffset;
-
};
- class ElementNode : public Node {
+ class ElementNode : public ParserRefCounted {
public:
ElementNode(JSGlobalData* globalData, int elision, ExpressionNode* node) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_elision(elision)
, m_node(node)
{
}
ElementNode(JSGlobalData* globalData, ElementNode* l, int elision, ExpressionNode* node) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_elision(elision)
, m_node(node)
{
l->m_next = this;
}
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~ElementNode();
+ virtual void releaseNodes(NodeReleaser&);
int elision() const { return m_elision; }
ExpressionNode* value() { return m_node.get(); }
ElementNode* next() { return m_next.get(); }
- PassRefPtr<ElementNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
private:
- ListRefPtr<ElementNode> m_next;
+ RefPtr<ElementNode> m_next;
int m_elision;
RefPtr<ExpressionNode> m_node;
};
@@ -537,10 +476,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~ArrayNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPrimary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ElementNode> m_element;
@@ -548,20 +487,20 @@ namespace JSC {
bool m_optional;
};
- class PropertyNode : public Node {
+ class PropertyNode : public ParserRefCounted {
public:
enum Type { Constant, Getter, Setter };
PropertyNode(JSGlobalData* globalData, const Identifier& name, ExpressionNode* assign, Type type) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_name(name)
, m_assign(assign)
, m_type(type)
{
}
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
+ virtual ~PropertyNode();
+ virtual void releaseNodes(NodeReleaser&);
const Identifier& name() const { return m_name; }
@@ -587,16 +526,14 @@ namespace JSC {
list->m_next = this;
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
+ virtual ~PropertyListNode();
+ virtual void releaseNodes(NodeReleaser&);
- PassRefPtr<PropertyListNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
- friend class ObjectLiteralNode;
RefPtr<PropertyNode> m_node;
- ListRefPtr<PropertyListNode> m_next;
+ RefPtr<PropertyListNode> m_next;
};
class ObjectLiteralNode : public ExpressionNode {
@@ -612,10 +549,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPrimary; }
- virtual bool needsParensIfLeftmost() const { return true; }
+ virtual ~ObjectLiteralNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<PropertyListNode> m_list;
@@ -631,10 +568,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~BracketAccessorNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecMember; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
virtual bool isLocation() const JSC_FAST_CALL { return true; }
virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return true; }
@@ -656,9 +593,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecMember; }
+ virtual ~DotAccessorNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
virtual bool isLocation() const JSC_FAST_CALL { return true; }
virtual bool isDotAccessorNode() const JSC_FAST_CALL { return true; }
@@ -685,31 +623,30 @@ namespace JSC {
listNode->m_next = this;
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
+ virtual ~ArgumentListNode();
+ virtual void releaseNodes(NodeReleaser&);
- PassRefPtr<ArgumentListNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- ListRefPtr<ArgumentListNode> m_next;
+ RefPtr<ArgumentListNode> m_next;
RefPtr<ExpressionNode> m_expr;
};
- class ArgumentsNode : public Node {
+ class ArgumentsNode : public ParserRefCounted {
public:
ArgumentsNode(JSGlobalData* globalData) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
{
}
ArgumentsNode(JSGlobalData* globalData, ArgumentListNode* listNode) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_listNode(listNode)
{
}
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
+ virtual ~ArgumentsNode();
+ virtual void releaseNodes(NodeReleaser&);
RefPtr<ArgumentListNode> m_listNode;
};
@@ -729,10 +666,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~NewExprNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecLeftHandSide; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
@@ -748,9 +685,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecCall; }
+ virtual ~EvalFunctionCallNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ArgumentsNode> m_args;
@@ -766,9 +704,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecCall; }
+ virtual ~FunctionCallValueNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
@@ -785,12 +724,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~FunctionCallResolveNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecCall; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- protected:
+ private:
Identifier m_ident;
RefPtr<ArgumentsNode> m_args;
size_t m_index; // Used by LocalVarFunctionCallNode.
@@ -808,11 +747,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecCall; }
+ virtual ~FunctionCallBracketNode();
+ virtual void releaseNodes(NodeReleaser&);
- protected:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+
+ private:
RefPtr<ExpressionNode> m_base;
RefPtr<ExpressionNode> m_subscript;
RefPtr<ArgumentsNode> m_args;
@@ -829,9 +769,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecCall; }
+ virtual ~FunctionCallDotNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_base;
@@ -842,7 +783,7 @@ namespace JSC {
class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
PrePostResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::constNumber()) // could be reusable for pre?
+ : ExpressionNode(globalData, ResultType::numberType()) // could be reusable for pre?
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_ident(ident)
{
@@ -860,11 +801,9 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPostfix; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- protected:
+ private:
Operator m_operator;
};
@@ -879,11 +818,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPostfix; }
+ virtual ~PostfixBracketNode();
+ virtual void releaseNodes(NodeReleaser&);
- protected:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+
+ private:
RefPtr<ExpressionNode> m_base;
RefPtr<ExpressionNode> m_subscript;
Operator m_operator;
@@ -900,11 +840,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPostfix; }
+ virtual ~PostfixDotNode();
+ virtual void releaseNodes(NodeReleaser&);
- protected:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+
+ private:
RefPtr<ExpressionNode> m_base;
Identifier m_ident;
Operator m_operator;
@@ -920,9 +861,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPostfix; }
+ virtual ~PostfixErrorNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
@@ -938,10 +880,7 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
Identifier m_ident;
@@ -957,10 +896,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~DeleteBracketNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_base;
@@ -977,10 +916,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~DeleteDotNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_base;
@@ -995,10 +934,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~DeleteValueNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
@@ -1012,10 +951,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~VoidNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
@@ -1024,35 +963,31 @@ namespace JSC {
class TypeOfResolveNode : public ExpressionNode {
public:
TypeOfResolveNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::string())
+ : ExpressionNode(globalData, ResultType::stringType())
, m_ident(ident)
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
- protected:
+ private:
Identifier m_ident;
- size_t m_index; // Used by LocalTypeOfNode.
};
class TypeOfValueNode : public ExpressionNode {
public:
TypeOfValueNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::string())
+ : ExpressionNode(globalData, ResultType::stringType())
, m_expr(expr)
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~TypeOfValueNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
@@ -1066,12 +1001,9 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- protected:
+ private:
Operator m_operator;
};
@@ -1086,11 +1018,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual ~PrefixBracketNode();
+ virtual void releaseNodes(NodeReleaser&);
- protected:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+
+ private:
RefPtr<ExpressionNode> m_base;
RefPtr<ExpressionNode> m_subscript;
Operator m_operator;
@@ -1107,11 +1040,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecPostfix; }
+ virtual ~PrefixDotNode();
+ virtual void releaseNodes(NodeReleaser&);
- protected:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+
+ private:
RefPtr<ExpressionNode> m_base;
Identifier m_ident;
Operator m_operator;
@@ -1127,9 +1061,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual ~PrefixErrorNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
@@ -1150,8 +1085,11 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual OpcodeID opcode() const JSC_FAST_CALL = 0;
+ virtual ~UnaryOpNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL = 0;
protected:
RefPtr<ExpressionNode> m_expr;
@@ -1160,51 +1098,43 @@ namespace JSC {
class UnaryPlusNode : public UnaryOpNode {
public:
UnaryPlusNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : UnaryOpNode(globalData, ResultType::constNumber(), expr)
+ : UnaryOpNode(globalData, ResultType::numberType(), expr)
{
}
virtual ExpressionNode* stripUnaryPlus() { return m_expr.get(); }
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_to_jsnumber; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_to_jsnumber; }
};
class NegateNode : public UnaryOpNode {
public:
NegateNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : UnaryOpNode(globalData, ResultType::reusableNumber(), expr)
+ : UnaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_negate; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_negate; }
};
class BitwiseNotNode : public UnaryOpNode {
public:
BitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : UnaryOpNode(globalData, ResultType::reusableNumber(), expr)
+ : UnaryOpNode(globalData, ResultType::forBitOp(), expr)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_bitnot; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitnot; }
};
class LogicalNotNode : public UnaryOpNode {
public:
LogicalNotNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : UnaryOpNode(globalData, ResultType::boolean(), expr)
+ : UnaryOpNode(globalData, ResultType::booleanType(), expr)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_not; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecUnary; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_not; }
};
class BinaryOpNode : public ExpressionNode {
@@ -1225,8 +1155,11 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual OpcodeID opcode() const JSC_FAST_CALL = 0;
+ virtual ~BinaryOpNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL = 0;
protected:
RefPtr<ExpressionNode> m_expr1;
@@ -1234,67 +1167,49 @@ namespace JSC {
bool m_rightHasAssignments;
};
- class ReverseBinaryOpNode : public ExpressionNode {
+ class ReverseBinaryOpNode : public BinaryOpNode {
public:
ReverseBinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : ExpressionNode(globalData)
- , m_expr1(expr1)
- , m_expr2(expr2)
- , m_rightHasAssignments(rightHasAssignments)
+ : BinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
{
}
ReverseBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : ExpressionNode(globalData, type)
- , m_expr1(expr1)
- , m_expr2(expr2)
- , m_rightHasAssignments(rightHasAssignments)
+ : BinaryOpNode(globalData, type, expr1, expr2, rightHasAssignments)
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual OpcodeID opcode() const JSC_FAST_CALL = 0;
-
- protected:
- RefPtr<ExpressionNode> m_expr1;
- RefPtr<ExpressionNode> m_expr2;
- bool m_rightHasAssignments;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
};
class MultNode : public BinaryOpNode {
public:
MultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_mul; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecMultiplicative; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_mul; }
};
class DivNode : public BinaryOpNode {
public:
DivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_div; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecMultiplicative; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_div; }
};
class ModNode : public BinaryOpNode {
public:
ModNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_mod; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecMultiplicative; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_mod; }
};
class AddNode : public BinaryOpNode {
@@ -1304,105 +1219,87 @@ namespace JSC {
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_add; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecAdditive; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_add; }
};
class SubNode : public BinaryOpNode {
public:
SubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_sub; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecAdditive; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_sub; }
};
class LeftShiftNode : public BinaryOpNode {
public:
LeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_lshift; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecShift; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_lshift; }
};
class RightShiftNode : public BinaryOpNode {
public:
RightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_rshift; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecShift; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_rshift; }
};
class UnsignedRightShiftNode : public BinaryOpNode {
public:
UnsignedRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_urshift; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecShift; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_urshift; }
};
class LessNode : public BinaryOpNode {
public:
LessNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_less; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecRelational; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_less; }
};
class GreaterNode : public ReverseBinaryOpNode {
public:
GreaterNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : ReverseBinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
+ : ReverseBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_less; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecRelational; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_less; }
};
class LessEqNode : public BinaryOpNode {
public:
LessEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_lesseq; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecRelational; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_lesseq; }
};
class GreaterEqNode : public ReverseBinaryOpNode {
public:
GreaterEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : ReverseBinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
+ : ReverseBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_lesseq; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecRelational; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_lesseq; }
};
class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
@@ -1415,21 +1312,19 @@ namespace JSC {
: BinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
};
class InstanceOfNode : public ThrowableBinaryOpNode {
public:
InstanceOfNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : ThrowableBinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
+ : ThrowableBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_instanceof; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecRelational; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_instanceof; }
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
};
class InNode : public ThrowableBinaryOpNode {
@@ -1439,95 +1334,79 @@ namespace JSC {
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_in; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecRelational; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_in; }
};
class EqualNode : public BinaryOpNode {
public:
EqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_eq; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecEquality; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_eq; }
};
class NotEqualNode : public BinaryOpNode {
public:
NotEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_neq; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecEquality; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_neq; }
};
class StrictEqualNode : public BinaryOpNode {
public:
StrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_stricteq; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecEquality; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_stricteq; }
};
class NotStrictEqualNode : public BinaryOpNode {
public:
NotStrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::boolean(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_nstricteq; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecEquality; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_nstricteq; }
};
class BitAndNode : public BinaryOpNode {
public:
BitAndNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_bitand; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecBitwiseAnd; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitand; }
};
class BitOrNode : public BinaryOpNode {
public:
BitOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_bitor; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecBitwiseOr; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitor; }
};
class BitXOrNode : public BinaryOpNode {
public:
BitXOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
- : BinaryOpNode(globalData, ResultType::reusableNumber(), expr1, expr2, rightHasAssignments)
+ : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
{
}
- virtual OpcodeID opcode() const JSC_FAST_CALL { return op_bitxor; }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecBitwiseXor; }
+ virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitxor; }
};
/**
@@ -1536,16 +1415,17 @@ namespace JSC {
class LogicalOpNode : public ExpressionNode {
public:
LogicalOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator oper) JSC_FAST_CALL
- : ExpressionNode(globalData, ResultType::boolean())
+ : ExpressionNode(globalData, ResultType::booleanType())
, m_expr1(expr1)
, m_expr2(expr2)
, m_operator(oper)
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return (m_operator == OpLogicalAnd) ? PrecLogicalAnd : PrecLogicalOr; }
+ virtual ~LogicalOpNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr1;
@@ -1566,9 +1446,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecConditional; }
+ virtual ~ConditionalNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_logical;
@@ -1588,12 +1469,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~ReadModifyResolveNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecAssignment; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- protected:
+ private:
Identifier m_ident;
RefPtr<ExpressionNode> m_right;
size_t m_index; // Used by ReadModifyLocalVarNode.
@@ -1611,12 +1492,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~AssignResolveNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecAssignment; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- protected:
+ private:
Identifier m_ident;
RefPtr<ExpressionNode> m_right;
size_t m_index; // Used by ReadModifyLocalVarNode.
@@ -1637,12 +1518,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~ReadModifyBracketNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecAssignment; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- protected:
+ private:
RefPtr<ExpressionNode> m_base;
RefPtr<ExpressionNode> m_subscript;
RefPtr<ExpressionNode> m_right;
@@ -1664,12 +1545,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~AssignBracketNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecAssignment; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- protected:
+ private:
RefPtr<ExpressionNode> m_base;
RefPtr<ExpressionNode> m_subscript;
RefPtr<ExpressionNode> m_right;
@@ -1689,11 +1570,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecAssignment; }
+ virtual ~AssignDotNode();
+ virtual void releaseNodes(NodeReleaser&);
- protected:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+
+ private:
RefPtr<ExpressionNode> m_base;
Identifier m_ident;
RefPtr<ExpressionNode> m_right;
@@ -1713,12 +1595,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~ReadModifyDotNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecAssignment; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- protected:
+ private:
RefPtr<ExpressionNode> m_base;
Identifier m_ident;
RefPtr<ExpressionNode> m_right;
@@ -1737,11 +1619,12 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecAssignment; }
+ virtual ~AssignErrorNode();
+ virtual void releaseNodes(NodeReleaser&);
- protected:
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+
+ private:
RefPtr<ExpressionNode> m_left;
Operator m_operator;
RefPtr<ExpressionNode> m_right;
@@ -1756,9 +1639,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecExpression; }
+ virtual ~CommaNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr1;
@@ -1771,23 +1655,21 @@ namespace JSC {
: CommaNode(globalData, expr1, expr2)
{
}
- virtual Precedence precedence() const { return PrecAssignment; }
};
class ConstDeclNode : public ExpressionNode {
public:
ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
- PassRefPtr<ConstDeclNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
+ virtual ~ConstDeclNode();
+ virtual void releaseNodes(NodeReleaser&);
Identifier m_ident;
- ListRefPtr<ConstDeclNode> m_next;
+ RefPtr<ConstDeclNode> m_next;
RefPtr<ExpressionNode> m_init;
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual RegisterID* emitCodeSingle(CodeGenerator&) JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual RegisterID* emitCodeSingle(BytecodeGenerator&) JSC_FAST_CALL;
};
class ConstStatementNode : public StatementNode {
@@ -1798,9 +1680,10 @@ namespace JSC {
{
}
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
-
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~ConstStatementNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ConstDeclNode> m_next;
@@ -1817,6 +1700,7 @@ namespace JSC {
{
ASSERT(destination.isEmpty());
m_statements.swap(destination);
+ destination.shrinkToFit();
}
private:
@@ -1827,13 +1711,16 @@ namespace JSC {
public:
BlockNode(JSGlobalData*, SourceElements* children) JSC_FAST_CALL;
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~BlockNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
StatementVector& children() { return m_children; }
virtual bool isBlock() const JSC_FAST_CALL { return true; }
- protected:
+
+ private:
StatementVector m_children;
};
@@ -1844,9 +1731,8 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
virtual bool isEmptyStatement() const JSC_FAST_CALL { return true; }
};
@@ -1857,9 +1743,7 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
};
class ExprStatementNode : public StatementNode {
@@ -1870,8 +1754,11 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual bool isExprStatement() const JSC_FAST_CALL { return true; }
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+
+ ExpressionNode* expr() const { return m_expr.get(); }
private:
RefPtr<ExpressionNode> m_expr;
@@ -1885,9 +1772,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~VarStatementNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
@@ -1902,8 +1790,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~IfNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
protected:
RefPtr<ExpressionNode> m_condition;
@@ -1918,8 +1808,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~IfElseNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<StatementNode> m_elseBlock;
@@ -1934,10 +1826,13 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~DoWhileNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
virtual bool isLoop() const JSC_FAST_CALL { return true; }
+
private:
RefPtr<StatementNode> m_statement;
RefPtr<ExpressionNode> m_expr;
@@ -1952,10 +1847,13 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~WhileNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
virtual bool isLoop() const JSC_FAST_CALL { return true; }
+
private:
RefPtr<ExpressionNode> m_expr;
RefPtr<StatementNode> m_statement;
@@ -1974,10 +1872,13 @@ namespace JSC {
ASSERT(statement);
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~ForNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
virtual bool isLoop() const JSC_FAST_CALL { return true; }
+
private:
RefPtr<ExpressionNode> m_expr1;
RefPtr<ExpressionNode> m_expr2;
@@ -1991,10 +1892,13 @@ namespace JSC {
ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*) JSC_FAST_CALL;
ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset) JSC_FAST_CALL;
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~ForInNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
virtual bool isLoop() const JSC_FAST_CALL { return true; }
+
private:
Identifier m_ident;
RefPtr<ExpressionNode> m_init;
@@ -2017,8 +1921,7 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
Identifier m_ident;
@@ -2037,8 +1940,7 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
Identifier m_ident;
@@ -2052,8 +1954,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~ReturnNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
virtual bool isReturnNode() const JSC_FAST_CALL { return true; }
private:
@@ -2071,8 +1975,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~WithNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
@@ -2090,8 +1996,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~LabelNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
Identifier m_name;
@@ -2106,8 +2014,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~ThrowNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
@@ -2115,111 +2025,136 @@ namespace JSC {
class TryNode : public StatementNode {
public:
- TryNode(JSGlobalData* globalData, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock) JSC_FAST_CALL
+ TryNode(JSGlobalData* globalData, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock) JSC_FAST_CALL
: StatementNode(globalData)
, m_tryBlock(tryBlock)
, m_exceptionIdent(exceptionIdent)
, m_catchBlock(catchBlock)
, m_finallyBlock(finallyBlock)
+ , m_catchHasEval(catchHasEval)
{
}
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual ~TryNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL;
private:
RefPtr<StatementNode> m_tryBlock;
Identifier m_exceptionIdent;
RefPtr<StatementNode> m_catchBlock;
RefPtr<StatementNode> m_finallyBlock;
+ bool m_catchHasEval;
};
- class ParameterNode : public Node {
+ class ParameterNode : public ParserRefCounted {
public:
ParameterNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_ident(ident)
{
}
ParameterNode(JSGlobalData* globalData, ParameterNode* l, const Identifier& ident) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_ident(ident)
{
l->m_next = this;
}
- Identifier ident() JSC_FAST_CALL { return m_ident; }
- ParameterNode *nextParam() JSC_FAST_CALL { return m_next.get(); }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- PassRefPtr<ParameterNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
+ virtual ~ParameterNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ const Identifier& ident() const JSC_FAST_CALL { return m_ident; }
+ ParameterNode* nextParam() const JSC_FAST_CALL { return m_next.get(); }
private:
- friend class FuncDeclNode;
- friend class FuncExprNode;
Identifier m_ident;
- ListRefPtr<ParameterNode> m_next;
+ RefPtr<ParameterNode> m_next;
+ };
+
+ struct ScopeNodeData {
+ typedef DeclarationStacks::VarStack VarStack;
+ typedef DeclarationStacks::FunctionStack FunctionStack;
+
+ ScopeNodeData(SourceElements*, VarStack*, FunctionStack*, int numConstants);
+
+ VarStack m_varStack;
+ FunctionStack m_functionStack;
+ int m_numConstants;
+ StatementVector m_children;
+
+ void mark();
};
- class ScopeNode : public BlockNode {
+ class ScopeNode : public StatementNode {
public:
+ typedef DeclarationStacks::VarStack VarStack;
+ typedef DeclarationStacks::FunctionStack FunctionStack;
+
+ ScopeNode(JSGlobalData*) JSC_FAST_CALL;
ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL;
+ virtual ~ScopeNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ void adoptData(std::auto_ptr<ScopeNodeData> data) { m_data.adopt(data); }
+ ScopeNodeData* data() const { return m_data.get(); }
+ void destroyData() { m_data.clear(); }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
-
const SourceCode& source() const { return m_source; }
const UString& sourceURL() const JSC_FAST_CALL { return m_source.provider()->url(); }
intptr_t sourceID() const { return m_source.provider()->asID(); }
+ void setFeatures(CodeFeatures features) { m_features = features; }
+ CodeFeatures features() { return m_features; }
+
bool usesEval() const { return m_features & EvalFeature; }
bool usesArguments() const { return m_features & ArgumentsFeature; }
void setUsesArguments() { m_features |= ArgumentsFeature; }
bool usesThis() const { return m_features & ThisFeature; }
bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
- VarStack& varStack() { return m_varStack; }
- FunctionStack& functionStack() { return m_functionStack; }
+ VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
+ FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
+
+ StatementVector& children() { ASSERT(m_data); return m_data->m_children; }
int neededConstants()
{
- // We may need 1 more constant than the count given by the parser,
- // because of the various uses of jsUndefined().
- return m_numConstants + 1;
+ ASSERT(m_data);
+ // We may need 2 more constants than the count given by the parser,
+ // because of the various uses of jsUndefined() and jsNull().
+ return m_data->m_numConstants + 2;
}
+ virtual void mark() { }
+
protected:
void setSource(const SourceCode& source) { m_source = source; }
- VarStack m_varStack;
- FunctionStack m_functionStack;
-
private:
- SourceCode m_source;
+ OwnPtr<ScopeNodeData> m_data;
CodeFeatures m_features;
- int m_numConstants;
+ SourceCode m_source;
};
class ProgramNode : public ScopeNode {
public:
static ProgramNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
- ProgramCodeBlock& byteCode(ScopeChainNode* scopeChain) JSC_FAST_CALL
+ ProgramCodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
{
if (!m_code)
- generateCode(scopeChain);
+ generateBytecode(scopeChain);
return *m_code;
}
private:
ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
- void generateCode(ScopeChainNode*) JSC_FAST_CALL;
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.)
- Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.)
+ void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
OwnPtr<ProgramCodeBlock> m_code;
};
@@ -2228,46 +2163,49 @@ namespace JSC {
public:
static EvalNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
- EvalCodeBlock& byteCode(ScopeChainNode* scopeChain) JSC_FAST_CALL
+ EvalCodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
{
if (!m_code)
- generateCode(scopeChain);
+ generateBytecode(scopeChain);
return *m_code;
}
+ EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*) JSC_FAST_CALL;
+
+ virtual void mark();
+
private:
EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
- void generateCode(ScopeChainNode*) JSC_FAST_CALL;
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
OwnPtr<EvalCodeBlock> m_code;
};
class FunctionBodyNode : public ScopeNode {
+ friend class JIT;
public:
+ static FunctionBodyNode* create(JSGlobalData*) JSC_FAST_CALL;
static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
- static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL;
- ~FunctionBodyNode();
+ virtual ~FunctionBodyNode();
const Identifier* parameters() const JSC_FAST_CALL { return m_parameters; }
size_t parameterCount() const { return m_parameterCount; }
UString paramString() const JSC_FAST_CALL;
Identifier* copyParameters();
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
- SymbolTable& symbolTable() { return m_symbolTable; } // FIXME: Remove this
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- CodeBlock& byteCode(ScopeChainNode* scopeChain) JSC_FAST_CALL
+ CodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
{
ASSERT(scopeChain);
if (!m_code)
- generateCode(scopeChain);
+ generateBytecode(scopeChain);
return *m_code;
}
- CodeBlock& generatedByteCode() JSC_FAST_CALL
+ CodeBlock& generatedBytecode() JSC_FAST_CALL
{
ASSERT(m_code);
return *m_code;
@@ -2278,12 +2216,12 @@ namespace JSC {
return m_code;
}
- void mark();
+ virtual void mark();
void finishParsing(const SourceCode&, ParameterNode*);
void finishParsing(Identifier* parameters, size_t parameterCount);
- UString toSourceString() const JSC_FAST_CALL { return UString("{") + source().toString() + UString("}"); }
+ UString toSourceString() const JSC_FAST_CALL { return source().toString(); }
// These objects are ref/deref'd a lot in the scope chain, so this is a faster ref/deref.
// If the virtual machine changes so this doesn't happen as much we can change back.
@@ -2299,15 +2237,16 @@ namespace JSC {
ScopeNode::deref();
}
- protected:
- FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+ CodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*) JSC_FAST_CALL;
private:
- void generateCode(ScopeChainNode*) JSC_FAST_CALL;
+ FunctionBodyNode(JSGlobalData*) JSC_FAST_CALL;
+ FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+
+ void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
Identifier* m_parameters;
size_t m_parameterCount;
- SymbolTable m_symbolTable;
OwnPtr<CodeBlock> m_code;
unsigned m_refCount;
};
@@ -2323,17 +2262,17 @@ namespace JSC {
m_body->finishParsing(source, m_parameter.get());
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~FuncExprNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual bool isFuncExprNode() const JSC_FAST_CALL { return true; }
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
JSFunction* makeFunction(ExecState*, ScopeChainNode*) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { return PrecMember; }
- virtual bool needsParensIfLeftmost() const { return true; }
FunctionBodyNode* body() { return m_body.get(); }
private:
- // Used for streamTo
- friend class PropertyNode;
Identifier m_ident;
RefPtr<ParameterNode> m_parameter;
RefPtr<FunctionBodyNode> m_body;
@@ -2350,9 +2289,11 @@ namespace JSC {
m_body->finishParsing(source, m_parameter.get());
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~FuncDeclNode();
+ virtual void releaseNodes(NodeReleaser&);
+
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
JSFunction* makeFunction(ExecState*, ScopeChainNode*) JSC_FAST_CALL;
Identifier m_ident;
@@ -2364,24 +2305,24 @@ namespace JSC {
RefPtr<FunctionBodyNode> m_body;
};
- class CaseClauseNode : public Node {
+ class CaseClauseNode : public ParserRefCounted {
public:
CaseClauseNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_expr(expr)
{
}
CaseClauseNode(JSGlobalData* globalData, ExpressionNode* expr, SourceElements* children) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_expr(expr)
{
if (children)
children->releaseContentsIntoVector(m_children);
}
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
+ virtual ~CaseClauseNode();
+ virtual void releaseNodes(NodeReleaser&);
ExpressionNode* expr() const { return m_expr.get(); }
StatementVector& children() { return m_children; }
@@ -2391,47 +2332,46 @@ namespace JSC {
StatementVector m_children;
};
- class ClauseListNode : public Node {
+ class ClauseListNode : public ParserRefCounted {
public:
ClauseListNode(JSGlobalData* globalData, CaseClauseNode* clause) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_clause(clause)
{
}
ClauseListNode(JSGlobalData* globalData, ClauseListNode* clauseList, CaseClauseNode* clause) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_clause(clause)
{
clauseList->m_next = this;
}
+ virtual ~ClauseListNode();
+ virtual void releaseNodes(NodeReleaser&);
+
CaseClauseNode* getClause() const JSC_FAST_CALL { return m_clause.get(); }
ClauseListNode* getNext() const JSC_FAST_CALL { return m_next.get(); }
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- PassRefPtr<ClauseListNode> releaseNext() JSC_FAST_CALL { return m_next.release(); }
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
private:
- friend class CaseBlockNode;
RefPtr<CaseClauseNode> m_clause;
- ListRefPtr<ClauseListNode> m_next;
+ RefPtr<ClauseListNode> m_next;
};
- class CaseBlockNode : public Node {
+ class CaseBlockNode : public ParserRefCounted {
public:
CaseBlockNode(JSGlobalData* globalData, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) JSC_FAST_CALL
- : Node(globalData)
+ : ParserRefCounted(globalData)
, m_list1(list1)
, m_defaultClause(defaultClause)
, m_list2(list2)
{
}
- RegisterID* emitCodeForBlock(CodeGenerator&, RegisterID* input, RegisterID* dst = 0) JSC_FAST_CALL;
+ virtual ~CaseBlockNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
- virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
+ RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* dst = 0) JSC_FAST_CALL;
private:
SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
@@ -2449,9 +2389,10 @@ namespace JSC {
{
}
- virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+ virtual ~SwitchNode();
+ virtual void releaseNodes(NodeReleaser&);
- virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
private:
RefPtr<ExpressionNode> m_expr;
diff --git a/JavaScriptCore/kjs/Parser.cpp b/JavaScriptCore/parser/Parser.cpp
index 26773e8..886a513 100644
--- a/JavaScriptCore/kjs/Parser.cpp
+++ b/JavaScriptCore/parser/Parser.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,11 +24,16 @@
#include "Parser.h"
#include "Debugger.h"
-#include "lexer.h"
+#include "Lexer.h"
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
+#include <memory>
-extern int kjsyyparse(void*);
+using std::auto_ptr;
+
+#ifndef yyparse
+extern int jscyyparse(void*);
+#endif
namespace JSC {
@@ -50,7 +55,7 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg)
Lexer& lexer = *globalData->lexer;
lexer.setCode(*m_source);
- int parseError = kjsyyparse(globalData);
+ int parseError = jscyyparse(globalData);
bool lexError = lexer.sawError();
lexer.clear();
@@ -63,6 +68,30 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg)
}
}
+void Parser::reparseInPlace(JSGlobalData* globalData, FunctionBodyNode* functionBodyNode)
+{
+ ASSERT(!functionBodyNode->data());
+
+ m_source = &functionBodyNode->source();
+ globalData->lexer->setIsReparsing();
+ parse(globalData, 0, 0);
+ ASSERT(m_sourceElements);
+
+ functionBodyNode->adoptData(std::auto_ptr<ScopeNodeData>(new ScopeNodeData(m_sourceElements.get(),
+ m_varDeclarations ? &m_varDeclarations->data : 0,
+ m_funcDeclarations ? &m_funcDeclarations->data : 0,
+ m_numConstants)));
+ bool usesArguments = functionBodyNode->usesArguments();
+ functionBodyNode->setFeatures(m_features);
+ if (usesArguments && !functionBodyNode->usesArguments())
+ functionBodyNode->setUsesArguments();
+
+ m_source = 0;
+ m_sourceElements = 0;
+ m_varDeclarations = 0;
+ m_funcDeclarations = 0;
+}
+
void Parser::didFinishParsing(SourceElements* sourceElements, ParserRefCountedData<DeclarationStacks::VarStack>* varStack,
ParserRefCountedData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants)
{
diff --git a/JavaScriptCore/kjs/Parser.h b/JavaScriptCore/parser/Parser.h
index c2f55d7..6191ccb 100644
--- a/JavaScriptCore/kjs/Parser.h
+++ b/JavaScriptCore/parser/Parser.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,7 +25,7 @@
#include "SourceProvider.h"
#include "Debugger.h"
-#include "nodes.h"
+#include "Nodes.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
@@ -50,6 +50,8 @@ namespace JSC {
class Parser : Noncopyable {
public:
template <class ParsedNode> PassRefPtr<ParsedNode> parse(ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
+ template <class ParsedNode> PassRefPtr<ParsedNode> reparse(JSGlobalData*, ParsedNode*);
+ void reparseInPlace(JSGlobalData*, FunctionBodyNode*);
void didFinishParsing(SourceElements*, ParserRefCountedData<DeclarationStacks::VarStack>*,
ParserRefCountedData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants);
@@ -92,6 +94,30 @@ namespace JSC {
return result.release();
}
+ template <class ParsedNode> PassRefPtr<ParsedNode> Parser::reparse(JSGlobalData* globalData, ParsedNode* oldParsedNode)
+ {
+ m_source = &oldParsedNode->source();
+ parse(globalData, 0, 0);
+ RefPtr<ParsedNode> result;
+ if (m_sourceElements) {
+ result = ParsedNode::create(globalData,
+ m_sourceElements.get(),
+ m_varDeclarations ? &m_varDeclarations->data : 0,
+ m_funcDeclarations ? &m_funcDeclarations->data : 0,
+ *m_source,
+ oldParsedNode->features(),
+ m_numConstants);
+ result->setLoc(m_source->firstLine(), m_lastLine);
+ }
+
+ m_source = 0;
+ m_sourceElements = 0;
+ m_varDeclarations = 0;
+ m_funcDeclarations = 0;
+
+ return result.release();
+ }
+
} // namespace JSC
#endif // Parser_h
diff --git a/JavaScriptCore/kjs/ResultType.h b/JavaScriptCore/parser/ResultType.h
index f838ce0..3e7fddb 100644
--- a/JavaScriptCore/kjs/ResultType.h
+++ b/JavaScriptCore/parser/ResultType.h
@@ -33,16 +33,16 @@ namespace JSC {
typedef char Type;
static const Type TypeReusable = 1;
+ static const Type TypeInt32 = 2;
- static const Type TypeMaybeNumber = 2;
- static const Type TypeMaybeString = 4;
- static const Type TypeMaybeNull = 8;
- static const Type TypeMaybeBool = 16;
- static const Type TypeMaybeOther = 32;
+ static const Type TypeMaybeNumber = 0x04;
+ static const Type TypeMaybeString = 0x08;
+ static const Type TypeMaybeNull = 0x10;
+ static const Type TypeMaybeBool = 0x20;
+ static const Type TypeMaybeOther = 0x40;
+
+ static const Type TypeBits = TypeMaybeNumber | TypeMaybeString | TypeMaybeNull | TypeMaybeBool | TypeMaybeOther;
- static const Type TypeReusableNumber = 3;
- static const Type TypeStringOrReusableNumber = 4;
-
explicit ResultType(Type type)
: m_type(type)
{
@@ -50,76 +50,81 @@ namespace JSC {
bool isReusable()
{
- return (m_type & TypeReusable);
+ return m_type & TypeReusable;
}
-
- bool isReusableNumber()
+
+ bool isInt32()
{
- return isReusable() && definitelyIsNumber();
+ return m_type & TypeInt32;
}
bool definitelyIsNumber()
{
- return ((m_type & ~TypeReusable) == TypeMaybeNumber);
- }
-
- bool isNotNumber()
- {
- return ((m_type & TypeMaybeNumber) == 0);
+ return (m_type & TypeBits) == TypeMaybeNumber;
}
bool mightBeNumber()
{
- return !isNotNumber();
+ return m_type & TypeMaybeNumber;
}
-
- int toInt()
+
+ bool isNotNumber()
{
- return static_cast<int>(m_type);
+ return !mightBeNumber();
}
-
+
static ResultType nullType()
{
return ResultType(TypeMaybeNull);
}
- static ResultType boolean()
+ static ResultType booleanType()
{
return ResultType(TypeMaybeBool);
}
- static ResultType constNumber()
+ static ResultType numberType()
{
return ResultType(TypeMaybeNumber);
}
- static ResultType reusableNumber()
+ static ResultType numberTypeCanReuse()
{
return ResultType(TypeReusable | TypeMaybeNumber);
}
- static ResultType reusableNumberOrString()
+ static ResultType numberTypeCanReuseIsInt32()
+ {
+ return ResultType(TypeReusable | TypeInt32 | TypeMaybeNumber);
+ }
+
+ static ResultType stringOrNumberTypeCanReuse()
{
return ResultType(TypeReusable | TypeMaybeNumber | TypeMaybeString);
}
- static ResultType string()
+ static ResultType stringType()
{
return ResultType(TypeMaybeString);
}
- static ResultType unknown()
+ static ResultType unknownType()
{
- return ResultType(TypeMaybeNumber | TypeMaybeString | TypeMaybeNull | TypeMaybeBool | TypeMaybeOther);
+ return ResultType(TypeBits);
}
static ResultType forAdd(ResultType op1, ResultType op2)
{
if (op1.definitelyIsNumber() && op2.definitelyIsNumber())
- return reusableNumber();
+ return numberTypeCanReuse();
if (op1.isNotNumber() || op2.isNotNumber())
- return string();
- return reusableNumberOrString();
+ return stringType();
+ return stringOrNumberTypeCanReuse();
+ }
+
+ static ResultType forBitOp()
+ {
+ return numberTypeCanReuseIsInt32();
}
private:
@@ -128,8 +133,11 @@ namespace JSC {
struct OperandTypes
{
- OperandTypes(ResultType first = ResultType::unknown(), ResultType second = ResultType::unknown())
+ OperandTypes(ResultType first = ResultType::unknownType(), ResultType second = ResultType::unknownType())
{
+ // We have to initialize one of the int to ensure that
+ // the entire struct is initialized.
+ m_u.i = 0;
m_u.rds.first = first.m_type;
m_u.rds.second = second.m_type;
}
diff --git a/JavaScriptCore/kjs/SourceCode.h b/JavaScriptCore/parser/SourceCode.h
index 2840161..84360b8 100644
--- a/JavaScriptCore/kjs/SourceCode.h
+++ b/JavaScriptCore/parser/SourceCode.h
@@ -70,6 +70,7 @@ namespace JSC {
SourceProvider* provider() const { return m_provider.get(); }
int firstLine() const { return m_firstLine; }
int startOffset() const { return m_startChar; }
+ int endOffset() const { return m_endChar; }
const UChar* data() const { return m_provider->data() + m_startChar; }
int length() const { return m_endChar - m_startChar; }
diff --git a/JavaScriptCore/kjs/SourceProvider.h b/JavaScriptCore/parser/SourceProvider.h
index 755a10f..07da9e0 100644
--- a/JavaScriptCore/kjs/SourceProvider.h
+++ b/JavaScriptCore/parser/SourceProvider.h
@@ -29,7 +29,7 @@
#ifndef SourceProvider_h
#define SourceProvider_h
-#include "ustring.h"
+#include "UString.h"
#include <wtf/RefCounted.h>
namespace JSC {
diff --git a/JavaScriptCore/pcre/dftables b/JavaScriptCore/pcre/dftables
index 9268f19..de2f5bb 100755
--- a/JavaScriptCore/pcre/dftables
+++ b/JavaScriptCore/pcre/dftables
@@ -8,7 +8,7 @@
#
# Originally written by Philip Hazel
# Copyright (c) 1997-2006 University of Cambridge
-# Copyright (C) 2002, 2004, 2006, 2007, 2008 Apple Inc. All rights reserved.
+# Copyright (C) 2002, 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
#
# -----------------------------------------------------------------------------
# Redistribution and use in source and binary forms, with or without
@@ -84,7 +84,7 @@ printf(OUT
"This file contains the default tables for characters with codes less than\n" .
"128 (ASCII characters). These tables are used when no external tables are\n" .
"passed to PCRE. */\n\n" .
- "const unsigned char kjs_pcre_default_tables[%d] = {\n\n" .
+ "const unsigned char jsc_pcre_default_tables[%d] = {\n\n" .
"/* This table is a lower casing table. */\n\n", $pcre_internal{tables_length});
if ($pcre_internal{lcc_offset} != 0) {
diff --git a/JavaScriptCore/pcre/pcre.pri b/JavaScriptCore/pcre/pcre.pri
index ec5c0d5..c33c67c 100644
--- a/JavaScriptCore/pcre/pcre.pri
+++ b/JavaScriptCore/pcre/pcre.pri
@@ -1,6 +1,6 @@
# Perl Compatible Regular Expressions - Qt4 build info
VPATH += $$PWD
-INCLUDEPATH += $$PWD $$OUTPUT_DIR/JavaScriptCore/kjs/tmp
+INCLUDEPATH += $$PWD $$OUTPUT_DIR/JavaScriptCore/tmp
DEPENDPATH += $$PWD
isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = tmp
diff --git a/JavaScriptCore/pcre/pcre_compile.cpp b/JavaScriptCore/pcre/pcre_compile.cpp
index fdd90af..18c54ff 100644
--- a/JavaScriptCore/pcre/pcre_compile.cpp
+++ b/JavaScriptCore/pcre/pcre_compile.cpp
@@ -6,7 +6,7 @@ needed by JavaScriptCore and the rest of WebKit.
Originally written by Philip Hazel
Copyright (c) 1997-2006 University of Cambridge
- Copyright (C) 2002, 2004, 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2002, 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
Copyright (C) 2007 Eric Seidel <eric@webkit.org>
-----------------------------------------------------------------------------
@@ -236,8 +236,11 @@ static int checkEscape(const UChar** ptrPtr, const UChar* patternEnd, ErrorCode*
/* Handle an octal number following \. If the first digit is 8 or 9,
this is not octal. */
- if ((c = *ptr) >= '8')
+ if ((c = *ptr) >= '8') {
+ c = '\\';
+ ptr -= 1;
break;
+ }
/* \0 always starts an octal number, but we may drop through to here with a
larger first octal digit. */
@@ -298,8 +301,17 @@ static int checkEscape(const UChar** ptrPtr, const UChar* patternEnd, ErrorCode*
*errorCodePtr = ERR2;
return 0;
}
- c = *ptr;
+ c = *ptr;
+
+ /* To match Firefox, inside a character class, we also accept
+ numbers and '_' as control characters */
+ if ((!isClass && !isASCIIAlpha(c)) || (!isASCIIAlphanumeric(c) && c != '_')) {
+ c = '\\';
+ ptr -= 2;
+ break;
+ }
+
/* A letter is upper-cased; then the 0x40 bit is flipped. This coding
is ASCII-specific, but then the whole concept of \cx is ASCII-specific. */
c = toASCIIUpper(c) ^ 0x40;
@@ -477,7 +489,7 @@ static bool getOthercaseRange(int* cptr, int d, int* ocptr, int* odptr)
int c, othercase = 0;
for (c = *cptr; c <= d; c++) {
- if ((othercase = kjs_pcre_ucp_othercase(c)) >= 0)
+ if ((othercase = jsc_pcre_ucp_othercase(c)) >= 0)
break;
}
@@ -488,7 +500,7 @@ static bool getOthercaseRange(int* cptr, int d, int* ocptr, int* odptr)
int next = othercase + 1;
for (++c; c <= d; c++) {
- if (kjs_pcre_ucp_othercase(c) != next)
+ if (jsc_pcre_ucp_othercase(c) != next)
break;
next++;
}
@@ -516,15 +528,15 @@ static bool getOthercaseRange(int* cptr, int d, int* ocptr, int* odptr)
static int encodeUTF8(int cvalue, unsigned char *buffer)
{
int i;
- for (i = 0; i < kjs_pcre_utf8_table1_size; i++)
- if (cvalue <= kjs_pcre_utf8_table1[i])
+ for (i = 0; i < jsc_pcre_utf8_table1_size; i++)
+ if (cvalue <= jsc_pcre_utf8_table1[i])
break;
buffer += i;
for (int j = i; j > 0; j--) {
*buffer-- = 0x80 | (cvalue & 0x3f);
cvalue >>= 6;
}
- *buffer = kjs_pcre_utf8_table2[i] | cvalue;
+ *buffer = jsc_pcre_utf8_table2[i] | cvalue;
return i + 1;
}
@@ -900,7 +912,7 @@ compileBranch(int options, int* brackets, unsigned char** codePtr,
if (options & IgnoreCaseOption) {
int othercase;
- if ((othercase = kjs_pcre_ucp_othercase(c)) >= 0) {
+ if ((othercase = jsc_pcre_ucp_othercase(c)) >= 0) {
*class_utf8data++ = XCL_SINGLE;
class_utf8data += encodeUTF8(othercase, class_utf8data);
}
@@ -1402,6 +1414,15 @@ compileBranch(int options, int* brackets, unsigned char** codePtr,
code[-ketoffset] = OP_KETRMAX + repeatType;
}
+ // A quantifier after an assertion is mostly meaningless, but it
+ // can nullify the assertion if it has a 0 minimum.
+ else if (*previous == OP_ASSERT || *previous == OP_ASSERT_NOT) {
+ if (repeatMin == 0) {
+ code = previous;
+ goto END_REPEAT;
+ }
+ }
+
/* Else there's some kind of shambles */
else {
@@ -1468,12 +1489,12 @@ compileBranch(int options, int* brackets, unsigned char** codePtr,
bravalue = OP_BRA + *brackets;
}
- /* Process nested bracketed re. Assertions may not be repeated, but other
- kinds can be. We copy code into a non-variable in order to be able
- to pass its address because some compilers complain otherwise. Pass in a
- new setting for the ims options if they have changed. */
+ /* Process nested bracketed re. We copy code into a non-variable
+ in order to be able to pass its address because some compilers
+ complain otherwise. Pass in a new setting for the ims options
+ if they have changed. */
- previous = (bravalue >= OP_BRAZERO) ? code : 0;
+ previous = code;
*code = bravalue;
tempcode = code;
tempreqvary = cd.reqVaryOpt; /* Save value before bracket */
@@ -2041,8 +2062,8 @@ static int calculateCompiledPatternLength(const UChar* pattern, int patternLengt
if (c > 127) {
int i;
- for (i = 0; i < kjs_pcre_utf8_table1_size; i++)
- if (c <= kjs_pcre_utf8_table1[i]) break;
+ for (i = 0; i < jsc_pcre_utf8_table1_size; i++)
+ if (c <= jsc_pcre_utf8_table1[i]) break;
length += i;
lastitemlength += i;
}
@@ -2495,8 +2516,8 @@ static int calculateCompiledPatternLength(const UChar* pattern, int patternLengt
if (c > 127) {
int i;
- for (i = 0; i < kjs_pcre_utf8_table1_size; i++)
- if (c <= kjs_pcre_utf8_table1[i])
+ for (i = 0; i < jsc_pcre_utf8_table1_size; i++)
+ if (c <= jsc_pcre_utf8_table1[i])
break;
length += i;
lastitemlength += i;
@@ -2586,7 +2607,7 @@ JSRegExp* jsRegExpCompile(const UChar* pattern, int patternLength,
const UChar* ptr = (const UChar*)pattern;
const UChar* patternEnd = pattern + patternLength;
- unsigned char* code = (unsigned char*)codeStart;
+ unsigned char* code = const_cast<unsigned char*>(codeStart);
int firstByte, reqByte;
int bracketCount = 0;
if (!cd.needOuterBracket)
diff --git a/JavaScriptCore/pcre/pcre_exec.cpp b/JavaScriptCore/pcre/pcre_exec.cpp
index 36d81e2..34e2786 100644
--- a/JavaScriptCore/pcre/pcre_exec.cpp
+++ b/JavaScriptCore/pcre/pcre_exec.cpp
@@ -6,7 +6,7 @@ needed by JavaScriptCore and the rest of WebKit.
Originally written by Philip Hazel
Copyright (c) 1997-2006 University of Cambridge
- Copyright (C) 2002, 2004, 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2002, 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
Copyright (C) 2007 Eric Seidel <eric@webkit.org>
-----------------------------------------------------------------------------
@@ -50,8 +50,8 @@ the JavaScript specification. There are also some supporting functions. */
#include <wtf/Vector.h>
#if REGEXP_HISTOGRAM
-#include <kjs/DateMath.h>
-#include <kjs/ustring.h>
+#include <parser/DateMath.h>
+#include <runtime/UString.h>
#endif
using namespace WTF;
@@ -250,7 +250,7 @@ static bool matchRef(int offset, const UChar* subjectPtr, int length, const Matc
if (md.ignoreCase) {
while (length-- > 0) {
UChar c = *p++;
- int othercase = kjs_pcre_ucp_othercase(c);
+ int othercase = jsc_pcre_ucp_othercase(c);
UChar d = *subjectPtr++;
if (c != d && othercase != d)
return false;
@@ -403,9 +403,9 @@ static inline void getUTF8CharAndIncrementLength(int& c, const unsigned char* su
{
c = *subjectPtr;
if ((c & 0xc0) == 0xc0) {
- int gcaa = kjs_pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
+ int gcaa = jsc_pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
int gcss = 6 * gcaa;
- c = (c & kjs_pcre_utf8_table3[gcaa]) << gcss;
+ c = (c & jsc_pcre_utf8_table3[gcaa]) << gcss;
for (int gcii = 1; gcii <= gcaa; gcii++) {
gcss -= 6;
c |= (subjectPtr[gcii] & 0x3f) << gcss;
@@ -1048,7 +1048,7 @@ RECURSE:
if (stack.currentFrame->args.subjectPtr >= md.endSubject)
RRETURN_NO_MATCH;
int c = *stack.currentFrame->args.subjectPtr++;
- if (!kjs_pcre_xclass(c, stack.currentFrame->locals.data))
+ if (!jsc_pcre_xclass(c, stack.currentFrame->locals.data))
RRETURN_NO_MATCH;
}
@@ -1069,7 +1069,7 @@ RECURSE:
if (stack.currentFrame->locals.fi >= stack.currentFrame->locals.max || stack.currentFrame->args.subjectPtr >= md.endSubject)
RRETURN;
int c = *stack.currentFrame->args.subjectPtr++;
- if (!kjs_pcre_xclass(c, stack.currentFrame->locals.data))
+ if (!jsc_pcre_xclass(c, stack.currentFrame->locals.data))
RRETURN;
}
/* Control never reaches here */
@@ -1083,7 +1083,7 @@ RECURSE:
if (stack.currentFrame->args.subjectPtr >= md.endSubject)
break;
int c = *stack.currentFrame->args.subjectPtr;
- if (!kjs_pcre_xclass(c, stack.currentFrame->locals.data))
+ if (!jsc_pcre_xclass(c, stack.currentFrame->locals.data))
break;
++stack.currentFrame->args.subjectPtr;
}
@@ -1122,7 +1122,7 @@ RECURSE:
if (stack.currentFrame->args.subjectPtr >= md.endSubject)
RRETURN_NO_MATCH;
int dc = *stack.currentFrame->args.subjectPtr++;
- if (stack.currentFrame->locals.fc != dc && kjs_pcre_ucp_othercase(stack.currentFrame->locals.fc) != dc)
+ if (stack.currentFrame->locals.fc != dc && jsc_pcre_ucp_othercase(stack.currentFrame->locals.fc) != dc)
RRETURN_NO_MATCH;
NEXT_OPCODE;
}
@@ -1186,7 +1186,7 @@ RECURSE:
stack.currentFrame->args.instructionPtr += stack.currentFrame->locals.length;
if (stack.currentFrame->locals.fc <= 0xFFFF) {
- int othercase = md.ignoreCase ? kjs_pcre_ucp_othercase(stack.currentFrame->locals.fc) : -1;
+ int othercase = md.ignoreCase ? jsc_pcre_ucp_othercase(stack.currentFrame->locals.fc) : -1;
for (int i = 1; i <= min; i++) {
if (*stack.currentFrame->args.subjectPtr != stack.currentFrame->locals.fc && *stack.currentFrame->args.subjectPtr != othercase)
diff --git a/JavaScriptCore/pcre/pcre_internal.h b/JavaScriptCore/pcre/pcre_internal.h
index 06c3e9d..2916765 100644
--- a/JavaScriptCore/pcre/pcre_internal.h
+++ b/JavaScriptCore/pcre/pcre_internal.h
@@ -6,7 +6,7 @@ needed by JavaScriptCore and the rest of WebKit.
Originally written by Philip Hazel
Copyright (c) 1997-2006 University of Cambridge
- Copyright (C) 2002, 2004, 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2002, 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -340,36 +340,36 @@ struct JSRegExp {
but are not part of the PCRE public API. The data for these tables is in the
pcre_tables.c module. */
-#define kjs_pcre_utf8_table1_size 6
+#define jsc_pcre_utf8_table1_size 6
-extern const int kjs_pcre_utf8_table1[6];
-extern const int kjs_pcre_utf8_table2[6];
-extern const int kjs_pcre_utf8_table3[6];
-extern const unsigned char kjs_pcre_utf8_table4[0x40];
+extern const int jsc_pcre_utf8_table1[6];
+extern const int jsc_pcre_utf8_table2[6];
+extern const int jsc_pcre_utf8_table3[6];
+extern const unsigned char jsc_pcre_utf8_table4[0x40];
-extern const unsigned char kjs_pcre_default_tables[tables_length];
+extern const unsigned char jsc_pcre_default_tables[tables_length];
static inline unsigned char toLowerCase(unsigned char c)
{
- static const unsigned char* lowerCaseChars = kjs_pcre_default_tables + lcc_offset;
+ static const unsigned char* lowerCaseChars = jsc_pcre_default_tables + lcc_offset;
return lowerCaseChars[c];
}
static inline unsigned char flipCase(unsigned char c)
{
- static const unsigned char* flippedCaseChars = kjs_pcre_default_tables + fcc_offset;
+ static const unsigned char* flippedCaseChars = jsc_pcre_default_tables + fcc_offset;
return flippedCaseChars[c];
}
static inline unsigned char classBitmapForChar(unsigned char c)
{
- static const unsigned char* charClassBitmaps = kjs_pcre_default_tables + cbits_offset;
+ static const unsigned char* charClassBitmaps = jsc_pcre_default_tables + cbits_offset;
return charClassBitmaps[c];
}
static inline unsigned char charTypeForChar(unsigned char c)
{
- const unsigned char* charTypeMap = kjs_pcre_default_tables + ctypes_offset;
+ const unsigned char* charTypeMap = jsc_pcre_default_tables + ctypes_offset;
return charTypeMap[c];
}
@@ -413,8 +413,8 @@ static inline void advanceToEndOfBracket(const unsigned char*& opcodePtr)
that one of the source files. They have to have external linkage, but
but are not part of the public API and so not exported from the library. */
-extern int kjs_pcre_ucp_othercase(unsigned);
-extern bool kjs_pcre_xclass(int, const unsigned char*);
+extern int jsc_pcre_ucp_othercase(unsigned);
+extern bool jsc_pcre_xclass(int, const unsigned char*);
#endif
diff --git a/JavaScriptCore/pcre/pcre_tables.cpp b/JavaScriptCore/pcre/pcre_tables.cpp
index d306233..8696879 100644
--- a/JavaScriptCore/pcre/pcre_tables.cpp
+++ b/JavaScriptCore/pcre/pcre_tables.cpp
@@ -6,7 +6,7 @@ needed by JavaScriptCore and the rest of WebKit.
Originally written by Philip Hazel
Copyright (c) 1997-2006 University of Cambridge
- Copyright (C) 2002, 2004, 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2002, 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -50,20 +50,20 @@ PCRE code modules. */
/* These are the breakpoints for different numbers of bytes in a UTF-8
character. */
-const int kjs_pcre_utf8_table1[6] =
+const int jsc_pcre_utf8_table1[6] =
{ 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
/* These are the indicator bits and the mask for the data bits to set in the
first byte of a character, indexed by the number of additional bytes. */
-const int kjs_pcre_utf8_table2[6] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
-const int kjs_pcre_utf8_table3[6] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
+const int jsc_pcre_utf8_table2[6] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
+const int jsc_pcre_utf8_table3[6] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
/* Table of the number of extra characters, indexed by the first character
masked with 0x3f. The highest number for a valid UTF-8 character is in fact
0x3d. */
-const unsigned char kjs_pcre_utf8_table4[0x40] = {
+const unsigned char jsc_pcre_utf8_table4[0x40] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
diff --git a/JavaScriptCore/pcre/pcre_ucp_searchfuncs.cpp b/JavaScriptCore/pcre/pcre_ucp_searchfuncs.cpp
index 6e1d0e4..5592865 100644
--- a/JavaScriptCore/pcre/pcre_ucp_searchfuncs.cpp
+++ b/JavaScriptCore/pcre/pcre_ucp_searchfuncs.cpp
@@ -6,7 +6,7 @@ needed by JavaScriptCore and the rest of WebKit.
Originally written by Philip Hazel
Copyright (c) 1997-2006 University of Cambridge
- Copyright (C) 2002, 2004, 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2002, 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -60,7 +60,7 @@ Arguments:
Returns: the other case or -1 if none
*/
-int kjs_pcre_ucp_othercase(unsigned c)
+int jsc_pcre_ucp_othercase(unsigned c)
{
int bot = 0;
int top = sizeof(ucp_table) / sizeof(cnode);
diff --git a/JavaScriptCore/pcre/pcre_xclass.cpp b/JavaScriptCore/pcre/pcre_xclass.cpp
index 2fb36d7..a32edd4 100644
--- a/JavaScriptCore/pcre/pcre_xclass.cpp
+++ b/JavaScriptCore/pcre/pcre_xclass.cpp
@@ -6,7 +6,7 @@ needed by JavaScriptCore and the rest of WebKit.
Originally written by Philip Hazel
Copyright (c) 1997-2006 University of Cambridge
- Copyright (C) 2002, 2004, 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2002, 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -64,9 +64,9 @@ static inline void getUTF8CharAndAdvancePointer(int& c, const unsigned char*& su
{
c = *subjectPtr++;
if ((c & 0xc0) == 0xc0) {
- int gcaa = kjs_pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
+ int gcaa = jsc_pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
int gcss = 6 * gcaa;
- c = (c & kjs_pcre_utf8_table3[gcaa]) << gcss;
+ c = (c & jsc_pcre_utf8_table3[gcaa]) << gcss;
while (gcaa-- > 0) {
gcss -= 6;
c |= (*subjectPtr++ & 0x3f) << gcss;
@@ -74,7 +74,7 @@ static inline void getUTF8CharAndAdvancePointer(int& c, const unsigned char*& su
}
}
-bool kjs_pcre_xclass(int c, const unsigned char* data)
+bool jsc_pcre_xclass(int c, const unsigned char* data)
{
bool negated = (*data & XCL_NOT);
diff --git a/JavaScriptCore/profiler/CallIdentifier.h b/JavaScriptCore/profiler/CallIdentifier.h
index c24c44b..6ceef13 100644
--- a/JavaScriptCore/profiler/CallIdentifier.h
+++ b/JavaScriptCore/profiler/CallIdentifier.h
@@ -27,7 +27,7 @@
#ifndef CallIdentifier_h
#define CallIdentifier_h
-#include <kjs/ustring.h>
+#include <runtime/UString.h>
namespace JSC {
diff --git a/JavaScriptCore/profiler/Profile.h b/JavaScriptCore/profiler/Profile.h
index c232c55..dd96f77 100644
--- a/JavaScriptCore/profiler/Profile.h
+++ b/JavaScriptCore/profiler/Profile.h
@@ -27,7 +27,7 @@
#define Profile_h
#include "ProfileNode.h"
-#include <kjs/ustring.h>
+#include <runtime/UString.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
diff --git a/JavaScriptCore/profiler/ProfileGenerator.cpp b/JavaScriptCore/profiler/ProfileGenerator.cpp
index 1506788..b1d5d48 100644
--- a/JavaScriptCore/profiler/ProfileGenerator.cpp
+++ b/JavaScriptCore/profiler/ProfileGenerator.cpp
@@ -26,11 +26,11 @@
#include "config.h"
#include "ProfileGenerator.h"
-#include "ExecState.h"
+#include "CallFrame.h"
#include "JSGlobalObject.h"
#include "JSStringRef.h"
#include "JSFunction.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "Profile.h"
#include "Profiler.h"
#include "Tracing.h"
@@ -59,10 +59,10 @@ void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
int lineNumber;
intptr_t sourceID;
UString sourceURL;
- JSValue* function;
+ JSValuePtr function;
- exec->machine()->retrieveLastCaller(exec, lineNumber, sourceID, sourceURL, function);
- m_currentNode = ProfileNode::create(Profiler::createCallIdentifier(&exec->globalData(), function ? function->toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
+ exec->interpreter()->retrieveLastCaller(exec, lineNumber, sourceID, sourceURL, function);
+ m_currentNode = ProfileNode::create(Profiler::createCallIdentifier(&exec->globalData(), function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
m_head->insertNode(m_currentNode.get());
}
diff --git a/JavaScriptCore/profiler/Profiler.cpp b/JavaScriptCore/profiler/Profiler.cpp
index c68fa1a..2de8f84 100644
--- a/JavaScriptCore/profiler/Profiler.cpp
+++ b/JavaScriptCore/profiler/Profiler.cpp
@@ -30,7 +30,7 @@
#include "Profiler.h"
#include "CommonIdentifiers.h"
-#include "ExecState.h"
+#include "CallFrame.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "Profile.h"
@@ -101,7 +101,7 @@ static inline void dispatchFunctionToProfiles(const Vector<RefPtr<ProfileGenerat
}
}
-void Profiler::willExecute(ExecState* exec, JSValue* function)
+void Profiler::willExecute(ExecState* exec, JSValuePtr function)
{
ASSERT(!m_currentProfiles.isEmpty());
@@ -117,7 +117,7 @@ void Profiler::willExecute(ExecState* exec, const UString& sourceURL, int starti
dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, exec->lexicalGlobalObject()->profileGroup());
}
-void Profiler::didExecute(ExecState* exec, JSValue* function)
+void Profiler::didExecute(ExecState* exec, JSValuePtr function)
{
ASSERT(!m_currentProfiles.isEmpty());
@@ -131,11 +131,11 @@ void Profiler::didExecute(ExecState* exec, const UString& sourceURL, int startin
dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(&exec->globalData(), noValue(), sourceURL, startingLineNumber), exec->lexicalGlobalObject()->profileGroup());
}
-CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSValue* function, const UString& defaultSourceURL, int defaultLineNumber)
+CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSValuePtr function, const UString& defaultSourceURL, int defaultLineNumber)
{
if (!function)
return CallIdentifier(GlobalCodeExecution, defaultSourceURL, defaultLineNumber);
- if (!function->isObject())
+ if (!function.isObject())
return CallIdentifier("(unknown)", defaultSourceURL, defaultLineNumber);
if (asObject(function)->inherits(&JSFunction::info))
return createCallIdentifierFromFunctionImp(globalData, asFunction(function));
@@ -147,7 +147,7 @@ CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSValue*
CallIdentifier createCallIdentifierFromFunctionImp(JSGlobalData* globalData, JSFunction* function)
{
const UString& name = function->name(globalData);
- return CallIdentifier(name.isEmpty() ? AnonymousFunction : name, function->m_body->sourceURL(), function->m_body->lineNo());
+ return CallIdentifier(name.isEmpty() ? AnonymousFunction : name, function->body()->sourceURL(), function->body()->lineNo());
}
} // namespace JSC
diff --git a/JavaScriptCore/profiler/Profiler.h b/JavaScriptCore/profiler/Profiler.h
index b622fb2..d00bccf 100644
--- a/JavaScriptCore/profiler/Profiler.h
+++ b/JavaScriptCore/profiler/Profiler.h
@@ -40,6 +40,7 @@ namespace JSC {
class ExecState;
class JSGlobalData;
class JSObject;
+ class JSValuePtr;
class ProfileGenerator;
class UString;
@@ -51,14 +52,14 @@ namespace JSC {
}
static Profiler* profiler();
- static CallIdentifier createCallIdentifier(JSGlobalData*, JSValue*, const UString& sourceURL, int lineNumber);
+ static CallIdentifier createCallIdentifier(JSGlobalData*, JSValuePtr, const UString& sourceURL, int lineNumber);
void startProfiling(ExecState*, const UString& title);
PassRefPtr<Profile> stopProfiling(ExecState*, const UString& title);
- void willExecute(ExecState*, JSValue* function);
+ void willExecute(ExecState*, JSValuePtr function);
void willExecute(ExecState*, const UString& sourceURL, int startingLineNumber);
- void didExecute(ExecState*, JSValue* function);
+ void didExecute(ExecState*, JSValuePtr function);
void didExecute(ExecState*, const UString& sourceURL, int startingLineNumber);
const Vector<RefPtr<ProfileGenerator> >& currentProfiles() { return m_currentProfiles; };
diff --git a/JavaScriptCore/runtime/ArgList.cpp b/JavaScriptCore/runtime/ArgList.cpp
index 7675b20..5ead733 100644
--- a/JavaScriptCore/runtime/ArgList.cpp
+++ b/JavaScriptCore/runtime/ArgList.cpp
@@ -51,7 +51,7 @@ void ArgList::markLists(ListSet& markSet)
}
}
-void ArgList::slowAppend(JSValue* v)
+void ArgList::slowAppend(JSValuePtr v)
{
// As long as our size stays within our Vector's inline
// capacity, all our values are allocated on the stack, and
diff --git a/JavaScriptCore/runtime/ArgList.h b/JavaScriptCore/runtime/ArgList.h
index 44446aa..a1763e0 100644
--- a/JavaScriptCore/runtime/ArgList.h
+++ b/JavaScriptCore/runtime/ArgList.h
@@ -85,7 +85,7 @@ namespace JSC {
size_t size() const { return m_size; }
bool isEmpty() const { return !m_size; }
- JSValue* at(ExecState* exec, size_t i) const
+ JSValuePtr at(ExecState* exec, size_t i) const
{
if (i < m_size)
return m_buffer[i].jsValue(exec);
@@ -99,7 +99,7 @@ namespace JSC {
m_size = 0;
}
- void append(JSValue* v)
+ void append(JSValuePtr v)
{
ASSERT(!m_isReadOnly);
@@ -125,7 +125,7 @@ namespace JSC {
static void markLists(ListSet&);
private:
- void slowAppend(JSValue*);
+ void slowAppend(JSValuePtr);
Register* m_buffer;
size_t m_size;
diff --git a/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp
index fe1de62..b0429a9 100644
--- a/JavaScriptCore/runtime/Arguments.cpp
+++ b/JavaScriptCore/runtime/Arguments.cpp
@@ -145,28 +145,28 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa
return JSObject::getOwnPropertySlot(exec, propertyName, slot);
}
-void Arguments::put(ExecState* exec, unsigned i, JSValue* value, PutPropertySlot& slot)
+void Arguments::put(ExecState* exec, unsigned i, JSValuePtr value, PutPropertySlot& slot)
{
if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
if (i < d->numParameters)
- d->registers[d->firstParameterIndex + i] = value;
+ d->registers[d->firstParameterIndex + i] = JSValuePtr(value);
else
- d->extraArguments[i - d->numParameters] = value;
+ d->extraArguments[i - d->numParameters] = JSValuePtr(value);
return;
}
JSObject::put(exec, Identifier(exec, UString::from(i)), value, slot);
}
-void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
bool isArrayIndex;
unsigned i = propertyName.toArrayIndex(&isArrayIndex);
if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
if (i < d->numParameters)
- d->registers[d->firstParameterIndex + i] = value;
+ d->registers[d->firstParameterIndex + i] = JSValuePtr(value);
else
- d->extraArguments[i - d->numParameters] = value;
+ d->extraArguments[i - d->numParameters] = JSValuePtr(value);
return;
}
diff --git a/JavaScriptCore/runtime/Arguments.h b/JavaScriptCore/runtime/Arguments.h
index 93cc64f..ebea6ad 100644
--- a/JavaScriptCore/runtime/Arguments.h
+++ b/JavaScriptCore/runtime/Arguments.h
@@ -27,7 +27,7 @@
#include "JSActivation.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
-#include "Machine.h"
+#include "Interpreter.h"
namespace JSC {
@@ -73,17 +73,17 @@ namespace JSC {
d->registers = &activation->registerAt(0);
}
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType));
}
private:
void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
- virtual void put(ExecState*, unsigned propertyName, JSValue*, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+ virtual void put(ExecState*, unsigned propertyName, JSValuePtr, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
@@ -94,9 +94,9 @@ namespace JSC {
OwnPtr<ArgumentsData> d;
};
- Arguments* asArguments(JSValue*);
+ Arguments* asArguments(JSValuePtr);
- inline Arguments* asArguments(JSValue* value)
+ inline Arguments* asArguments(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&Arguments::info));
return static_cast<Arguments*>(asObject(value));
@@ -106,8 +106,8 @@ namespace JSC {
{
function = callFrame->callee();
- CodeBlock* codeBlock = &function->m_body->generatedByteCode();
- int numParameters = codeBlock->numParameters;
+ CodeBlock* codeBlock = &function->body()->generatedBytecode();
+ int numParameters = codeBlock->m_numParameters;
argc = callFrame->argumentCount();
if (argc <= numParameters)
@@ -129,7 +129,7 @@ namespace JSC {
int numArguments;
getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments);
- d->numParameters = callee->m_body->parameterCount();
+ d->numParameters = callee->body()->parameterCount();
d->firstParameterIndex = firstParameterIndex;
d->numArguments = numArguments;
@@ -160,7 +160,7 @@ namespace JSC {
: JSObject(callFrame->lexicalGlobalObject()->argumentsStructure())
, d(new ArgumentsData)
{
- ASSERT(!callFrame->callee()->m_body->parameterCount());
+ ASSERT(!callFrame->callee()->body()->parameterCount());
unsigned numArguments = callFrame->argumentCount() - 1;
@@ -206,8 +206,8 @@ namespace JSC {
{
ASSERT(!d()->registerArray);
- size_t numParametersMinusThis = d()->functionBody->generatedByteCode().numParameters - 1;
- size_t numVars = d()->functionBody->generatedByteCode().numVars;
+ size_t numParametersMinusThis = d()->functionBody->generatedBytecode().m_numParameters - 1;
+ size_t numVars = d()->functionBody->generatedBytecode().m_numVars;
size_t numLocals = numVars + numParametersMinusThis;
if (!numLocals)
diff --git a/JavaScriptCore/runtime/ArrayConstructor.cpp b/JavaScriptCore/runtime/ArrayConstructor.cpp
index 5784af0..dd3ff4b 100644
--- a/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -26,13 +26,13 @@
#include "ArrayPrototype.h"
#include "JSArray.h"
-#include "lookup.h"
+#include "Lookup.h"
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor);
-ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<StructureID> structure, ArrayPrototype* arrayPrototype)
+ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> structure, ArrayPrototype* arrayPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, arrayPrototype->classInfo()->className))
{
// ECMA 15.4.3.1 Array.prototype
@@ -45,9 +45,9 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<StructureID> stru
static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
{
// a single numeric argument denotes the array size (!)
- if (args.size() == 1 && args.at(exec, 0)->isNumber()) {
- uint32_t n = args.at(exec, 0)->toUInt32(exec);
- if (n != args.at(exec, 0)->toNumber(exec))
+ if (args.size() == 1 && args.at(exec, 0).isNumber()) {
+ uint32_t n = args.at(exec, 0).toUInt32(exec);
+ if (n != args.at(exec, 0).toNumber(exec))
return throwError(exec, RangeError, "Array size is not a small enough positive integer.");
return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), n);
}
@@ -68,7 +68,7 @@ ConstructType ArrayConstructor::getConstructData(ConstructData& constructData)
return ConstructTypeHost;
}
-static JSValue* callArrayConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr callArrayConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
return constructArrayWithSizeQuirk(exec, args);
}
diff --git a/JavaScriptCore/runtime/ArrayConstructor.h b/JavaScriptCore/runtime/ArrayConstructor.h
index 6f0f866..8300d8c 100644
--- a/JavaScriptCore/runtime/ArrayConstructor.h
+++ b/JavaScriptCore/runtime/ArrayConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class ArrayConstructor : public InternalFunction {
public:
- ArrayConstructor(ExecState*, PassRefPtr<StructureID>, ArrayPrototype*);
+ ArrayConstructor(ExecState*, PassRefPtr<Structure>, ArrayPrototype*);
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index 5280784..4cd229a 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -24,10 +24,11 @@
#include "config.h"
#include "ArrayPrototype.h"
-#include "Machine.h"
+#include "CodeBlock.h"
+#include "Interpreter.h"
#include "ObjectPrototype.h"
-#include "lookup.h"
-#include "operations.h"
+#include "Lookup.h"
+#include "Operations.h"
#include <algorithm>
#include <wtf/Assertions.h>
#include <wtf/HashSet.h>
@@ -36,25 +37,25 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ArrayPrototype);
-static JSValue* arrayProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncConcat(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncJoin(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncPop(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncPush(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncReverse(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncShift(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncSlice(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncSort(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncSplice(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncUnShift(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncEvery(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncForEach(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncSome(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncFilter(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncMap(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr arrayProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncConcat(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncJoin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncPop(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncPush(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncReverse(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncShift(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncSlice(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncSort(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncSplice(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncUnShift(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncEvery(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncForEach(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncSome(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncFilter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncMap(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
}
@@ -62,6 +63,14 @@ static JSValue* arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue*, const
namespace JSC {
+static inline bool isNumericCompareFunction(CallType callType, const CallData& callData)
+{
+ if (callType != CallTypeJS)
+ return false;
+
+ return callData.js.functionBody->bytecode(callData.js.scopeChain).isNumericCompareFunction();
+}
+
// ------------------------------ ArrayPrototype ----------------------------
const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::arrayTable};
@@ -91,7 +100,7 @@ const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::a
*/
// ECMA 15.4.4
-ArrayPrototype::ArrayPrototype(PassRefPtr<StructureID> structure)
+ArrayPrototype::ArrayPrototype(PassRefPtr<Structure> structure)
: JSArray(structure)
{
}
@@ -104,7 +113,7 @@ bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& prope
// ------------------------------ Array Functions ----------------------------
// Helper function
-static JSValue* getProperty(ExecState* exec, JSObject* obj, unsigned index)
+static JSValuePtr getProperty(ExecState* exec, JSObject* obj, unsigned index)
{
PropertySlot slot(obj);
if (!obj->getPropertySlot(exec, index, slot))
@@ -112,15 +121,15 @@ static JSValue* getProperty(ExecState* exec, JSObject* obj, unsigned index)
return slot.getValue(exec, index);
}
-static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValue* value)
+static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValuePtr value)
{
PutPropertySlot slot;
obj->put(exec, propertyName, value, slot);
}
-JSValue* arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr arrayProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&JSArray::info))
+ if (!thisValue.isObject(&JSArray::info))
return throwError(exec, TypeError);
JSObject* thisObj = asArray(thisValue);
@@ -133,7 +142,7 @@ JSValue* arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue,
return jsEmptyString(exec); // return an empty string, avoiding infinite recursion.
Vector<UChar, 256> strBuffer;
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
if (k >= 1)
strBuffer.append(',');
@@ -143,11 +152,11 @@ JSValue* arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue,
break;
}
- JSValue* element = thisObj->get(exec, k);
- if (element->isUndefinedOrNull())
+ JSValuePtr element = thisObj->get(exec, k);
+ if (element.isUndefinedOrNull())
continue;
- UString str = element->toString(exec);
+ UString str = element.toString(exec);
strBuffer.append(str.data(), str.size());
if (!strBuffer.data()) {
@@ -162,9 +171,9 @@ JSValue* arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue,
return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
}
-JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&JSArray::info))
+ if (!thisValue.isObject(&JSArray::info))
return throwError(exec, TypeError);
JSObject* thisObj = asArray(thisValue);
@@ -177,7 +186,7 @@ JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisV
return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
Vector<UChar, 256> strBuffer;
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
if (k >= 1)
strBuffer.append(',');
@@ -187,19 +196,19 @@ JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisV
break;
}
- JSValue* element = thisObj->get(exec, k);
- if (element->isUndefinedOrNull())
+ JSValuePtr element = thisObj->get(exec, k);
+ if (element.isUndefinedOrNull())
continue;
- JSObject* o = element->toObject(exec);
- JSValue* conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
+ JSObject* o = element.toObject(exec);
+ JSValuePtr conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
UString str;
CallData callData;
- CallType callType = conversionFunction->getCallData(callData);
+ CallType callType = conversionFunction.getCallData(callData);
if (callType != CallTypeNone)
- str = call(exec, conversionFunction, callType, callData, element, exec->emptyList())->toString(exec);
+ str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec);
else
- str = element->toString(exec);
+ str = element.toString(exec);
strBuffer.append(str.data(), str.size());
if (!strBuffer.data()) {
@@ -214,9 +223,9 @@ JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisV
return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
}
-JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
if (arrayVisitedElements.size() > MaxReentryDepth)
@@ -229,9 +238,9 @@ JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue* thisValue, cons
Vector<UChar, 256> strBuffer;
UChar comma = ',';
- UString separator = args.at(exec, 0)->isUndefined() ? UString(&comma, 1) : args.at(exec, 0)->toString(exec);
+ UString separator = args.at(exec, 0).isUndefined() ? UString(&comma, 1) : args.at(exec, 0).toString(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
if (k >= 1)
strBuffer.append(separator.data(), separator.size());
@@ -241,11 +250,11 @@ JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue* thisValue, cons
break;
}
- JSValue* element = thisObj->get(exec, k);
- if (element->isUndefinedOrNull())
+ JSValuePtr element = thisObj->get(exec, k);
+ if (element.isUndefinedOrNull())
continue;
- UString str = element->toString(exec);
+ UString str = element.toString(exec);
strBuffer.append(str.data(), str.size());
if (!strBuffer.data()) {
@@ -260,19 +269,19 @@ JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue* thisValue, cons
return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
}
-JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
JSArray* arr = constructEmptyArray(exec);
int n = 0;
- JSValue* curArg = thisValue->toThisObject(exec);
+ JSValuePtr curArg = thisValue.toThisObject(exec);
ArgList::const_iterator it = args.begin();
ArgList::const_iterator end = args.end();
while (1) {
- if (curArg->isObject(&JSArray::info)) {
+ if (curArg.isObject(&JSArray::info)) {
JSArray* curArray = asArray(curArg);
unsigned length = curArray->length();
for (unsigned k = 0; k < length; ++k) {
- if (JSValue* v = getProperty(exec, curArray, k))
+ if (JSValuePtr v = getProperty(exec, curArray, k))
arr->put(exec, n, v);
n++;
}
@@ -289,14 +298,14 @@ JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, co
return arr;
}
-JSValue* arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr arrayProtoFuncPop(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (exec->machine()->isJSArray(thisValue))
+ if (exec->interpreter()->isJSArray(thisValue))
return asArray(thisValue)->pop();
- JSObject* thisObj = thisValue->toThisObject(exec);
- JSValue* result;
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
+ JSValuePtr result;
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (length == 0) {
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
result = jsUndefined();
@@ -308,16 +317,16 @@ JSValue* arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue* thisValue, const
return result;
}
-JSValue* arrayProtoFuncPush(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncPush(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- if (exec->machine()->isJSArray(thisValue) && args.size() == 1) {
+ if (exec->interpreter()->isJSArray(thisValue) && args.size() == 1) {
JSArray* array = asArray(thisValue);
array->push(exec, args.begin()->jsValue(exec));
return jsNumber(exec, array->length());
}
- JSObject* thisObj = thisValue->toThisObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned n = 0; n < args.size(); n++)
thisObj->put(exec, length + n, args.at(exec, n));
length += args.size();
@@ -325,16 +334,16 @@ JSValue* arrayProtoFuncPush(ExecState* exec, JSObject*, JSValue* thisValue, cons
return jsNumber(exec, length);
}
-JSValue* arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned middle = length / 2;
for (unsigned k = 0; k < middle; k++) {
unsigned lk1 = length - k - 1;
- JSValue* obj2 = getProperty(exec, thisObj, lk1);
- JSValue* obj = getProperty(exec, thisObj, k);
+ JSValuePtr obj2 = getProperty(exec, thisObj, lk1);
+ JSValuePtr obj = getProperty(exec, thisObj, k);
if (obj2)
thisObj->put(exec, k, obj2);
@@ -349,19 +358,19 @@ JSValue* arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValue* thisValue, c
return thisObj;
}
-JSValue* arrayProtoFuncShift(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr arrayProtoFuncShift(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
- JSValue* result;
+ JSObject* thisObj = thisValue.toThisObject(exec);
+ JSValuePtr result;
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (length == 0) {
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
result = jsUndefined();
} else {
result = thisObj->get(exec, 0);
for (unsigned k = 1; k < length; k++) {
- if (JSValue* obj = getProperty(exec, thisObj, k))
+ if (JSValuePtr obj = getProperty(exec, thisObj, k))
thisObj->put(exec, k - 1, obj);
else
thisObj->deleteProperty(exec, k - 1);
@@ -372,17 +381,17 @@ JSValue* arrayProtoFuncShift(ExecState* exec, JSObject*, JSValue* thisValue, con
return result;
}
-JSValue* arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
// http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
// We return a new array
JSArray* resObj = constructEmptyArray(exec);
- JSValue* result = resObj;
- double begin = args.at(exec, 0)->toInteger(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ JSValuePtr result = resObj;
+ double begin = args.at(exec, 0).toInteger(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (begin >= 0) {
if (begin > length)
begin = length;
@@ -392,10 +401,10 @@ JSValue* arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValue* thisValue, con
begin = 0;
}
double end;
- if (args.at(exec, 1)->isUndefined())
+ if (args.at(exec, 1).isUndefined())
end = length;
else {
- end = args.at(exec, 1)->toInteger(exec);
+ end = args.at(exec, 1).toInteger(exec);
if (end < 0) {
end += length;
if (end < 0)
@@ -410,30 +419,32 @@ JSValue* arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValue* thisValue, con
int b = static_cast<int>(begin);
int e = static_cast<int>(end);
for (int k = b; k < e; k++, n++) {
- if (JSValue* v = getProperty(exec, thisObj, k))
+ if (JSValuePtr v = getProperty(exec, thisObj, k))
resObj->put(exec, n, v);
}
resObj->setLength(n);
return result;
}
-JSValue* arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncSort(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValue* function = args.at(exec, 0);
+ JSValuePtr function = args.at(exec, 0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (thisObj->classInfo() == &JSArray::info) {
- if (callType != CallTypeNone)
+ if (isNumericCompareFunction(callType, callData))
+ asArray(thisObj)->sortNumeric(exec, function, callType, callData);
+ else if (callType != CallTypeNone)
asArray(thisObj)->sort(exec, function, callType, callData);
else
asArray(thisObj)->sort(exec);
return thisObj;
}
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length)
return thisObj;
@@ -441,23 +452,23 @@ JSValue* arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue* thisValue, cons
// "Min" sort. Not the fastest, but definitely less code than heapsort
// or quicksort, and much less swapping than bubblesort/insertionsort.
for (unsigned i = 0; i < length - 1; ++i) {
- JSValue* iObj = thisObj->get(exec, i);
+ JSValuePtr iObj = thisObj->get(exec, i);
unsigned themin = i;
- JSValue* minObj = iObj;
+ JSValuePtr minObj = iObj;
for (unsigned j = i + 1; j < length; ++j) {
- JSValue* jObj = thisObj->get(exec, j);
+ JSValuePtr jObj = thisObj->get(exec, j);
double compareResult;
- if (jObj->isUndefined())
+ if (jObj.isUndefined())
compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
- else if (minObj->isUndefined())
+ else if (minObj.isUndefined())
compareResult = -1;
else if (callType != CallTypeNone) {
ArgList l;
l.append(jObj);
l.append(minObj);
- compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l)->toNumber(exec);
+ compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l).toNumber(exec);
} else
- compareResult = (jObj->toString(exec) < minObj->toString(exec)) ? -1 : 1;
+ compareResult = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1;
if (compareResult < 0) {
themin = j;
@@ -473,17 +484,17 @@ JSValue* arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue* thisValue, cons
return thisObj;
}
-JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
// 15.4.4.12
JSArray* resObj = constructEmptyArray(exec);
- JSValue* result = resObj;
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ JSValuePtr result = resObj;
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!args.size())
return jsUndefined();
- int begin = args.at(exec, 0)->toUInt32(exec);
+ int begin = args.at(exec, 0).toUInt32(exec);
if (begin < 0)
begin = std::max<int>(begin + length, 0);
else
@@ -491,12 +502,12 @@ JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue* thisValue, co
unsigned deleteCount;
if (args.size() > 1)
- deleteCount = std::min<int>(std::max<int>(args.at(exec, 1)->toUInt32(exec), 0), length - begin);
+ deleteCount = std::min<int>(std::max<int>(args.at(exec, 1).toUInt32(exec), 0), length - begin);
else
deleteCount = length - begin;
for (unsigned k = 0; k < deleteCount; k++) {
- if (JSValue* v = getProperty(exec, thisObj, k + begin))
+ if (JSValuePtr v = getProperty(exec, thisObj, k + begin))
resObj->put(exec, k, v);
}
resObj->setLength(deleteCount);
@@ -505,7 +516,7 @@ JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue* thisValue, co
if (additionalArgs != deleteCount) {
if (additionalArgs < deleteCount) {
for (unsigned k = begin; k < length - deleteCount; ++k) {
- if (JSValue* v = getProperty(exec, thisObj, k + deleteCount))
+ if (JSValuePtr v = getProperty(exec, thisObj, k + deleteCount))
thisObj->put(exec, k + additionalArgs, v);
else
thisObj->deleteProperty(exec, k + additionalArgs);
@@ -514,7 +525,7 @@ JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue* thisValue, co
thisObj->deleteProperty(exec, k - 1);
} else {
for (unsigned k = length - deleteCount; (int)k > begin; --k) {
- if (JSValue* obj = getProperty(exec, thisObj, k + deleteCount - 1))
+ if (JSValuePtr obj = getProperty(exec, thisObj, k + deleteCount - 1))
thisObj->put(exec, k + additionalArgs - 1, obj);
else
thisObj->deleteProperty(exec, k + additionalArgs - 1);
@@ -528,16 +539,16 @@ JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue* thisValue, co
return result;
}
-JSValue* arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
// 15.4.4.13
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned nrArgs = args.size();
if (nrArgs) {
for (unsigned k = length; k > 0; --k) {
- if (JSValue* v = getProperty(exec, thisObj, k - 1))
+ if (JSValuePtr v = getProperty(exec, thisObj, k - 1))
thisObj->put(exec, k + nrArgs - 1, v);
else
thisObj->deleteProperty(exec, k + nrArgs - 1);
@@ -545,33 +556,33 @@ JSValue* arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValue* thisValue, c
}
for (unsigned k = 0; k < nrArgs; ++k)
thisObj->put(exec, k, args.at(exec, k));
- JSValue* result = jsNumber(exec, length + nrArgs);
+ JSValuePtr result = jsNumber(exec, length + nrArgs);
putProperty(exec, thisObj, exec->propertyNames().length, result);
return result;
}
-JSValue* arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValue* function = args.at(exec, 0);
+ JSValuePtr function = args.at(exec, 0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+ JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec);
JSArray* resultArray = constructEmptyArray(exec);
unsigned filterIndex = 0;
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
PropertySlot slot(thisObj);
if (!thisObj->getPropertySlot(exec, k, slot))
continue;
- JSValue* v = slot.getValue(exec, k);
+ JSValuePtr v = slot.getValue(exec, k);
ArgList eachArguments;
@@ -579,27 +590,27 @@ JSValue* arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValue* thisValue, co
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
- JSValue* result = call(exec, function, callType, callData, applyThis, eachArguments);
+ JSValuePtr result = call(exec, function, callType, callData, applyThis, eachArguments);
- if (result->toBoolean(exec))
+ if (result.toBoolean(exec))
resultArray->put(exec, filterIndex++, v);
}
return resultArray;
}
-JSValue* arrayProtoFuncMap(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncMap(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValue* function = args.at(exec, 0);
+ JSValuePtr function = args.at(exec, 0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+ JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
JSArray* resultArray = constructEmptyArray(exec, length);
@@ -608,7 +619,7 @@ JSValue* arrayProtoFuncMap(ExecState* exec, JSObject*, JSValue* thisValue, const
if (!thisObj->getPropertySlot(exec, k, slot))
continue;
- JSValue* v = slot.getValue(exec, k);
+ JSValuePtr v = slot.getValue(exec, k);
ArgList eachArguments;
@@ -616,7 +627,7 @@ JSValue* arrayProtoFuncMap(ExecState* exec, JSObject*, JSValue* thisValue, const
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
- JSValue* result = call(exec, function, callType, callData, applyThis, eachArguments);
+ JSValuePtr result = call(exec, function, callType, callData, applyThis, eachArguments);
resultArray->put(exec, k, result);
}
@@ -628,21 +639,21 @@ JSValue* arrayProtoFuncMap(ExecState* exec, JSObject*, JSValue* thisValue, const
// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach
// http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some
-JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValue* function = args.at(exec, 0);
+ JSValuePtr function = args.at(exec, 0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+ JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec);
- JSValue* result = jsBoolean(true);
+ JSValuePtr result = jsBoolean(true);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
PropertySlot slot(thisObj);
@@ -655,7 +666,7 @@ JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue* thisValue, con
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
- bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments)->toBoolean(exec);
+ bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
if (!predicateResult) {
result = jsBoolean(false);
@@ -666,19 +677,19 @@ JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue* thisValue, con
return result;
}
-JSValue* arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValue* function = args.at(exec, 0);
+ JSValuePtr function = args.at(exec, 0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+ JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
PropertySlot slot(thisObj);
if (!thisObj->getPropertySlot(exec, k, slot))
@@ -694,21 +705,21 @@ JSValue* arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValue* thisValue, c
return jsUndefined();
}
-JSValue* arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncSome(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- JSValue* function = args.at(exec, 0);
+ JSValuePtr function = args.at(exec, 0);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSObject* applyThis = args.at(exec, 1)->isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1)->toObject(exec);
+ JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec);
- JSValue* result = jsBoolean(false);
+ JSValuePtr result = jsBoolean(false);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
PropertySlot slot(thisObj);
if (!thisObj->getPropertySlot(exec, k, slot))
@@ -719,7 +730,7 @@ JSValue* arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue* thisValue, cons
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
- bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments)->toBoolean(exec);
+ bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments).toBoolean(exec);
if (predicateResult) {
result = jsBoolean(true);
@@ -729,16 +740,16 @@ JSValue* arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue* thisValue, cons
return result;
}
-JSValue* arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
// JavaScript 1.5 Extension by Mozilla
// Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
unsigned index = 0;
- double d = args.at(exec, 1)->toInteger(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ double d = args.at(exec, 1).toInteger(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (d < 0)
d += length;
if (d > 0) {
@@ -748,28 +759,28 @@ JSValue* arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, c
index = static_cast<unsigned>(d);
}
- JSValue* searchElement = args.at(exec, 0);
+ JSValuePtr searchElement = args.at(exec, 0);
for (; index < length; ++index) {
- JSValue* e = getProperty(exec, thisObj, index);
+ JSValuePtr e = getProperty(exec, thisObj, index);
if (!e)
continue;
- if (strictEqual(searchElement, e))
+ if (JSValuePtr::strictEqual(searchElement, e))
return jsNumber(exec, index);
}
return jsNumber(exec, -1);
}
-JSValue* arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
// JavaScript 1.6 Extension by Mozilla
// Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
int index = length - 1;
- double d = args.at(exec, 1)->toIntegerPreserveNaN(exec);
+ double d = args.at(exec, 1).toIntegerPreserveNaN(exec);
if (d < 0) {
d += length;
@@ -779,12 +790,12 @@ JSValue* arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue* thisValu
if (d < length)
index = static_cast<int>(d);
- JSValue* searchElement = args.at(exec, 0);
+ JSValuePtr searchElement = args.at(exec, 0);
for (; index >= 0; --index) {
- JSValue* e = getProperty(exec, thisObj, index);
+ JSValuePtr e = getProperty(exec, thisObj, index);
if (!e)
continue;
- if (strictEqual(searchElement, e))
+ if (JSValuePtr::strictEqual(searchElement, e))
return jsNumber(exec, index);
}
diff --git a/JavaScriptCore/runtime/ArrayPrototype.h b/JavaScriptCore/runtime/ArrayPrototype.h
index 33ce30b..2165089 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.h
+++ b/JavaScriptCore/runtime/ArrayPrototype.h
@@ -22,13 +22,13 @@
#define ArrayPrototype_h
#include "JSArray.h"
-#include "lookup.h"
+#include "Lookup.h"
namespace JSC {
class ArrayPrototype : public JSArray {
public:
- explicit ArrayPrototype(PassRefPtr<StructureID>);
+ explicit ArrayPrototype(PassRefPtr<Structure>);
bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
diff --git a/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
index 536d09c..13dd95c 100644
--- a/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
+++ b/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
@@ -37,13 +37,13 @@ namespace JSC {
BatchedTransitionOptimizer(JSObject* object)
: m_object(object)
{
- if (!m_object->structureID()->isDictionary())
- m_object->setStructureID(StructureID::toDictionaryTransition(m_object->structureID()));
+ if (!m_object->structure()->isDictionary())
+ m_object->setStructure(Structure::toDictionaryTransition(m_object->structure()));
}
~BatchedTransitionOptimizer()
{
- m_object->setStructureID(StructureID::fromDictionaryTransition(m_object->structureID()));
+ m_object->setStructure(Structure::fromDictionaryTransition(m_object->structure()));
}
private:
diff --git a/JavaScriptCore/runtime/BooleanConstructor.cpp b/JavaScriptCore/runtime/BooleanConstructor.cpp
index 46a6018..bdf3322 100644
--- a/JavaScriptCore/runtime/BooleanConstructor.cpp
+++ b/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -28,7 +28,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor);
-BooleanConstructor::BooleanConstructor(ExecState* exec, PassRefPtr<StructureID> structure, BooleanPrototype* booleanPrototype)
+BooleanConstructor::BooleanConstructor(ExecState* exec, PassRefPtr<Structure> structure, BooleanPrototype* booleanPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, booleanPrototype->classInfo()->className))
{
putDirectWithoutTransition(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
@@ -41,7 +41,7 @@ BooleanConstructor::BooleanConstructor(ExecState* exec, PassRefPtr<StructureID>
JSObject* constructBoolean(ExecState* exec, const ArgList& args)
{
BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
- obj->setInternalValue(jsBoolean(args.at(exec, 0)->toBoolean(exec)));
+ obj->setInternalValue(jsBoolean(args.at(exec, 0).toBoolean(exec)));
return obj;
}
@@ -57,9 +57,9 @@ ConstructType BooleanConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.6.1
-static JSValue* callBooleanConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr callBooleanConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsBoolean(args.at(exec, 0)->toBoolean(exec));
+ return jsBoolean(args.at(exec, 0).toBoolean(exec));
}
CallType BooleanConstructor::getCallData(CallData& callData)
@@ -68,7 +68,7 @@ CallType BooleanConstructor::getCallData(CallData& callData)
return CallTypeHost;
}
-JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValue* immediateBooleanValue)
+JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValuePtr immediateBooleanValue)
{
BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
obj->setInternalValue(immediateBooleanValue);
diff --git a/JavaScriptCore/runtime/BooleanConstructor.h b/JavaScriptCore/runtime/BooleanConstructor.h
index 3b1f1a0..db4e8e2 100644
--- a/JavaScriptCore/runtime/BooleanConstructor.h
+++ b/JavaScriptCore/runtime/BooleanConstructor.h
@@ -29,14 +29,14 @@ namespace JSC {
class BooleanConstructor : public InternalFunction {
public:
- BooleanConstructor(ExecState*, PassRefPtr<StructureID>, BooleanPrototype*);
+ BooleanConstructor(ExecState*, PassRefPtr<Structure>, BooleanPrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
};
- JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValue*);
+ JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValuePtr);
JSObject* constructBoolean(ExecState*, const ArgList&);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/BooleanObject.cpp b/JavaScriptCore/runtime/BooleanObject.cpp
index 2ebfb1b..01f695a 100644
--- a/JavaScriptCore/runtime/BooleanObject.cpp
+++ b/JavaScriptCore/runtime/BooleanObject.cpp
@@ -27,7 +27,7 @@ ASSERT_CLASS_FITS_IN_CELL(BooleanObject);
const ClassInfo BooleanObject::info = { "Boolean", 0, 0, 0 };
-BooleanObject::BooleanObject(PassRefPtr<StructureID> structure)
+BooleanObject::BooleanObject(PassRefPtr<Structure> structure)
: JSWrapperObject(structure)
{
}
diff --git a/JavaScriptCore/runtime/BooleanObject.h b/JavaScriptCore/runtime/BooleanObject.h
index 5963b28..68941e3 100644
--- a/JavaScriptCore/runtime/BooleanObject.h
+++ b/JavaScriptCore/runtime/BooleanObject.h
@@ -27,15 +27,15 @@ namespace JSC {
class BooleanObject : public JSWrapperObject {
public:
- explicit BooleanObject(PassRefPtr<StructureID>);
+ explicit BooleanObject(PassRefPtr<Structure>);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
};
- BooleanObject* asBooleanObject(JSValue*);
+ BooleanObject* asBooleanObject(JSValuePtr);
- inline BooleanObject* asBooleanObject(JSValue* value)
+ inline BooleanObject* asBooleanObject(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&BooleanObject::info));
return static_cast<BooleanObject*>(asObject(value));
diff --git a/JavaScriptCore/runtime/BooleanPrototype.cpp b/JavaScriptCore/runtime/BooleanPrototype.cpp
index b47aeac..9eb52d1 100644
--- a/JavaScriptCore/runtime/BooleanPrototype.cpp
+++ b/JavaScriptCore/runtime/BooleanPrototype.cpp
@@ -31,12 +31,12 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(BooleanPrototype);
// Functions
-static JSValue* booleanProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* booleanProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr booleanProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr booleanProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
// ECMA 15.6.4
-BooleanPrototype::BooleanPrototype(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure)
+BooleanPrototype::BooleanPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
: BooleanObject(structure)
{
setInternalValue(jsBoolean(false));
@@ -50,7 +50,7 @@ BooleanPrototype::BooleanPrototype(ExecState* exec, PassRefPtr<StructureID> stru
// ECMA 15.6.4.2 + 15.6.4.3
-JSValue* booleanProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr booleanProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
if (thisValue == jsBoolean(false))
return jsNontrivialString(exec, "false");
@@ -58,7 +58,7 @@ JSValue* booleanProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue
if (thisValue == jsBoolean(true))
return jsNontrivialString(exec, "true");
- if (!thisValue->isObject(&BooleanObject::info))
+ if (!thisValue.isObject(&BooleanObject::info))
return throwError(exec, TypeError);
if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false))
@@ -68,12 +68,12 @@ JSValue* booleanProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue
return jsNontrivialString(exec, "true");
}
-JSValue* booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (JSImmediate::isBoolean(thisValue))
+ if (thisValue.isBoolean())
return thisValue;
- if (!thisValue->isObject(&BooleanObject::info))
+ if (!thisValue.isObject(&BooleanObject::info))
return throwError(exec, TypeError);
return asBooleanObject(thisValue)->internalValue();
diff --git a/JavaScriptCore/runtime/BooleanPrototype.h b/JavaScriptCore/runtime/BooleanPrototype.h
index 484bb7d..16f80b5 100644
--- a/JavaScriptCore/runtime/BooleanPrototype.h
+++ b/JavaScriptCore/runtime/BooleanPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class BooleanPrototype : public BooleanObject {
public:
- BooleanPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
+ BooleanPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
};
} // namespace JSC
diff --git a/JavaScriptCore/runtime/CallData.cpp b/JavaScriptCore/runtime/CallData.cpp
index 572c495..fbb6392 100644
--- a/JavaScriptCore/runtime/CallData.cpp
+++ b/JavaScriptCore/runtime/CallData.cpp
@@ -30,7 +30,7 @@
namespace JSC {
-JSValue* call(ExecState* exec, JSValue* functionObject, CallType callType, const CallData& callData, JSValue* thisValue, const ArgList& args)
+JSValuePtr call(ExecState* exec, JSValuePtr functionObject, CallType callType, const CallData& callData, JSValuePtr thisValue, const ArgList& args)
{
if (callType == CallTypeHost)
return callData.native.function(exec, asObject(functionObject), thisValue, args);
diff --git a/JavaScriptCore/runtime/CallData.h b/JavaScriptCore/runtime/CallData.h
index 5be011a..b8d84cd 100644
--- a/JavaScriptCore/runtime/CallData.h
+++ b/JavaScriptCore/runtime/CallData.h
@@ -29,14 +29,13 @@
#ifndef CallData_h
#define CallData_h
-#include "JSImmediate.h"
-
namespace JSC {
class ArgList;
class ExecState;
class FunctionBodyNode;
class JSObject;
+ class JSValuePtr;
class ScopeChainNode;
enum CallType {
@@ -45,7 +44,7 @@ namespace JSC {
CallTypeJS
};
- typedef JSValue* (*NativeFunction)(ExecState*, JSObject*, JSValue* thisValue, const ArgList&);
+ typedef JSValuePtr (*NativeFunction)(ExecState*, JSObject*, JSValuePtr thisValue, const ArgList&);
union CallData {
struct {
@@ -57,7 +56,7 @@ namespace JSC {
} js;
};
- JSValue* call(ExecState*, JSValue* functionObject, CallType, const CallData&, JSValue* thisValue, const ArgList&);
+ JSValuePtr call(ExecState*, JSValuePtr functionObject, CallType, const CallData&, JSValuePtr thisValue, const ArgList&);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/ClassInfo.h b/JavaScriptCore/runtime/ClassInfo.h
index 979145e..097fb09 100644
--- a/JavaScriptCore/runtime/ClassInfo.h
+++ b/JavaScriptCore/runtime/ClassInfo.h
@@ -23,7 +23,7 @@
#ifndef ClassInfo_h
#define ClassInfo_h
-#include "ExecState.h"
+#include "CallFrame.h"
namespace JSC {
diff --git a/JavaScriptCore/kjs/collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 53e889e..13e7f51 100644
--- a/JavaScriptCore/kjs/collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -19,16 +19,17 @@
*/
#include "config.h"
-#include "collector.h"
+#include "Collector.h"
#include "ArgList.h"
+#include "CallFrame.h"
#include "CollectorHeapIterator.h"
-#include "ExecState.h"
+#include "Interpreter.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
#include "JSString.h"
#include "JSValue.h"
-#include "Machine.h"
+#include "Nodes.h"
#include "Tracing.h"
#include <algorithm>
#include <setjmp.h>
@@ -59,10 +60,6 @@
#include <thread.h>
#endif
-#if PLATFORM(LINUX)
-#include <pthread.h>
-#endif
-
#if PLATFORM(OPENBSD)
#include <pthread.h>
#endif
@@ -125,17 +122,12 @@ Heap::Heap(JSGlobalData* globalData)
: m_markListSet(0)
#if ENABLE(JSC_MULTIPLE_THREADS)
, m_registeredThreads(0)
+ , m_currentThreadRegistrar(0)
#endif
, m_globalData(globalData)
{
ASSERT(globalData);
-#if ENABLE(JSC_MULTIPLE_THREADS)
- int error = pthread_key_create(&m_currentThreadRegistrar, unregisterThread);
- if (error)
- CRASH();
-#endif
-
memset(&primaryHeap, 0, sizeof(CollectorHeap));
memset(&numberHeap, 0, sizeof(CollectorHeap));
}
@@ -169,11 +161,10 @@ void Heap::destroy()
freeHeap(&numberHeap);
#if ENABLE(JSC_MULTIPLE_THREADS)
-#ifndef NDEBUG
- int error =
-#endif
- pthread_key_delete(m_currentThreadRegistrar);
- ASSERT(!error);
+ if (m_currentThreadRegistrar) {
+ int error = pthread_key_delete(m_currentThreadRegistrar);
+ ASSERT_UNUSED(error, !error);
+ }
MutexLocker registeredThreadsLock(m_registeredThreadsMutex);
for (Heap::Thread* t = m_registeredThreads; t;) {
@@ -193,6 +184,10 @@ static NEVER_INLINE CollectorBlock* allocateBlock()
vm_address_t address = 0;
// FIXME: tag the region as a JavaScriptCore heap when we get a registered VM tag: <rdar://problem/6054788>.
vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
+#elif PLATFORM(SYMBIAN)
+ // no memory map in symbian, need to hack with fastMalloc
+ void* address = fastMalloc(BLOCK_SIZE);
+ memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE);
#elif PLATFORM(WIN_OS)
// windows virtual address granularity is naturally 64k
LPVOID address = VirtualAlloc(NULL, BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
@@ -235,6 +230,8 @@ static void freeBlock(CollectorBlock* block)
{
#if PLATFORM(DARWIN)
vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(block), BLOCK_SIZE);
+#elif PLATFORM(SYMBIAN)
+ fastFree(block);
#elif PLATFORM(WIN_OS)
VirtualFree(block, 0, MEM_RELEASE);
#elif HAVE(POSIX_MEMALIGN)
@@ -278,24 +275,23 @@ template <HeapType heapType> ALWAYS_INLINE void* Heap::heapAllocate(size_t s)
CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap;
ASSERT(JSLock::lockCount() > 0);
ASSERT(JSLock::currentThreadIsHoldingLock());
- ASSERT(s <= HeapConstants<heapType>::cellSize);
- UNUSED_PARAM(s); // s is now only used for the above assert
+ ASSERT_UNUSED(s, s <= HeapConstants<heapType>::cellSize);
ASSERT(heap.operationInProgress == NoOperation);
ASSERT(heapType == PrimaryHeap || heap.extraCost == 0);
// FIXME: If another global variable access here doesn't hurt performance
- // too much, we could abort() in NDEBUG builds, which could help ensure we
+ // too much, we could CRASH() in NDEBUG builds, which could help ensure we
// don't spend any time debugging cases where we allocate inside an object's
// deallocation code.
- size_t numLiveObjects = heap.numLiveObjects;
- size_t usedBlocks = heap.usedBlocks;
- size_t i = heap.firstBlockWithPossibleSpace;
-
#if COLLECT_ON_EVERY_ALLOCATION
collect();
#endif
+ size_t numLiveObjects = heap.numLiveObjects;
+ size_t usedBlocks = heap.usedBlocks;
+ size_t i = heap.firstBlockWithPossibleSpace;
+
// if we have a huge amount of extra cost, we'll try to collect even if we still have
// free cells left.
if (heapType == PrimaryHeap && heap.extraCost > ALLOCATIONS_PER_COLLECTION) {
@@ -436,7 +432,7 @@ static inline void* currentThreadStackBase()
if (stackBase == 0 || thread != stackThread) {
pthread_attr_t sattr;
pthread_attr_init(&sattr);
-#if HAVE(PTHREAD_NP_H)
+#if HAVE(PTHREAD_NP_H) || PLATFORM(NETBSD)
// e.g. on FreeBSD 5.4, neundorf@kde.org
pthread_attr_get_np(thread, &sattr);
#else
@@ -450,6 +446,15 @@ static inline void* currentThreadStackBase()
stackThread = thread;
}
return static_cast<char*>(stackBase) + stackSize;
+#elif PLATFORM(SYMBIAN)
+ static void* stackBase = 0;
+ if (stackBase == 0) {
+ TThreadStackInfo info;
+ RThread thread;
+ thread.StackInfo(info);
+ stackBase = (void*)info.iBase;
+ }
+ return (void*)stackBase;
#else
#error Need a way to get the stack base on this platform
#endif
@@ -467,9 +472,19 @@ static inline PlatformThread getCurrentPlatformThread()
#endif
}
+void Heap::makeUsableFromMultipleThreads()
+{
+ if (m_currentThreadRegistrar)
+ return;
+
+ int error = pthread_key_create(&m_currentThreadRegistrar, unregisterThread);
+ if (error)
+ CRASH();
+}
+
void Heap::registerThread()
{
- if (pthread_getspecific(m_currentThreadRegistrar))
+ if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar))
return;
pthread_setspecific(m_currentThreadRegistrar, this);
@@ -651,7 +666,7 @@ typedef CONTEXT PlatformThreadRegisters;
#error Need a thread register struct for this platform
#endif
-size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
+static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
{
#if PLATFORM(DARWIN)
@@ -789,45 +804,45 @@ void Heap::setGCProtectNeedsLocking()
m_protectedValuesMutex.set(new Mutex);
}
-void Heap::protect(JSValue* k)
+void Heap::protect(JSValuePtr k)
{
ASSERT(k);
ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
- if (JSImmediate::isImmediate(k))
+ if (!k.isCell())
return;
if (m_protectedValuesMutex)
m_protectedValuesMutex->lock();
- m_protectedValues.add(k->asCell());
+ m_protectedValues.add(k.asCell());
if (m_protectedValuesMutex)
m_protectedValuesMutex->unlock();
}
-void Heap::unprotect(JSValue* k)
+void Heap::unprotect(JSValuePtr k)
{
ASSERT(k);
ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
- if (JSImmediate::isImmediate(k))
+ if (!k.isCell())
return;
if (m_protectedValuesMutex)
m_protectedValuesMutex->lock();
- m_protectedValues.remove(k->asCell());
+ m_protectedValues.remove(k.asCell());
if (m_protectedValuesMutex)
m_protectedValuesMutex->unlock();
}
-Heap* Heap::heap(JSValue* v)
+Heap* Heap::heap(JSValuePtr v)
{
- if (JSImmediate::isImmediate(v))
+ if (!v.isCell())
return 0;
- return Heap::cellBlock(v->asCell())->heap;
+ return Heap::cellBlock(v.asCell())->heap;
}
void Heap::markProtectedObjects()
@@ -956,7 +971,7 @@ bool Heap::collect()
ASSERT((primaryHeap.operationInProgress == NoOperation) | (numberHeap.operationInProgress == NoOperation));
if ((primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation))
- abort();
+ CRASH();
JAVASCRIPTCORE_GC_BEGIN();
primaryHeap.operationInProgress = Collection;
@@ -968,18 +983,12 @@ bool Heap::collect()
markProtectedObjects();
if (m_markListSet && m_markListSet->size())
ArgList::markLists(*m_markListSet);
- if (m_globalData->exception && !m_globalData->exception->marked())
- m_globalData->exception->mark();
- m_globalData->machine->registerFile().markCallFrames(this);
+ if (m_globalData->exception && !m_globalData->exception.marked())
+ m_globalData->exception.mark();
+ m_globalData->interpreter->registerFile().markCallFrames(this);
m_globalData->smallStrings.mark();
-
- JSGlobalObject* globalObject = m_globalData->head;
- if (globalObject) {
- do {
- globalObject->markCrossHeapDependentObjects();
- globalObject = globalObject->next();
- } while (globalObject != m_globalData->head);
- }
+ if (m_globalData->scopeNodeBeingReparsed)
+ m_globalData->scopeNodeBeingReparsed->mark();
JAVASCRIPTCORE_GC_MARKED();
@@ -994,9 +1003,29 @@ bool Heap::collect()
return numLiveObjects < originalLiveObjects;
}
-size_t Heap::size()
+size_t Heap::objectCount()
+{
+ return primaryHeap.numLiveObjects + numberHeap.numLiveObjects - m_globalData->smallStrings.count();
+}
+
+template <HeapType heapType>
+static void addToStatistics(Heap::Statistics& statistics, const CollectorHeap& heap)
+{
+ typedef HeapConstants<heapType> HC;
+ for (size_t i = 0; i < heap.usedBlocks; ++i) {
+ if (heap.blocks[i]) {
+ statistics.size += BLOCK_SIZE;
+ statistics.free += (HC::cellsPerBlock - heap.blocks[i]->usedCells) * HC::cellSize;
+ }
+ }
+}
+
+Heap::Statistics Heap::statistics() const
{
- return primaryHeap.numLiveObjects + numberHeap.numLiveObjects;
+ Statistics statistics = { 0, 0 };
+ JSC::addToStatistics<PrimaryHeap>(statistics, primaryHeap);
+ JSC::addToStatistics<NumberHeap>(statistics, numberHeap);
+ return statistics;
}
size_t Heap::globalObjectCount()
@@ -1046,16 +1075,16 @@ size_t Heap::protectedObjectCount()
return result;
}
-static const char* typeName(JSCell* val)
+static const char* typeName(JSCell* cell)
{
- if (val->isString())
+ if (cell->isString())
return "string";
- if (val->isNumber())
+ if (cell->isNumber())
return "number";
- if (val->isGetterSetter())
+ if (cell->isGetterSetter())
return "gettersetter";
- ASSERT(val->isObject());
- const ClassInfo* info = static_cast<JSObject*>(val)->classInfo();
+ ASSERT(cell->isObject());
+ const ClassInfo* info = static_cast<JSObject*>(cell)->classInfo();
return info ? info->className : "Object";
}
diff --git a/JavaScriptCore/kjs/collector.h b/JavaScriptCore/runtime/Collector.h
index 4233b06..ba41d60 100644
--- a/JavaScriptCore/kjs/collector.h
+++ b/JavaScriptCore/runtime/Collector.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -19,10 +19,10 @@
*
*/
-#ifndef KJSCOLLECTOR_H_
-#define KJSCOLLECTOR_H_
+#ifndef Collector_h
+#define Collector_h
-#include "JSImmediate.h"
+#include <stddef.h>
#include <string.h>
#include <wtf/HashCountedSet.h>
#include <wtf/HashSet.h>
@@ -43,6 +43,7 @@ namespace JSC {
class CollectorBlock;
class JSCell;
class JSGlobalData;
+ class JSValuePtr;
enum OperationInProgress { NoOperation, Allocation, Collection };
enum HeapType { PrimaryHeap, NumberHeap };
@@ -87,13 +88,18 @@ namespace JSC {
void reportExtraMemoryCost(size_t cost);
- size_t size();
+ size_t objectCount();
+ struct Statistics {
+ size_t size;
+ size_t free;
+ };
+ Statistics statistics() const;
void setGCProtectNeedsLocking();
- void protect(JSValue*);
- void unprotect(JSValue*);
+ void protect(JSValuePtr);
+ void unprotect(JSValuePtr);
- static Heap* heap(JSValue*); // 0 for immediate values
+ static Heap* heap(JSValuePtr); // 0 for immediate values
size_t globalObjectCount();
size_t protectedObjectCount();
@@ -144,6 +150,8 @@ namespace JSC {
HashSet<ArgList*>* m_markListSet;
#if ENABLE(JSC_MULTIPLE_THREADS)
+ void makeUsableFromMultipleThreads();
+
static void unregisterThread(void*);
void unregisterThread();
@@ -276,4 +284,4 @@ namespace JSC {
} // namespace JSC
-#endif /* KJSCOLLECTOR_H_ */
+#endif /* Collector_h */
diff --git a/JavaScriptCore/runtime/CollectorHeapIterator.h b/JavaScriptCore/runtime/CollectorHeapIterator.h
index c5e1d78..e38a852 100644
--- a/JavaScriptCore/runtime/CollectorHeapIterator.h
+++ b/JavaScriptCore/runtime/CollectorHeapIterator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,7 +24,10 @@
*/
#include "config.h"
-#include "collector.h"
+#include "Collector.h"
+
+#ifndef CollectorHeapIterator_h
+#define CollectorHeapIterator_h
namespace JSC {
@@ -83,3 +86,5 @@ namespace JSC {
}
} // namespace JSC
+
+#endif // CollectorHeapIterator_h
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.h b/JavaScriptCore/runtime/CommonIdentifiers.h
index 1788c77..45b99a8 100644
--- a/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -21,7 +21,7 @@
#ifndef CommonIdentifiers_h
#define CommonIdentifiers_h
-#include "identifier.h"
+#include "Identifier.h"
#include <wtf/Noncopyable.h>
// ArgList of property names, passed to a macro so we can do set them up various
diff --git a/JavaScriptCore/kjs/interpreter.cpp b/JavaScriptCore/runtime/Completion.cpp
index 1188349..0231a15 100644
--- a/JavaScriptCore/kjs/interpreter.cpp
+++ b/JavaScriptCore/runtime/Completion.cpp
@@ -21,14 +21,13 @@
*/
#include "config.h"
-#include "interpreter.h"
+#include "Completion.h"
-#include "ExecState.h"
+#include "CallFrame.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "Parser.h"
-#include "completion.h"
#include "Debugger.h"
#include <stdio.h>
@@ -38,7 +37,7 @@
namespace JSC {
-Completion Interpreter::checkSyntax(ExecState* exec, const SourceCode& source)
+Completion checkSyntax(ExecState* exec, const SourceCode& source)
{
JSLock lock(exec);
@@ -51,7 +50,7 @@ Completion Interpreter::checkSyntax(ExecState* exec, const SourceCode& source)
return Completion(Normal);
}
-Completion Interpreter::evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue* thisValue)
+Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValuePtr thisValue)
{
JSLock lock(exec);
@@ -62,13 +61,13 @@ Completion Interpreter::evaluate(ExecState* exec, ScopeChain& scopeChain, const
if (!programNode)
return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
- JSObject* thisObj = (!thisValue || thisValue->isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue->toObject(exec);
+ JSObject* thisObj = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
- JSValue* exception = noValue();
- JSValue* result = exec->machine()->execute(programNode.get(), exec, scopeChain.node(), thisObj, &exception);
+ JSValuePtr exception = noValue();
+ JSValuePtr result = exec->interpreter()->execute(programNode.get(), exec, scopeChain.node(), thisObj, &exception);
if (exception) {
- if (exception->isObject() && asObject(exception)->isWatchdogException())
+ if (exception.isObject() && asObject(exception)->isWatchdogException())
return Completion(Interrupted, result);
return Completion(Throw, exception);
}
diff --git a/JavaScriptCore/kjs/completion.h b/JavaScriptCore/runtime/Completion.h
index 56d13ed..9631b50 100644
--- a/JavaScriptCore/kjs/completion.h
+++ b/JavaScriptCore/runtime/Completion.h
@@ -20,13 +20,17 @@
*
*/
-#ifndef KJS_COMPLETION_H
-#define KJS_COMPLETION_H
+#ifndef Completion_h
+#define Completion_h
#include "JSValue.h"
namespace JSC {
+ class ExecState;
+ class ScopeChain;
+ class SourceCode;
+
enum ComplType { Normal, Break, Continue, ReturnValue, Throw, Interrupted };
/*
@@ -35,22 +39,25 @@ namespace JSC {
*/
class Completion {
public:
- Completion(ComplType type = Normal, JSValue* value = noValue())
+ Completion(ComplType type = Normal, JSValuePtr value = noValue())
: m_type(type)
, m_value(value)
{
}
ComplType complType() const { return m_type; }
- JSValue* value() const { return m_value; }
- void setValue(JSValue* v) { m_value = v; }
- bool isValueCompletion() const { return !!m_value; }
+ JSValuePtr value() const { return m_value; }
+ void setValue(JSValuePtr v) { m_value = v; }
+ bool isValueCompletion() const { return m_value; }
private:
ComplType m_type;
- JSValue* m_value;
+ JSValuePtr m_value;
};
+ Completion checkSyntax(ExecState*, const SourceCode&);
+ Completion evaluate(ExecState*, ScopeChain&, const SourceCode&, JSValuePtr thisValue = noValue());
+
} // namespace JSC
-#endif // KJS_COMPLETION_H
+#endif // Completion_h
diff --git a/JavaScriptCore/runtime/ConstructData.cpp b/JavaScriptCore/runtime/ConstructData.cpp
index 88a8ef6..7a729ae 100644
--- a/JavaScriptCore/runtime/ConstructData.cpp
+++ b/JavaScriptCore/runtime/ConstructData.cpp
@@ -30,7 +30,7 @@
namespace JSC {
-JSObject* construct(ExecState* exec, JSValue* object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
+JSObject* construct(ExecState* exec, JSValuePtr object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
{
if (constructType == ConstructTypeHost)
return constructData.native.function(exec, asObject(object), args);
diff --git a/JavaScriptCore/runtime/ConstructData.h b/JavaScriptCore/runtime/ConstructData.h
index 3cc52a0..559c1bd 100644
--- a/JavaScriptCore/runtime/ConstructData.h
+++ b/JavaScriptCore/runtime/ConstructData.h
@@ -29,14 +29,13 @@
#ifndef ConstructData_h
#define ConstructData_h
-#include "JSImmediate.h" // temporary until JSValue* becomes a class we can forward-declare
-
namespace JSC {
class ArgList;
class ExecState;
class FunctionBodyNode;
class JSObject;
+ class JSValuePtr;
class ScopeChainNode;
enum ConstructType {
@@ -57,7 +56,7 @@ namespace JSC {
} js;
};
- JSObject* construct(ExecState*, JSValue* constructor, ConstructType, const ConstructData&, const ArgList&);
+ JSObject* construct(ExecState*, JSValuePtr constructor, ConstructType, const ConstructData&, const ArgList&);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp
index 8339ff3..92ab897 100644
--- a/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/JavaScriptCore/runtime/DateConstructor.cpp
@@ -47,11 +47,11 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(DateConstructor);
-static JSValue* dateParse(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateNow(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateUTC(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr dateParse(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateNow(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateUTC(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-DateConstructor::DateConstructor(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure, DatePrototype* datePrototype)
+DateConstructor::DateConstructor(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, DatePrototype* datePrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, datePrototype->classInfo()->className))
{
putDirectWithoutTransition(exec->propertyNames().prototype, datePrototype, DontEnum|DontDelete|ReadOnly);
@@ -73,35 +73,35 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
if (numArgs == 0) // new Date() ECMA 15.9.3.3
value = getCurrentUTCTime();
else if (numArgs == 1) {
- if (args.at(exec, 0)->isObject(&DateInstance::info))
+ if (args.at(exec, 0).isObject(&DateInstance::info))
value = asDateInstance(args.at(exec, 0))->internalNumber();
else {
- JSValue* primitive = args.at(exec, 0)->toPrimitive(exec);
- if (primitive->isString())
- value = parseDate(primitive->getString());
+ JSValuePtr primitive = args.at(exec, 0).toPrimitive(exec);
+ if (primitive.isString())
+ value = parseDate(primitive.getString());
else
- value = primitive->toNumber(exec);
+ value = primitive.toNumber(exec);
}
} else {
- if (isnan(args.at(exec, 0)->toNumber(exec))
- || isnan(args.at(exec, 1)->toNumber(exec))
- || (numArgs >= 3 && isnan(args.at(exec, 2)->toNumber(exec)))
- || (numArgs >= 4 && isnan(args.at(exec, 3)->toNumber(exec)))
- || (numArgs >= 5 && isnan(args.at(exec, 4)->toNumber(exec)))
- || (numArgs >= 6 && isnan(args.at(exec, 5)->toNumber(exec)))
- || (numArgs >= 7 && isnan(args.at(exec, 6)->toNumber(exec))))
+ if (isnan(args.at(exec, 0).toNumber(exec))
+ || isnan(args.at(exec, 1).toNumber(exec))
+ || (numArgs >= 3 && isnan(args.at(exec, 2).toNumber(exec)))
+ || (numArgs >= 4 && isnan(args.at(exec, 3).toNumber(exec)))
+ || (numArgs >= 5 && isnan(args.at(exec, 4).toNumber(exec)))
+ || (numArgs >= 6 && isnan(args.at(exec, 5).toNumber(exec)))
+ || (numArgs >= 7 && isnan(args.at(exec, 6).toNumber(exec))))
value = NaN;
else {
GregorianDateTime t;
- int year = args.at(exec, 0)->toInt32(exec);
+ int year = args.at(exec, 0).toInt32(exec);
t.year = (year >= 0 && year <= 99) ? year : year - 1900;
- t.month = args.at(exec, 1)->toInt32(exec);
- t.monthDay = (numArgs >= 3) ? args.at(exec, 2)->toInt32(exec) : 1;
- t.hour = args.at(exec, 3)->toInt32(exec);
- t.minute = args.at(exec, 4)->toInt32(exec);
- t.second = args.at(exec, 5)->toInt32(exec);
+ t.month = args.at(exec, 1).toInt32(exec);
+ t.monthDay = (numArgs >= 3) ? args.at(exec, 2).toInt32(exec) : 1;
+ t.hour = args.at(exec, 3).toInt32(exec);
+ t.minute = args.at(exec, 4).toInt32(exec);
+ t.second = args.at(exec, 5).toInt32(exec);
t.isDST = -1;
- double ms = (numArgs >= 7) ? args.at(exec, 6)->toNumber(exec) : 0;
+ double ms = (numArgs >= 7) ? args.at(exec, 6).toNumber(exec) : 0;
value = gregorianDateTimeToMS(t, ms, false);
}
}
@@ -123,7 +123,7 @@ ConstructType DateConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.9.2
-static JSValue* callDate(ExecState* exec, JSObject*, JSValue*, const ArgList&)
+static JSValuePtr callDate(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
{
time_t localTime = time(0);
tm localTM;
@@ -138,37 +138,37 @@ CallType DateConstructor::getCallData(CallData& callData)
return CallTypeHost;
}
-static JSValue* dateParse(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr dateParse(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, parseDate(args.at(exec, 0)->toString(exec)));
+ return jsNumber(exec, parseDate(args.at(exec, 0).toString(exec)));
}
-static JSValue* dateNow(ExecState* exec, JSObject*, JSValue*, const ArgList&)
+static JSValuePtr dateNow(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
{
return jsNumber(exec, getCurrentUTCTime());
}
-static JSValue* dateUTC(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr dateUTC(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
int n = args.size();
- if (isnan(args.at(exec, 0)->toNumber(exec))
- || isnan(args.at(exec, 1)->toNumber(exec))
- || (n >= 3 && isnan(args.at(exec, 2)->toNumber(exec)))
- || (n >= 4 && isnan(args.at(exec, 3)->toNumber(exec)))
- || (n >= 5 && isnan(args.at(exec, 4)->toNumber(exec)))
- || (n >= 6 && isnan(args.at(exec, 5)->toNumber(exec)))
- || (n >= 7 && isnan(args.at(exec, 6)->toNumber(exec))))
+ if (isnan(args.at(exec, 0).toNumber(exec))
+ || isnan(args.at(exec, 1).toNumber(exec))
+ || (n >= 3 && isnan(args.at(exec, 2).toNumber(exec)))
+ || (n >= 4 && isnan(args.at(exec, 3).toNumber(exec)))
+ || (n >= 5 && isnan(args.at(exec, 4).toNumber(exec)))
+ || (n >= 6 && isnan(args.at(exec, 5).toNumber(exec)))
+ || (n >= 7 && isnan(args.at(exec, 6).toNumber(exec))))
return jsNaN(exec);
GregorianDateTime t;
- int year = args.at(exec, 0)->toInt32(exec);
+ int year = args.at(exec, 0).toInt32(exec);
t.year = (year >= 0 && year <= 99) ? year : year - 1900;
- t.month = args.at(exec, 1)->toInt32(exec);
- t.monthDay = (n >= 3) ? args.at(exec, 2)->toInt32(exec) : 1;
- t.hour = args.at(exec, 3)->toInt32(exec);
- t.minute = args.at(exec, 4)->toInt32(exec);
- t.second = args.at(exec, 5)->toInt32(exec);
- double ms = (n >= 7) ? args.at(exec, 6)->toNumber(exec) : 0;
+ t.month = args.at(exec, 1).toInt32(exec);
+ t.monthDay = (n >= 3) ? args.at(exec, 2).toInt32(exec) : 1;
+ t.hour = args.at(exec, 3).toInt32(exec);
+ t.minute = args.at(exec, 4).toInt32(exec);
+ t.second = args.at(exec, 5).toInt32(exec);
+ double ms = (n >= 7) ? args.at(exec, 6).toNumber(exec) : 0;
return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
}
diff --git a/JavaScriptCore/runtime/DateConstructor.h b/JavaScriptCore/runtime/DateConstructor.h
index 1279f82..dcef3cc 100644
--- a/JavaScriptCore/runtime/DateConstructor.h
+++ b/JavaScriptCore/runtime/DateConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class DateConstructor : public InternalFunction {
public:
- DateConstructor(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure, DatePrototype*);
+ DateConstructor(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure, DatePrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/JavaScriptCore/runtime/DateInstance.cpp b/JavaScriptCore/runtime/DateInstance.cpp
index b38c6ef..8806dec 100644
--- a/JavaScriptCore/runtime/DateInstance.cpp
+++ b/JavaScriptCore/runtime/DateInstance.cpp
@@ -37,7 +37,7 @@ struct DateInstance::Cache {
const ClassInfo DateInstance::info = {"Date", 0, 0, 0};
-DateInstance::DateInstance(PassRefPtr<StructureID> structure)
+DateInstance::DateInstance(PassRefPtr<Structure> structure)
: JSWrapperObject(structure)
, m_cache(0)
{
diff --git a/JavaScriptCore/runtime/DateInstance.h b/JavaScriptCore/runtime/DateInstance.h
index 98f4b64..398f299 100644
--- a/JavaScriptCore/runtime/DateInstance.h
+++ b/JavaScriptCore/runtime/DateInstance.h
@@ -29,10 +29,10 @@ namespace JSC {
class DateInstance : public JSWrapperObject {
public:
- explicit DateInstance(PassRefPtr<StructureID>);
+ explicit DateInstance(PassRefPtr<Structure>);
virtual ~DateInstance();
- double internalNumber() const { return internalValue()->uncheckedGetNumber(); }
+ double internalNumber() const { return internalValue().uncheckedGetNumber(); }
bool getTime(GregorianDateTime&, int& offset) const;
bool getUTCTime(GregorianDateTime&) const;
@@ -52,9 +52,9 @@ namespace JSC {
mutable Cache* m_cache;
};
- DateInstance* asDateInstance(JSValue*);
+ DateInstance* asDateInstance(JSValuePtr);
- inline DateInstance* asDateInstance(JSValue* value)
+ inline DateInstance* asDateInstance(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&DateInstance::info));
return static_cast<DateInstance*>(asObject(value));
diff --git a/JavaScriptCore/runtime/DateMath.cpp b/JavaScriptCore/runtime/DateMath.cpp
index ec2a3f6..b452963 100644
--- a/JavaScriptCore/runtime/DateMath.cpp
+++ b/JavaScriptCore/runtime/DateMath.cpp
@@ -48,6 +48,7 @@
#include <time.h>
#include <wtf/ASCIICType.h>
#include <wtf/Assertions.h>
+#include <wtf/CurrentTime.h>
#include <wtf/MathExtras.h>
#include <wtf/StringExtras.h>
@@ -67,6 +68,10 @@
#include <sys/timeb.h>
#endif
+#if HAVE(STRINGS_H)
+#include <strings.h>
+#endif
+
using namespace WTF;
namespace JSC {
@@ -287,129 +292,15 @@ double getCurrentUTCTime()
return floor(getCurrentUTCTimeWithMicroseconds());
}
-#if PLATFORM(WIN_OS)
-
-static LARGE_INTEGER qpcFrequency;
-static bool syncedTime;
-
-static double highResUpTime()
-{
- // We use QPC, but only after sanity checking its result, due to bugs:
- // http://support.microsoft.com/kb/274323
- // http://support.microsoft.com/kb/895980
- // http://msdn.microsoft.com/en-us/library/ms644904.aspx ("...you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL)."
-
- static LARGE_INTEGER qpcLast;
- static DWORD tickCountLast;
- static bool inited;
-
- LARGE_INTEGER qpc;
- QueryPerformanceCounter(&qpc);
- DWORD tickCount = GetTickCount();
-
- if (inited) {
- __int64 qpcElapsed = ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFrequency.QuadPart;
- __int64 tickCountElapsed;
- if (tickCount >= tickCountLast)
- tickCountElapsed = (tickCount - tickCountLast);
- else {
-#if COMPILER(MINGW)
- __int64 tickCountLarge = tickCount + 0x100000000ULL;
-#else
- __int64 tickCountLarge = tickCount + 0x100000000I64;
-#endif
- tickCountElapsed = tickCountLarge - tickCountLast;
- }
-
- // force a re-sync if QueryPerformanceCounter differs from GetTickCount by more than 500ms.
- // (500ms value is from http://support.microsoft.com/kb/274323)
- __int64 diff = tickCountElapsed - qpcElapsed;
- if (diff > 500 || diff < -500)
- syncedTime = false;
- } else
- inited = true;
-
- qpcLast = qpc;
- tickCountLast = tickCount;
-
- return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart);;
-}
-
-static double lowResUTCTime()
-{
- struct _timeb timebuffer;
- _ftime(&timebuffer);
- return timebuffer.time * msPerSecond + timebuffer.millitm;
-}
-
-static bool qpcAvailable()
-{
- static bool available;
- static bool checked;
-
- if (checked)
- return available;
-
- available = QueryPerformanceFrequency(&qpcFrequency);
- checked = true;
- return available;
-}
-
-#endif
-
+// Returns current time in milliseconds since 1 Jan 1970.
double getCurrentUTCTimeWithMicroseconds()
{
-#if PLATFORM(WIN_OS)
- // Use a combination of ftime and QueryPerformanceCounter.
- // ftime returns the information we want, but doesn't have sufficient resolution.
- // QueryPerformanceCounter has high resolution, but is only usable to measure time intervals.
- // To combine them, we call ftime and QueryPerformanceCounter initially. Later calls will use QueryPerformanceCounter
- // by itself, adding the delta to the saved ftime. We periodically re-sync to correct for drift.
- static bool started;
- static double syncLowResUTCTime;
- static double syncHighResUpTime;
- static double lastUTCTime;
-
- double lowResTime = lowResUTCTime();
-
- if (!qpcAvailable())
- return lowResTime;
-
- double highResTime = highResUpTime();
-
- if (!syncedTime) {
- timeBeginPeriod(1); // increase time resolution around low-res time getter
- syncLowResUTCTime = lowResTime = lowResUTCTime();
- timeEndPeriod(1); // restore time resolution
- syncHighResUpTime = highResTime;
- syncedTime = true;
- }
-
- double highResElapsed = highResTime - syncHighResUpTime;
- double utc = syncLowResUTCTime + highResElapsed;
-
- // force a clock re-sync if we've drifted
- double lowResElapsed = lowResTime - syncLowResUTCTime;
- const double maximumAllowedDriftMsec = 15.625 * 2.0; // 2x the typical low-res accuracy
- if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec)
- syncedTime = false;
-
- // make sure time doesn't run backwards (only correct if difference is < 2 seconds, since DST or clock changes could occur)
- const double backwardTimeLimit = 2000.0;
- if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit)
- return lastUTCTime;
- lastUTCTime = utc;
-#else
- struct timeval tv;
- gettimeofday(&tv, 0);
- double utc = tv.tv_sec * msPerSecond + tv.tv_usec / 1000.0;
-#endif
- return utc;
+ return currentTime() * 1000.0;
}
void getLocalTime(const time_t* localTime, struct tm* localTM)
{
-#if COMPILER(MSVC7) || COMPILER(MINGW)
+#if COMPILER(MSVC7) || COMPILER(MINGW) || PLATFORM(WIN_CE)
*localTM = *localtime(localTime);
#elif COMPILER(MSVC)
localtime_s(localTM, localTime);
@@ -696,6 +587,15 @@ static int findMonth(const char* monthStr)
return -1;
}
+static bool parseLong(const char* string, char** stopPosition, int base, long* result)
+{
+ *result = strtol(string, stopPosition, base);
+ // Avoid the use of errno as it is not available on Windows CE
+ if (string == *stopPosition || *result == LONG_MIN || *result == LONG_MAX)
+ return false;
+ return true;
+}
+
double parseDate(const UString &date)
{
// This parses a date in the form:
@@ -741,10 +641,9 @@ double parseDate(const UString &date)
return NaN;
// ' 09-Nov-99 23:12:40 GMT'
- char *newPosStr;
- errno = 0;
- long day = strtol(dateString, &newPosStr, 10);
- if (errno)
+ char* newPosStr;
+ long day;
+ if (!parseLong(dateString, &newPosStr, 10, &day))
return NaN;
dateString = newPosStr;
@@ -763,22 +662,20 @@ double parseDate(const UString &date)
if (!*++dateString)
return NaN;
year = day;
- month = strtol(dateString, &newPosStr, 10) - 1;
- if (errno)
+ if (!parseLong(dateString, &newPosStr, 10, &month))
return NaN;
+ month -= 1;
dateString = newPosStr;
if (*dateString++ != '/' || !*dateString)
return NaN;
- day = strtol(dateString, &newPosStr, 10);
- if (errno)
+ if (!parseLong(dateString, &newPosStr, 10, &day))
return NaN;
dateString = newPosStr;
} else if (*dateString == '/' && month == -1) {
dateString++;
// This looks like a MM/DD/YYYY date, not an RFC date.
month = day - 1; // 0-based
- day = strtol(dateString, &newPosStr, 10);
- if (errno)
+ if (!parseLong(dateString, &newPosStr, 10, &day))
return NaN;
if (day < 1 || day > 31)
return NaN;
@@ -819,8 +716,7 @@ double parseDate(const UString &date)
// '99 23:12:40 GMT'
if (year <= 0 && *dateString) {
- year = strtol(dateString, &newPosStr, 10);
- if (errno)
+ if (!parseLong(dateString, &newPosStr, 10, &year))
return NaN;
}
@@ -843,7 +739,7 @@ double parseDate(const UString &date)
skipSpacesAndComments(dateString);
}
- hour = strtol(dateString, &newPosStr, 10);
+ parseLong(dateString, &newPosStr, 10, &hour);
// Do not check for errno here since we want to continue
// even if errno was set becasue we are still looking
// for the timezone!
@@ -862,8 +758,7 @@ double parseDate(const UString &date)
if (*dateString++ != ':')
return NaN;
- minute = strtol(dateString, &newPosStr, 10);
- if (errno)
+ if (!parseLong(dateString, &newPosStr, 10, &minute))
return NaN;
dateString = newPosStr;
@@ -878,8 +773,7 @@ double parseDate(const UString &date)
if (*dateString ==':') {
dateString++;
- second = strtol(dateString, &newPosStr, 10);
- if (errno)
+ if (!parseLong(dateString, &newPosStr, 10, &second))
return NaN;
dateString = newPosStr;
@@ -919,8 +813,8 @@ double parseDate(const UString &date)
}
if (*dateString == '+' || *dateString == '-') {
- long o = strtol(dateString, &newPosStr, 10);
- if (errno)
+ long o;
+ if (!parseLong(dateString, &newPosStr, 10, &o))
return NaN;
dateString = newPosStr;
@@ -932,8 +826,8 @@ double parseDate(const UString &date)
if (*dateString != ':') {
offset = ((o / 100) * 60 + (o % 100)) * sgn;
} else { // GMT+05:00
- long o2 = strtol(dateString, &newPosStr, 10);
- if (errno)
+ long o2;
+ if (!parseLong(dateString, &newPosStr, 10, &o2))
return NaN;
dateString = newPosStr;
offset = (o * 60 + o2) * sgn;
@@ -954,8 +848,7 @@ double parseDate(const UString &date)
skipSpacesAndComments(dateString);
if (*dateString && year == -1) {
- year = strtol(dateString, &newPosStr, 10);
- if (errno)
+ if (!parseLong(dateString, &newPosStr, 10, &year))
return NaN;
dateString = newPosStr;
}
diff --git a/JavaScriptCore/runtime/DateMath.h b/JavaScriptCore/runtime/DateMath.h
index ab939a7..8a15c80 100644
--- a/JavaScriptCore/runtime/DateMath.h
+++ b/JavaScriptCore/runtime/DateMath.h
@@ -113,7 +113,7 @@ struct GregorianDateTime : Noncopyable {
, year(inTm.tm_year)
, isDST(inTm.tm_isdst)
{
-#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS)
+#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !COMPILER(RVCT)
utcOffset = static_cast<int>(inTm.tm_gmtoff);
int inZoneSize = strlen(inTm.tm_zone) + 1;
@@ -140,7 +140,7 @@ struct GregorianDateTime : Noncopyable {
ret.tm_year = year;
ret.tm_isdst = isDST;
-#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS)
+#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !COMPILER(RVCT)
ret.tm_gmtoff = static_cast<long>(utcOffset);
ret.tm_zone = timeZone;
#endif
diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp
index a3e792e..b325070 100644
--- a/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/JavaScriptCore/runtime/DatePrototype.cpp
@@ -58,50 +58,49 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(DatePrototype);
-static JSValue* dateProtoFuncGetDate(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetDay(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetHours(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetMilliSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetTime(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetTimezoneOffset(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetUTCDate(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetUTCDay(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetUTCFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetUTCHours(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetUTCMilliseconds(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetUTCMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetUTCMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetUTCSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncGetYear(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetDate(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetHours(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetMilliSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetTime(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetUTCDate(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetUTCFullYear(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetUTCHours(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetUTCMilliseconds(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetUTCMinutes(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetUTCMonth(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetUTCSeconds(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncSetYear(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncToDateString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncToGMTString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncToLocaleDateString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncToLocaleTimeString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncToTimeString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncToUTCString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* dateProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr dateProtoFuncGetDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetDay(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetMilliSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetTime(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetTimezoneOffset(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetUTCDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetUTCDay(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetUTCFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetUTCHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetUTCMilliseconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetUTCMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetUTCMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetUTCSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncGetYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetMilliSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetTime(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetUTCDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetUTCFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetUTCHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetUTCMilliseconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetUTCMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetUTCMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetUTCSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncSetYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncToDateString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncToGMTString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncToLocaleDateString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncToLocaleTimeString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncToTimeString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr dateProtoFuncToUTCString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
}
@@ -109,8 +108,13 @@ static JSValue* dateProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgL
namespace JSC {
+enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime };
+
#if PLATFORM(MAC)
+// FIXME: Since this is superior to the strftime-based version, why limit this to PLATFORM(MAC)?
+// Instead we should consider using this whenever PLATFORM(CF) is true.
+
static CFDateFormatterStyle styleFromArgString(const UString& string, CFDateFormatterStyle defaultStyle)
{
if (string == "short")
@@ -124,24 +128,24 @@ static CFDateFormatterStyle styleFromArgString(const UString& string, CFDateForm
return defaultStyle;
}
-static UString formatLocaleDate(ExecState* exec, double time, bool includeDate, bool includeTime, const ArgList& args)
+static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMilliseconds, LocaleDateTimeFormat format, const ArgList& args)
{
- CFDateFormatterStyle dateStyle = (includeDate ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
- CFDateFormatterStyle timeStyle = (includeTime ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
+ CFDateFormatterStyle dateStyle = (format != LocaleTime ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
+ CFDateFormatterStyle timeStyle = (format != LocaleDate ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle);
bool useCustomFormat = false;
UString customFormatString;
- UString arg0String = args.at(exec, 0)->toString(exec);
- if (arg0String == "custom" && !args.at(exec, 1)->isUndefined()) {
+ UString arg0String = args.at(exec, 0).toString(exec);
+ if (arg0String == "custom" && !args.at(exec, 1).isUndefined()) {
useCustomFormat = true;
- customFormatString = args.at(exec, 1)->toString(exec);
- } else if (includeDate && includeTime && !args.at(exec, 1)->isUndefined()) {
+ customFormatString = args.at(exec, 1).toString(exec);
+ } else if (format == LocaleDateAndTime && !args.at(exec, 1).isUndefined()) {
dateStyle = styleFromArgString(arg0String, dateStyle);
- timeStyle = styleFromArgString(args.at(exec, 1)->toString(exec), timeStyle);
- } else if (includeDate && !args.at(exec, 0)->isUndefined())
+ timeStyle = styleFromArgString(args.at(exec, 1).toString(exec), timeStyle);
+ } else if (format != LocaleTime && !args.at(exec, 0).isUndefined())
dateStyle = styleFromArgString(arg0String, dateStyle);
- else if (includeTime && !args.at(exec, 0)->isUndefined())
+ else if (format != LocaleDate && !args.at(exec, 0).isUndefined())
timeStyle = styleFromArgString(arg0String, timeStyle);
CFLocaleRef locale = CFLocaleCopyCurrent();
@@ -149,12 +153,12 @@ static UString formatLocaleDate(ExecState* exec, double time, bool includeDate,
CFRelease(locale);
if (useCustomFormat) {
- CFStringRef customFormatCFString = CFStringCreateWithCharacters(0, (UniChar *)customFormatString.data(), customFormatString.size());
+ CFStringRef customFormatCFString = CFStringCreateWithCharacters(0, customFormatString.data(), customFormatString.size());
CFDateFormatterSetFormat(formatter, customFormatCFString);
CFRelease(customFormatCFString);
}
- CFStringRef string = CFDateFormatterCreateStringWithAbsoluteTime(0, formatter, time - kCFAbsoluteTimeIntervalSince1970);
+ CFStringRef string = CFDateFormatterCreateStringWithAbsoluteTime(0, formatter, floor(timeInMilliseconds / msPerSecond) - kCFAbsoluteTimeIntervalSince1970);
CFRelease(formatter);
@@ -166,20 +170,18 @@ static UString formatLocaleDate(ExecState* exec, double time, bool includeDate,
ASSERT(length <= bufferLength);
if (length > bufferLength)
length = bufferLength;
- CFStringGetCharacters(string, CFRangeMake(0, length), reinterpret_cast<UniChar *>(buffer));
+ CFStringGetCharacters(string, CFRangeMake(0, length), buffer);
CFRelease(string);
- return UString(buffer, length);
+ return jsNontrivialString(exec, UString(buffer, length));
}
-#else
+#else // !PLATFORM(MAC)
-enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime };
-
-static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, const LocaleDateTimeFormat format)
+static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, LocaleDateTimeFormat format)
{
- static const char* formatStrings[] = {"%#c", "%#x", "%X"};
+ static const char* const formatStrings[] = { "%#c", "%#x", "%X" };
// Offset year if needed
struct tm localTM = gdt;
@@ -211,7 +213,15 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, c
return jsNontrivialString(exec, timebuffer);
}
-#endif // PLATFORM(WIN_OS)
+static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double timeInMilliseconds, LocaleDateTimeFormat format, const ArgList&)
+{
+ GregorianDateTime gregorianDateTime;
+ const bool notUTC = false;
+ dateObject->msToGregorianDateTime(timeInMilliseconds, notUTC, gregorianDateTime);
+ return formatLocaleDate(exec, gregorianDateTime, format);
+}
+
+#endif // !PLATFORM(MAC)
// Converts a list of arguments sent to a Date member function into milliseconds, updating
// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately.
@@ -231,19 +241,19 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, const ArgList& args, in
// hours
if (maxArgs >= 4 && idx < numArgs) {
t->hour = 0;
- milliseconds += args.at(exec, idx++)->toInt32(exec, ok) * msPerHour;
+ milliseconds += args.at(exec, idx++).toInt32(exec, ok) * msPerHour;
}
// minutes
if (maxArgs >= 3 && idx < numArgs && ok) {
t->minute = 0;
- milliseconds += args.at(exec, idx++)->toInt32(exec, ok) * msPerMinute;
+ milliseconds += args.at(exec, idx++).toInt32(exec, ok) * msPerMinute;
}
// seconds
if (maxArgs >= 2 && idx < numArgs && ok) {
t->second = 0;
- milliseconds += args.at(exec, idx++)->toInt32(exec, ok) * msPerSecond;
+ milliseconds += args.at(exec, idx++).toInt32(exec, ok) * msPerSecond;
}
if (!ok)
@@ -251,7 +261,7 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, const ArgList& args, in
// milliseconds
if (idx < numArgs) {
- double millis = args.at(exec, idx)->toNumber(exec);
+ double millis = args.at(exec, idx).toNumber(exec);
ok = isfinite(millis);
milliseconds += millis;
} else
@@ -277,16 +287,16 @@ static bool fillStructuresUsingDateArgs(ExecState *exec, const ArgList& args, in
// years
if (maxArgs >= 3 && idx < numArgs)
- t->year = args.at(exec, idx++)->toInt32(exec, ok) - 1900;
+ t->year = args.at(exec, idx++).toInt32(exec, ok) - 1900;
// months
if (maxArgs >= 2 && idx < numArgs && ok)
- t->month = args.at(exec, idx++)->toInt32(exec, ok);
+ t->month = args.at(exec, idx++).toInt32(exec, ok);
// days
if (idx < numArgs && ok) {
t->monthDay = 0;
- *ms += args.at(exec, idx)->toInt32(exec, ok) * msPerDay;
+ *ms += args.at(exec, idx).toInt32(exec, ok) * msPerDay;
}
return ok;
@@ -295,7 +305,6 @@ static bool fillStructuresUsingDateArgs(ExecState *exec, const ArgList& args, in
const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState::dateTable};
/* Source for DatePrototype.lut.h
- FIXME: We could use templates to simplify the UTC variants.
@begin dateTable
toString dateProtoFuncToString DontEnum|Function 0
toUTCString dateProtoFuncToUTCString DontEnum|Function 0
@@ -304,7 +313,7 @@ const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState
toLocaleString dateProtoFuncToLocaleString DontEnum|Function 0
toLocaleDateString dateProtoFuncToLocaleDateString DontEnum|Function 0
toLocaleTimeString dateProtoFuncToLocaleTimeString DontEnum|Function 0
- valueOf dateProtoFuncValueOf DontEnum|Function 0
+ valueOf dateProtoFuncGetTime DontEnum|Function 0
getTime dateProtoFuncGetTime DontEnum|Function 0
getFullYear dateProtoFuncGetFullYear DontEnum|Function 0
getUTCFullYear dateProtoFuncGetUTCFullYear DontEnum|Function 0
@@ -343,9 +352,10 @@ const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState
getYear dateProtoFuncGetYear DontEnum|Function 0
@end
*/
+
// ECMA 15.9.4
-DatePrototype::DatePrototype(ExecState* exec, PassRefPtr<StructureID> structure)
+DatePrototype::DatePrototype(ExecState* exec, PassRefPtr<Structure> structure)
: DateInstance(structure)
{
setInternalValue(jsNaN(exec));
@@ -359,9 +369,9 @@ bool DatePrototype::getOwnPropertySlot(ExecState* exec, const Identifier& proper
// Functions
-JSValue* dateProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -376,9 +386,9 @@ JSValue* dateProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, c
return jsNontrivialString(exec, formatDate(t) + " " + formatTime(t, utc));
}
-JSValue* dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -393,9 +403,9 @@ JSValue* dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue* thisValue
return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
}
-JSValue* dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -410,9 +420,9 @@ JSValue* dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValue* thisValu
return jsNontrivialString(exec, formatDate(t));
}
-JSValue* dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -427,9 +437,9 @@ JSValue* dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue* thisValu
return jsNontrivialString(exec, formatTime(t, utc));
}
-JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -437,23 +447,12 @@ JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisVa
if (isnan(milli))
return jsNontrivialString(exec, "Invalid Date");
-#if PLATFORM(MAC)
- double secs = floor(milli / msPerSecond);
- return jsNontrivialString(exec, formatLocaleDate(exec, secs, true, true, args));
-#else
- UNUSED_PARAM(args);
-
- const bool utc = false;
-
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return formatLocaleDate(exec, t, LocaleDateAndTime);
-#endif
+ return formatLocaleDate(exec, thisDateObj, milli, LocaleDateAndTime, args);
}
-JSValue* dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -461,23 +460,12 @@ JSValue* dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue* th
if (isnan(milli))
return jsNontrivialString(exec, "Invalid Date");
-#if PLATFORM(MAC)
- double secs = floor(milli / msPerSecond);
- return jsNontrivialString(exec, formatLocaleDate(exec, secs, true, false, args));
-#else
- UNUSED_PARAM(args);
-
- const bool utc = false;
-
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return formatLocaleDate(exec, t, LocaleDate);
-#endif
+ return formatLocaleDate(exec, thisDateObj, milli, LocaleDate, args);
}
-JSValue* dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -485,36 +473,12 @@ JSValue* dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue* th
if (isnan(milli))
return jsNontrivialString(exec, "Invalid Date");
-#if PLATFORM(MAC)
- double secs = floor(milli / msPerSecond);
- return jsNontrivialString(exec, formatLocaleDate(exec, secs, false, true, args));
-#else
- UNUSED_PARAM(args);
-
- const bool utc = false;
-
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return formatLocaleDate(exec, t, LocaleTime);
-#endif
-}
-
-JSValue* dateProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
-{
- if (!thisValue->isObject(&DateInstance::info))
- return throwError(exec, TypeError);
-
- DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
-
- return jsNumber(exec, milli);
+ return formatLocaleDate(exec, thisDateObj, milli, LocaleTime, args);
}
-JSValue* dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -525,9 +489,9 @@ JSValue* dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue* thisValue, co
return jsNumber(exec, milli);
}
-JSValue* dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -542,9 +506,9 @@ JSValue* dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue* thisValue
return jsNumber(exec, 1900 + t.year);
}
-JSValue* dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -559,9 +523,9 @@ JSValue* dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValue* thisVa
return jsNumber(exec, 1900 + t.year);
}
-JSValue* dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -576,9 +540,9 @@ JSValue* dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue* thisValue
return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
}
-JSValue* dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -593,9 +557,9 @@ JSValue* dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue* thisValue, c
return jsNumber(exec, t.month);
}
-JSValue* dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -610,9 +574,9 @@ JSValue* dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValue* thisValue
return jsNumber(exec, t.month);
}
-JSValue* dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -627,9 +591,9 @@ JSValue* dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue* thisValue, co
return jsNumber(exec, t.monthDay);
}
-JSValue* dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -644,9 +608,9 @@ JSValue* dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValue* thisValue,
return jsNumber(exec, t.monthDay);
}
-JSValue* dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -661,9 +625,9 @@ JSValue* dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue* thisValue, con
return jsNumber(exec, t.weekDay);
}
-JSValue* dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -678,9 +642,9 @@ JSValue* dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue* thisValue,
return jsNumber(exec, t.weekDay);
}
-JSValue* dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -695,9 +659,9 @@ JSValue* dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue* thisValue, c
return jsNumber(exec, t.hour);
}
-JSValue* dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -712,9 +676,9 @@ JSValue* dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValue* thisValue
return jsNumber(exec, t.hour);
}
-JSValue* dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -729,9 +693,9 @@ JSValue* dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValue* thisValue,
return jsNumber(exec, t.minute);
}
-JSValue* dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -746,9 +710,9 @@ JSValue* dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValue* thisVal
return jsNumber(exec, t.minute);
}
-JSValue* dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -763,9 +727,9 @@ JSValue* dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValue* thisValue,
return jsNumber(exec, t.second);
}
-JSValue* dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = true;
@@ -780,9 +744,9 @@ JSValue* dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue* thisVal
return jsNumber(exec, t.second);
}
-JSValue* dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -795,9 +759,9 @@ JSValue* dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValue* thisV
return jsNumber(exec, ms);
}
-JSValue* dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
@@ -810,9 +774,9 @@ JSValue* dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValue* th
return jsNumber(exec, ms);
}
-JSValue* dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
@@ -827,29 +791,29 @@ JSValue* dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue* thi
return jsNumber(exec, -gmtoffset(t) / minutesPerHour);
}
-JSValue* dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = timeClip(args.at(exec, 0)->toNumber(exec));
- JSValue* result = jsNumber(exec, milli);
+ double milli = timeClip(args.at(exec, 0).toNumber(exec));
+ JSValuePtr result = jsNumber(exec, milli);
thisDateObj->setInternalValue(result);
return result;
}
-static JSValue* setNewValueFromTimeArgs(ExecState* exec, JSValue* thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
+static JSValuePtr setNewValueFromTimeArgs(ExecState* exec, JSValuePtr thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
double milli = thisDateObj->internalNumber();
if (args.isEmpty() || isnan(milli)) {
- JSValue* result = jsNaN(exec);
+ JSValuePtr result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
@@ -861,24 +825,24 @@ static JSValue* setNewValueFromTimeArgs(ExecState* exec, JSValue* thisValue, con
thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t);
if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) {
- JSValue* result = jsNaN(exec);
+ JSValuePtr result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
- JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
+ JSValuePtr result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
-static JSValue* setNewValueFromDateArgs(ExecState* exec, JSValue* thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
+static JSValuePtr setNewValueFromDateArgs(ExecState* exec, JSValuePtr thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
if (args.isEmpty()) {
- JSValue* result = jsNaN(exec);
+ JSValuePtr result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
@@ -898,110 +862,110 @@ static JSValue* setNewValueFromDateArgs(ExecState* exec, JSValue* thisValue, con
}
if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) {
- JSValue* result = jsNaN(exec);
+ JSValuePtr result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
- JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
+ JSValuePtr result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
-JSValue* dateProtoFuncSetMilliSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetMilliSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
}
-JSValue* dateProtoFuncSetUTCMilliseconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetUTCMilliseconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
}
-JSValue* dateProtoFuncSetSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
}
-JSValue* dateProtoFuncSetUTCSeconds(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetUTCSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
}
-JSValue* dateProtoFuncSetMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
}
-JSValue* dateProtoFuncSetUTCMinutes(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetUTCMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
}
-JSValue* dateProtoFuncSetHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
}
-JSValue* dateProtoFuncSetUTCHours(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetUTCHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
}
-JSValue* dateProtoFuncSetDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
}
-JSValue* dateProtoFuncSetUTCDate(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetUTCDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
}
-JSValue* dateProtoFuncSetMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
}
-JSValue* dateProtoFuncSetUTCMonth(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetUTCMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
}
-JSValue* dateProtoFuncSetFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = false;
return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
}
-JSValue* dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
const bool inputIsUTC = true;
return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
}
-JSValue* dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
DateInstance* thisDateObj = asDateInstance(thisValue);
if (args.isEmpty()) {
- JSValue* result = jsNaN(exec);
+ JSValuePtr result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
@@ -1021,22 +985,22 @@ JSValue* dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue* thisValue, co
}
bool ok = true;
- int32_t year = args.at(exec, 0)->toInt32(exec, ok);
+ int32_t year = args.at(exec, 0).toInt32(exec, ok);
if (!ok) {
- JSValue* result = jsNaN(exec);
+ JSValuePtr result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
t.year = (year > 99 || year < 0) ? year - 1900 : year;
- JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc));
+ JSValuePtr result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc));
thisDateObj->setInternalValue(result);
return result;
}
-JSValue* dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&DateInstance::info))
+ if (!thisValue.isObject(&DateInstance::info))
return throwError(exec, TypeError);
const bool utc = false;
diff --git a/JavaScriptCore/runtime/DatePrototype.h b/JavaScriptCore/runtime/DatePrototype.h
index 500b40d..a6bbdf2 100644
--- a/JavaScriptCore/runtime/DatePrototype.h
+++ b/JavaScriptCore/runtime/DatePrototype.h
@@ -29,16 +29,16 @@ namespace JSC {
class DatePrototype : public DateInstance {
public:
- DatePrototype(ExecState*, PassRefPtr<StructureID>);
+ DatePrototype(ExecState*, PassRefPtr<Structure>);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType));
}
};
diff --git a/JavaScriptCore/runtime/ErrorConstructor.cpp b/JavaScriptCore/runtime/ErrorConstructor.cpp
index 3c83fd4..5cc0df0 100644
--- a/JavaScriptCore/runtime/ErrorConstructor.cpp
+++ b/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -29,7 +29,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ErrorConstructor);
-ErrorConstructor::ErrorConstructor(ExecState* exec, PassRefPtr<StructureID> structure, ErrorPrototype* errorPrototype)
+ErrorConstructor::ErrorConstructor(ExecState* exec, PassRefPtr<Structure> structure, ErrorPrototype* errorPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, errorPrototype->classInfo()->className))
{
// ECMA 15.11.3.1 Error.prototype
@@ -41,8 +41,8 @@ ErrorConstructor::ErrorConstructor(ExecState* exec, PassRefPtr<StructureID> stru
ErrorInstance* constructError(ExecState* exec, const ArgList& args)
{
ErrorInstance* obj = new (exec) ErrorInstance(exec->lexicalGlobalObject()->errorStructure());
- if (!args.at(exec, 0)->isUndefined())
- obj->putDirect(exec->propertyNames().message, jsString(exec, args.at(exec, 0)->toString(exec)));
+ if (!args.at(exec, 0).isUndefined())
+ obj->putDirect(exec->propertyNames().message, jsString(exec, args.at(exec, 0).toString(exec)));
return obj;
}
@@ -58,7 +58,7 @@ ConstructType ErrorConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.9.2
-static JSValue* callErrorConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr callErrorConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
// "Error()" gives the sames result as "new Error()"
return constructError(exec, args);
diff --git a/JavaScriptCore/runtime/ErrorConstructor.h b/JavaScriptCore/runtime/ErrorConstructor.h
index 45e4bb0..2dd4124 100644
--- a/JavaScriptCore/runtime/ErrorConstructor.h
+++ b/JavaScriptCore/runtime/ErrorConstructor.h
@@ -30,7 +30,7 @@ namespace JSC {
class ErrorConstructor : public InternalFunction {
public:
- ErrorConstructor(ExecState*, PassRefPtr<StructureID>, ErrorPrototype*);
+ ErrorConstructor(ExecState*, PassRefPtr<Structure>, ErrorPrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/JavaScriptCore/runtime/ErrorInstance.cpp b/JavaScriptCore/runtime/ErrorInstance.cpp
index 1c55856..2e2cdce 100644
--- a/JavaScriptCore/runtime/ErrorInstance.cpp
+++ b/JavaScriptCore/runtime/ErrorInstance.cpp
@@ -25,7 +25,7 @@ namespace JSC {
const ClassInfo ErrorInstance::info = { "Error", 0, 0, 0 };
-ErrorInstance::ErrorInstance(PassRefPtr<StructureID> structure)
+ErrorInstance::ErrorInstance(PassRefPtr<Structure> structure)
: JSObject(structure)
{
}
diff --git a/JavaScriptCore/runtime/ErrorInstance.h b/JavaScriptCore/runtime/ErrorInstance.h
index 8d86eec..6f9d262 100644
--- a/JavaScriptCore/runtime/ErrorInstance.h
+++ b/JavaScriptCore/runtime/ErrorInstance.h
@@ -27,7 +27,7 @@ namespace JSC {
class ErrorInstance : public JSObject {
public:
- explicit ErrorInstance(PassRefPtr<StructureID>);
+ explicit ErrorInstance(PassRefPtr<Structure>);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
diff --git a/JavaScriptCore/runtime/ErrorPrototype.cpp b/JavaScriptCore/runtime/ErrorPrototype.cpp
index 69255c1..8703d81 100644
--- a/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -24,16 +24,16 @@
#include "JSString.h"
#include "ObjectPrototype.h"
#include "PrototypeFunction.h"
-#include "ustring.h"
+#include "UString.h"
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
-static JSValue* errorProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr errorProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
// ECMA 15.9.4
-ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure)
+ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
: ErrorInstance(structure)
{
// The constructor will be added later in ErrorConstructor's constructor
@@ -44,21 +44,21 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<StructureID> structur
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
}
-JSValue* errorProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr errorProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
UString s = "Error";
- JSValue* v = thisObj->get(exec, exec->propertyNames().name);
- if (!v->isUndefined())
- s = v->toString(exec);
+ JSValuePtr v = thisObj->get(exec, exec->propertyNames().name);
+ if (!v.isUndefined())
+ s = v.toString(exec);
v = thisObj->get(exec, exec->propertyNames().message);
- if (!v->isUndefined()) {
+ if (!v.isUndefined()) {
// Mozilla-compatible format.
s += ": ";
- s += v->toString(exec);
+ s += v.toString(exec);
}
return jsNontrivialString(exec, s);
diff --git a/JavaScriptCore/runtime/ErrorPrototype.h b/JavaScriptCore/runtime/ErrorPrototype.h
index 255ea11..53d12d9 100644
--- a/JavaScriptCore/runtime/ErrorPrototype.h
+++ b/JavaScriptCore/runtime/ErrorPrototype.h
@@ -29,7 +29,7 @@ namespace JSC {
class ErrorPrototype : public ErrorInstance {
public:
- ErrorPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
+ ErrorPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
};
} // namespace JSC
diff --git a/JavaScriptCore/VM/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp
index 0ad332d..d1b5aac 100644
--- a/JavaScriptCore/VM/ExceptionHelpers.cpp
+++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,24 +30,15 @@
#include "ExceptionHelpers.h"
#include "CodeBlock.h"
-#include "ExecState.h"
+#include "CallFrame.h"
+#include "JSGlobalObjectFunctions.h"
#include "JSObject.h"
#include "JSNotAnObject.h"
-#include "Machine.h"
-#include "nodes.h"
+#include "Interpreter.h"
+#include "Nodes.h"
namespace JSC {
-static void substitute(UString& string, const UString& substring)
-{
- int position = string.find("%s");
- ASSERT(position != -1);
- UString newString = string.substr(0, position);
- newString.append(substring);
- newString.append(string.substr(position + 2));
- string = newString;
-}
-
class InterruptedExecutionError : public JSObject {
public:
InterruptedExecutionError(JSGlobalData* globalData)
@@ -58,56 +49,40 @@ public:
virtual bool isWatchdogException() const { return true; }
};
-JSValue* createInterruptedExecutionException(JSGlobalData* globalData)
+JSValuePtr createInterruptedExecutionException(JSGlobalData* globalData)
{
return new (globalData) InterruptedExecutionError(globalData);
}
-JSValue* createError(ExecState* exec, ErrorType e, const char* msg)
+static JSValuePtr createError(ExecState* exec, ErrorType e, const char* msg)
{
return Error::create(exec, e, msg, -1, -1, 0);
}
-JSValue* createError(ExecState* exec, ErrorType e, const char* msg, const Identifier& label)
-{
- UString message = msg;
- substitute(message, label.ustring());
- return Error::create(exec, e, message, -1, -1, 0);
-}
-
-JSValue* createError(ExecState* exec, ErrorType e, const char* msg, JSValue* v)
-{
- UString message = msg;
- substitute(message, v->toString(exec));
- return Error::create(exec, e, message, -1, -1, 0);
-}
-
-JSValue* createStackOverflowError(ExecState* exec)
+JSValuePtr createStackOverflowError(ExecState* exec)
{
return createError(exec, RangeError, "Maximum call stack size exceeded.");
}
-JSValue* createUndefinedVariableError(ExecState* exec, const Identifier& ident, const Instruction* vPC, CodeBlock* codeBlock)
+JSValuePtr createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
- int line = codeBlock->expressionRangeForVPC(vPC, divotPoint, startOffset, endOffset);
+ int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
UString message = "Can't find variable: ";
message.append(ident.ustring());
- JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->sourceURL());
+ JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
return exception;
}
-bool isStrWhiteSpace(UChar c);
-
-static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValue* value, UString error)
+static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValuePtr value, UString error)
{
- if (!expressionStop || expressionStart > codeBlock->source->length()) {
- UString errorText = value->toString(exec);
+ if (!expressionStop || expressionStart > codeBlock->source()->length()) {
+ UString errorText = value.toString(exec);
errorText.append(" is ");
errorText.append(error);
return errorText;
@@ -117,14 +92,14 @@ static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, in
if (expressionStart < expressionStop) {
errorText.append('\'');
- errorText.append(codeBlock->source->getRange(expressionStart, expressionStop));
+ errorText.append(codeBlock->source()->getRange(expressionStart, expressionStop));
errorText.append("' [");
- errorText.append(value->toString(exec));
+ errorText.append(value.toString(exec));
errorText.append("] is ");
} else {
// No range information, so give a few characters of context
- const UChar* data = codeBlock->source->data();
- int dataLength = codeBlock->source->length();
+ const UChar* data = codeBlock->source()->data();
+ int dataLength = codeBlock->source()->length();
int start = expressionStart;
int stop = expressionStart;
// Get up to 20 characters of context to the left and right of the divot, clamping to the line.
@@ -138,9 +113,9 @@ static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, in
while (stop > expressionStart && isStrWhiteSpace(data[stop]))
stop--;
errorText.append("near '...");
- errorText.append(codeBlock->source->getRange(start, stop));
+ errorText.append(codeBlock->source()->getRange(start, stop));
errorText.append("...' [");
- errorText.append(value->toString(exec));
+ errorText.append(value.toString(exec));
errorText.append("] is ");
}
errorText.append(error);
@@ -148,7 +123,7 @@ static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, in
return errorText;
}
-JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue* value, const Instruction* vPC, CodeBlock* codeBlock)
+JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValuePtr value, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
UString message = "not a valid argument for '";
message.append(op);
@@ -157,44 +132,44 @@ JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue* valu
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
- int line = codeBlock->expressionRangeForVPC(vPC, divotPoint, startOffset, endOffset);
+ int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, message);
- JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->sourceURL());
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
return exception;
}
-JSObject* createNotAConstructorError(ExecState* exec, JSValue* value, const Instruction* vPC, CodeBlock* codeBlock)
+JSObject* createNotAConstructorError(ExecState* exec, JSValuePtr value, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
- int line = codeBlock->expressionRangeForVPC(vPC, divotPoint, startOffset, endOffset);
+ int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
// We're in a "new" expression, so we need to skip over the "new.." part
int startPoint = divotPoint - (startOffset ? startOffset - 4 : 0); // -4 for "new "
- const UChar* data = codeBlock->source->data();
+ const UChar* data = codeBlock->source()->data();
while (startPoint < divotPoint && isStrWhiteSpace(data[startPoint]))
startPoint++;
UString errorMessage = createErrorMessage(exec, codeBlock, line, startPoint, divotPoint, value, "not a constructor");
- JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->sourceURL());
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
return exception;
}
-JSValue* createNotAFunctionError(ExecState* exec, JSValue* value, const Instruction* vPC, CodeBlock* codeBlock)
+JSValuePtr createNotAFunctionError(ExecState* exec, JSValuePtr value, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
- int line = codeBlock->expressionRangeForVPC(vPC, divotPoint, startOffset, endOffset);
+ int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, value, "not a function");
- JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->sourceURL());
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
@@ -206,19 +181,25 @@ JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState* exec, bool isNull)
return new (exec) JSNotAnObjectErrorStub(exec, isNull);
}
-JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error, const Instruction* vPC, CodeBlock* codeBlock)
+JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
- if (vPC[8].u.opcode == exec->machine()->getOpcode(op_instanceof))
- return createInvalidParamError(exec, "instanceof", error->isNull() ? jsNull() : jsUndefined(), vPC, codeBlock);
- if (vPC[8].u.opcode == exec->machine()->getOpcode(op_construct))
- return createNotAConstructorError(exec, error->isNull() ? jsNull() : jsUndefined(), vPC, codeBlock);
+ // Both op_construct and op_instanceof require a use of op_get_by_id to get
+ // the prototype property from an object. The exception messages for exceptions
+ // thrown by these instances op_get_by_id need to reflect this.
+ OpcodeID followingOpcodeID;
+ if (codeBlock->getByIdExceptionInfoForBytecodeOffset(exec, bytecodeOffset, followingOpcodeID)) {
+ ASSERT(followingOpcodeID == op_construct || followingOpcodeID == op_instanceof);
+ if (followingOpcodeID == op_construct)
+ return createNotAConstructorError(exec, error->isNull() ? jsNull() : jsUndefined(), bytecodeOffset, codeBlock);
+ return createInvalidParamError(exec, "instanceof", error->isNull() ? jsNull() : jsUndefined(), bytecodeOffset, codeBlock);
+ }
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
- int line = codeBlock->expressionRangeForVPC(vPC, divotPoint, startOffset, endOffset);
+ int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint - startOffset, divotPoint, error->isNull() ? jsNull() : jsUndefined(), "not an object");
- JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->sourceURL());
+ JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
diff --git a/JavaScriptCore/VM/ExceptionHelpers.h b/JavaScriptCore/runtime/ExceptionHelpers.h
index fbbe450..d4dfdd8 100644
--- a/JavaScriptCore/VM/ExceptionHelpers.h
+++ b/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -40,16 +40,17 @@ namespace JSC {
class JSGlobalData;
class JSNotAnObjectErrorStub;
class JSObject;
+ class JSValuePtr;
class Node;
- JSValue* createInterruptedExecutionException(JSGlobalData*);
- JSValue* createStackOverflowError(ExecState*);
- JSValue* createUndefinedVariableError(ExecState*, const Identifier&, const Instruction*, CodeBlock*);
+ JSValuePtr createInterruptedExecutionException(JSGlobalData*);
+ JSValuePtr createStackOverflowError(ExecState*);
+ JSValuePtr createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*);
JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState*, bool isNull);
- JSObject* createInvalidParamError(ExecState*, const char* op, JSValue*, const Instruction*, CodeBlock*);
- JSObject* createNotAConstructorError(ExecState*, JSValue*, const Instruction*, CodeBlock*);
- JSValue* createNotAFunctionError(ExecState*, JSValue*, const Instruction*, CodeBlock*);
- JSObject* createNotAnObjectError(ExecState*, JSNotAnObjectErrorStub*, const Instruction*, CodeBlock*);
+ JSObject* createInvalidParamError(ExecState*, const char* op, JSValuePtr, unsigned bytecodeOffset, CodeBlock*);
+ JSObject* createNotAConstructorError(ExecState*, JSValuePtr, unsigned bytecodeOffset, CodeBlock*);
+ JSValuePtr createNotAFunctionError(ExecState*, JSValuePtr, unsigned bytecodeOffset, CodeBlock*);
+ JSObject* createNotAnObjectError(ExecState*, JSNotAnObjectErrorStub*, unsigned bytecodeOffset, CodeBlock*);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp
index adc3d3c..d58334a 100644
--- a/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -27,14 +27,14 @@
#include "JSString.h"
#include "Parser.h"
#include "Debugger.h"
-#include "lexer.h"
-#include "nodes.h"
+#include "Lexer.h"
+#include "Nodes.h"
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor);
-FunctionConstructor::FunctionConstructor(ExecState* exec, PassRefPtr<StructureID> structure, FunctionPrototype* functionPrototype)
+FunctionConstructor::FunctionConstructor(ExecState* exec, PassRefPtr<Structure> structure, FunctionPrototype* functionPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, functionPrototype->classInfo()->className))
{
putDirectWithoutTransition(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
@@ -54,7 +54,7 @@ ConstructType FunctionConstructor::getConstructData(ConstructData& constructData
return ConstructTypeHost;
}
-static JSValue* callFunctionConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr callFunctionConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
return constructFunction(exec, args);
}
@@ -66,75 +66,57 @@ CallType FunctionConstructor::getCallData(CallData& callData)
return CallTypeHost;
}
+FunctionBodyNode* extractFunctionBody(ProgramNode* program)
+{
+ if (!program)
+ return 0;
+
+ StatementVector& children = program->children();
+ if (children.size() != 1)
+ return 0;
+
+ ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(children[0].get());
+ ASSERT(exprStatement->isExprStatement());
+ if (!exprStatement || !exprStatement->isExprStatement())
+ return 0;
+
+ FuncExprNode* funcExpr = static_cast<FuncExprNode*>(exprStatement->expr());
+ ASSERT(funcExpr->isFuncExprNode());
+ if (!funcExpr || !funcExpr->isFuncExprNode())
+ return 0;
+
+ FunctionBodyNode* body = funcExpr->body();
+ ASSERT(body);
+ return body;
+}
+
// ECMA 15.3.2 The Function Constructor
JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
{
- UString p("");
- UString body;
- int argsSize = args.size();
- if (argsSize == 0)
- body = "";
- else if (argsSize == 1)
- body = args.at(exec, 0)->toString(exec);
+ UString program;
+ if (args.isEmpty())
+ program = "(function(){})";
+ else if (args.size() == 1)
+ program = "(function(){" + args.at(exec, 0).toString(exec) + "})";
else {
- p = args.at(exec, 0)->toString(exec);
- for (int k = 1; k < argsSize - 1; k++)
- p += "," + args.at(exec, k)->toString(exec);
- body = args.at(exec, argsSize - 1)->toString(exec);
+ program = "(function(" + args.at(exec, 0).toString(exec);
+ for (size_t i = 1; i < args.size() - 1; i++)
+ program += "," + args.at(exec, i).toString(exec);
+ program += "){" + args.at(exec, args.size() - 1).toString(exec) + "})";
}
- // parse the source code
int errLine;
UString errMsg;
- SourceCode source = makeSource(body, sourceURL, lineNumber);
- RefPtr<FunctionBodyNode> functionBody = exec->globalData().parser->parse<FunctionBodyNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
+ SourceCode source = makeSource(program, sourceURL, lineNumber);
+ RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
- // No program node == syntax error - throw a syntax error
- if (!functionBody)
- // We can't return a Completion(Throw) here, so just set the exception
- // and return it
+ FunctionBodyNode* body = extractFunctionBody(programNode.get());
+ if (!body)
return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
- // parse parameter list. throw syntax error on illegal identifiers
- int len = p.size();
- const UChar* c = p.data();
- int i = 0;
- UString param;
- Vector<Identifier> parameters;
- while (i < len) {
- while (*c == ' ' && i < len)
- c++, i++;
- if (Lexer::isIdentStart(c[0])) { // else error
- param = UString(c, 1);
- c++, i++;
- while (i < len && (Lexer::isIdentPart(c[0]))) {
- param.append(*c);
- c++, i++;
- }
- while (i < len && *c == ' ')
- c++, i++;
- if (i == len) {
- parameters.append(Identifier(exec, param));
- break;
- } else if (*c == ',') {
- parameters.append(Identifier(exec, param));
- c++, i++;
- continue;
- } // else error
- }
- return throwError(exec, SyntaxError, "Syntax error in parameter list");
- }
- size_t count = parameters.size();
- functionBody->finishParsing(parameters.releaseBuffer(), count);
-
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue());
- JSFunction* function = new (exec) JSFunction(exec, functionName, functionBody.get(), scopeChain.node());
-
- JSObject* prototype = constructEmptyObject(exec);
- prototype->putDirect(exec->propertyNames().constructor, function, DontEnum);
- function->putDirect(exec->propertyNames().prototype, prototype, DontDelete);
- return function;
+ return new (exec) JSFunction(exec, functionName, body, scopeChain.node());
}
// ECMA 15.3.2 The Function Constructor
diff --git a/JavaScriptCore/runtime/FunctionConstructor.h b/JavaScriptCore/runtime/FunctionConstructor.h
index c309c41..124b354 100644
--- a/JavaScriptCore/runtime/FunctionConstructor.h
+++ b/JavaScriptCore/runtime/FunctionConstructor.h
@@ -26,10 +26,12 @@
namespace JSC {
class FunctionPrototype;
+ class ProgramNode;
+ class FunctionBodyNode;
class FunctionConstructor : public InternalFunction {
public:
- FunctionConstructor(ExecState*, PassRefPtr<StructureID>, FunctionPrototype*);
+ FunctionConstructor(ExecState*, PassRefPtr<Structure>, FunctionPrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
@@ -39,6 +41,8 @@ namespace JSC {
JSObject* constructFunction(ExecState*, const ArgList&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
JSObject* constructFunction(ExecState*, const ArgList&);
+ FunctionBodyNode* extractFunctionBody(ProgramNode*);
+
} // namespace JSC
#endif // FunctionConstructor_h
diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp
index 8c3a260..7be2685 100644
--- a/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -25,31 +25,31 @@
#include "JSArray.h"
#include "JSFunction.h"
#include "JSString.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "PrototypeFunction.h"
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(FunctionPrototype);
-static JSValue* functionProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* functionProtoFuncApply(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* functionProtoFuncCall(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr functionProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr functionProtoFuncApply(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr functionProtoFuncCall(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-FunctionPrototype::FunctionPrototype(ExecState* exec, PassRefPtr<StructureID> structure)
+FunctionPrototype::FunctionPrototype(ExecState* exec, PassRefPtr<Structure> structure)
: InternalFunction(&exec->globalData(), structure, exec->propertyNames().nullIdentifier)
{
putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
}
-void FunctionPrototype::addFunctionProperties(ExecState* exec, StructureID* prototypeFunctionStructure)
+void FunctionPrototype::addFunctionProperties(ExecState* exec, Structure* prototypeFunctionStructure)
{
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
}
-static JSValue* callFunctionPrototype(ExecState*, JSObject*, JSValue*, const ArgList&)
+static JSValuePtr callFunctionPrototype(ExecState*, JSObject*, JSValuePtr, const ArgList&)
{
return jsUndefined();
}
@@ -63,14 +63,14 @@ CallType FunctionPrototype::getCallData(CallData& callData)
// Functions
-JSValue* functionProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr functionProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (thisValue->isObject(&JSFunction::info)) {
+ if (thisValue.isObject(&JSFunction::info)) {
JSFunction* function = asFunction(thisValue);
- return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->m_body->paramString() + ") " + function->m_body->toSourceString());
+ return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->body()->paramString() + ") " + function->body()->toSourceString());
}
- if (thisValue->isObject(&InternalFunction::info)) {
+ if (thisValue.isObject(&InternalFunction::info)) {
InternalFunction* function = asInternalFunction(thisValue);
return jsString(exec, "function " + function->name(&exec->globalData()) + "() {\n [native code]\n}");
}
@@ -78,32 +78,32 @@ JSValue* functionProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValu
return throwError(exec, TypeError);
}
-JSValue* functionProtoFuncApply(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr functionProtoFuncApply(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
CallData callData;
- CallType callType = thisValue->getCallData(callData);
+ CallType callType = thisValue.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSValue* thisArg = args.at(exec, 0);
- JSValue* argArray = args.at(exec, 1);
+ JSValuePtr thisArg = args.at(exec, 0);
+ JSValuePtr argArray = args.at(exec, 1);
- JSValue* applyThis;
- if (thisArg->isUndefinedOrNull())
+ JSValuePtr applyThis;
+ if (thisArg.isUndefinedOrNull())
applyThis = exec->globalThisValue();
else
- applyThis = thisArg->toObject(exec);
+ applyThis = thisArg.toObject(exec);
ArgList applyArgs;
- if (!argArray->isUndefinedOrNull()) {
- if (!argArray->isObject())
+ if (!argArray.isUndefinedOrNull()) {
+ if (!argArray.isObject())
return throwError(exec, TypeError);
if (asObject(argArray)->classInfo() == &Arguments::info)
asArguments(argArray)->fillArgList(exec, applyArgs);
- else if (exec->machine()->isJSArray(argArray))
+ else if (exec->interpreter()->isJSArray(argArray))
asArray(argArray)->fillArgList(exec, applyArgs);
else if (asObject(argArray)->inherits(&JSArray::info)) {
- unsigned length = asArray(argArray)->get(exec, exec->propertyNames().length)->toUInt32(exec);
+ unsigned length = asArray(argArray)->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned i = 0; i < length; ++i)
applyArgs.append(asArray(argArray)->get(exec, i));
} else
@@ -113,20 +113,20 @@ JSValue* functionProtoFuncApply(ExecState* exec, JSObject*, JSValue* thisValue,
return call(exec, thisValue, callType, callData, applyThis, applyArgs);
}
-JSValue* functionProtoFuncCall(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr functionProtoFuncCall(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
CallData callData;
- CallType callType = thisValue->getCallData(callData);
+ CallType callType = thisValue.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSValue* thisArg = args.at(exec, 0);
+ JSValuePtr thisArg = args.at(exec, 0);
JSObject* callThis;
- if (thisArg->isUndefinedOrNull())
+ if (thisArg.isUndefinedOrNull())
callThis = exec->globalThisValue();
else
- callThis = thisArg->toObject(exec);
+ callThis = thisArg.toObject(exec);
ArgList argsTail;
args.getSlice(1, argsTail);
diff --git a/JavaScriptCore/runtime/FunctionPrototype.h b/JavaScriptCore/runtime/FunctionPrototype.h
index f493642..33d68b7 100644
--- a/JavaScriptCore/runtime/FunctionPrototype.h
+++ b/JavaScriptCore/runtime/FunctionPrototype.h
@@ -27,12 +27,12 @@ namespace JSC {
class FunctionPrototype : public InternalFunction {
public:
- FunctionPrototype(ExecState*, PassRefPtr<StructureID>);
- void addFunctionProperties(ExecState*, StructureID* prototypeFunctionStructure);
+ FunctionPrototype(ExecState*, PassRefPtr<Structure>);
+ void addFunctionProperties(ExecState*, Structure* prototypeFunctionStructure);
- static PassRefPtr<StructureID> createStructureID(JSValue* proto)
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto)
{
- return StructureID::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
+ return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
}
private:
diff --git a/JavaScriptCore/runtime/GetterSetter.cpp b/JavaScriptCore/runtime/GetterSetter.cpp
index c3d089f..39ee6fc 100644
--- a/JavaScriptCore/runtime/GetterSetter.cpp
+++ b/JavaScriptCore/runtime/GetterSetter.cpp
@@ -38,13 +38,13 @@ void GetterSetter::mark()
m_setter->mark();
}
-JSValue* GetterSetter::toPrimitive(ExecState*, PreferredPrimitiveType) const
+JSValuePtr GetterSetter::toPrimitive(ExecState*, PreferredPrimitiveType) const
{
ASSERT_NOT_REACHED();
return jsNull();
}
-bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
+bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value)
{
ASSERT_NOT_REACHED();
number = 0;
@@ -73,7 +73,7 @@ UString GetterSetter::toString(ExecState*) const
JSObject* GetterSetter::toObject(ExecState* exec) const
{
ASSERT_NOT_REACHED();
- return jsNull()->toObject(exec);
+ return jsNull().toObject(exec);
}
bool GetterSetter::isGetterSetter() const
diff --git a/JavaScriptCore/runtime/GetterSetter.h b/JavaScriptCore/runtime/GetterSetter.h
index da968b2..48e1baf 100644
--- a/JavaScriptCore/runtime/GetterSetter.h
+++ b/JavaScriptCore/runtime/GetterSetter.h
@@ -50,8 +50,8 @@ namespace JSC {
private:
virtual bool isGetterSetter() const;
- virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+ virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
@@ -61,9 +61,9 @@ namespace JSC {
JSObject* m_setter;
};
- GetterSetter* asGetterSetter(JSValue*);
+ GetterSetter* asGetterSetter(JSValuePtr);
- inline GetterSetter* asGetterSetter(JSValue* value)
+ inline GetterSetter* asGetterSetter(JSValuePtr value)
{
ASSERT(asCell(value)->isGetterSetter());
return static_cast<GetterSetter*>(asCell(value));
diff --git a/JavaScriptCore/runtime/GlobalEvalFunction.cpp b/JavaScriptCore/runtime/GlobalEvalFunction.cpp
index 10b3a2f..b0d4c25 100644
--- a/JavaScriptCore/runtime/GlobalEvalFunction.cpp
+++ b/JavaScriptCore/runtime/GlobalEvalFunction.cpp
@@ -32,7 +32,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(GlobalEvalFunction);
-GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, PassRefPtr<StructureID> structure, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
+GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, PassRefPtr<Structure> structure, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
: PrototypeFunction(exec, structure, len, name, function)
, m_cachedGlobalObject(cachedGlobalObject)
{
diff --git a/JavaScriptCore/runtime/GlobalEvalFunction.h b/JavaScriptCore/runtime/GlobalEvalFunction.h
index 2d207c4..49b1847 100644
--- a/JavaScriptCore/runtime/GlobalEvalFunction.h
+++ b/JavaScriptCore/runtime/GlobalEvalFunction.h
@@ -32,7 +32,7 @@ namespace JSC {
class GlobalEvalFunction : public PrototypeFunction {
public:
- GlobalEvalFunction(ExecState*, PassRefPtr<StructureID>, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
+ GlobalEvalFunction(ExecState*, PassRefPtr<Structure>, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
private:
diff --git a/JavaScriptCore/kjs/identifier.cpp b/JavaScriptCore/runtime/Identifier.cpp
index 50a6cc3..040c123 100644
--- a/JavaScriptCore/kjs/identifier.cpp
+++ b/JavaScriptCore/runtime/Identifier.cpp
@@ -19,9 +19,9 @@
*/
#include "config.h"
-#include "identifier.h"
+#include "Identifier.h"
-#include "ExecState.h"
+#include "CallFrame.h"
#include <new> // for placement new
#include <string.h> // for strlen
#include <wtf/Assertions.h>
@@ -96,8 +96,7 @@ bool Identifier::equal(const UString::Rep* r, const UChar* s, int length)
return true;
}
-struct CStringTranslator
-{
+struct CStringTranslator {
static unsigned hash(const char* c)
{
return UString::Rep::computeHash(c);
@@ -116,7 +115,6 @@ struct CStringTranslator
d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
UString::Rep* r = UString::Rep::create(d, static_cast<int>(length)).releaseRef();
- r->rc = 0;
r->_hash = hash;
location = r;
@@ -126,12 +124,12 @@ struct CStringTranslator
PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
{
if (!c) {
- UString::Rep::null.hash();
- return &UString::Rep::null;
+ UString::Rep::null().hash();
+ return &UString::Rep::null();
}
if (!c[0]) {
- UString::Rep::empty.hash();
- return &UString::Rep::empty;
+ UString::Rep::empty().hash();
+ return &UString::Rep::empty();
}
if (!c[1])
return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0])));
@@ -143,10 +141,15 @@ PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c
if (iter != literalIdentifierTable.end())
return iter->second;
- UString::Rep* addedString = *identifierTable.add<const char*, CStringTranslator>(c).first;
- literalIdentifierTable.add(c, addedString);
+ pair<HashSet<UString::Rep*>::iterator, bool> addResult = identifierTable.add<const char*, CStringTranslator>(c);
+
+ // If the string is newly-translated, then we need to adopt it.
+ // The boolean in the pair tells us if that is so.
+ RefPtr<UString::Rep> addedString = addResult.second ? adoptRef(*addResult.first) : *addResult.first;
+
+ literalIdentifierTable.add(c, addedString.get());
- return addedString;
+ return addedString.release();
}
PassRefPtr<UString::Rep> Identifier::add(ExecState* exec, const char* c)
@@ -159,8 +162,7 @@ struct UCharBuffer {
unsigned int length;
};
-struct UCharBufferTranslator
-{
+struct UCharBufferTranslator {
static unsigned hash(const UCharBuffer& buf)
{
return UString::Rep::computeHash(buf.s, buf.length);
@@ -178,7 +180,6 @@ struct UCharBufferTranslator
d[i] = buf.s[i];
UString::Rep* r = UString::Rep::create(d, buf.length).releaseRef();
- r->rc = 0;
r->_hash = hash;
location = r;
@@ -193,11 +194,15 @@ PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar*
return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
}
if (!length) {
- UString::Rep::empty.hash();
- return &UString::Rep::empty;
+ UString::Rep::empty().hash();
+ return &UString::Rep::empty();
}
UCharBuffer buf = {s, length};
- return *globalData->identifierTable->add<UCharBuffer, UCharBufferTranslator>(buf).first;
+ pair<HashSet<UString::Rep*>::iterator, bool> addResult = globalData->identifierTable->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<UString::Rep> Identifier::add(ExecState* exec, const UChar* s, int length)
@@ -220,8 +225,8 @@ PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UStri
}
}
if (!r->len) {
- UString::Rep::empty.hash();
- return &UString::Rep::empty;
+ UString::Rep::empty().hash();
+ return &UString::Rep::empty();
}
return *globalData->identifierTable->add(r).first;
}
diff --git a/JavaScriptCore/kjs/identifier.h b/JavaScriptCore/runtime/Identifier.h
index a79dd92..631cf42 100644
--- a/JavaScriptCore/kjs/identifier.h
+++ b/JavaScriptCore/runtime/Identifier.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -18,18 +18,18 @@
*
*/
-#ifndef KJS_IDENTIFIER_H
-#define KJS_IDENTIFIER_H
+#ifndef Identifier_h
+#define Identifier_h
#include "JSGlobalData.h"
-#include "ustring.h"
+#include "UString.h"
namespace JSC {
class ExecState;
class Identifier {
- friend class StructureID;
+ friend class Structure;
public:
Identifier() { }
@@ -68,6 +68,7 @@ namespace JSC {
friend bool operator!=(const Identifier&, const Identifier&);
friend bool operator==(const Identifier&, const char*);
+ friend bool operator!=(const Identifier&, const char*);
static void remove(UString::Rep*);
@@ -78,8 +79,6 @@ namespace JSC {
static PassRefPtr<UString::Rep> add(ExecState*, const char*); // Only to be used with string literals.
static PassRefPtr<UString::Rep> add(JSGlobalData*, const char*); // Only to be used with string literals.
- static void initializeIdentifierThreading();
-
private:
UString _ustring;
@@ -132,9 +131,14 @@ namespace JSC {
return Identifier::equal(a, b);
}
+ inline bool operator!=(const Identifier& a, const char* b)
+ {
+ return !Identifier::equal(a, b);
+ }
+
IdentifierTable* createIdentifierTable();
void deleteIdentifierTable(IdentifierTable*);
} // namespace JSC
-#endif // KJS_IDENTIFIER_H
+#endif // Identifier_h
diff --git a/JavaScriptCore/runtime/InitializeThreading.cpp b/JavaScriptCore/runtime/InitializeThreading.cpp
index 9e14768..cda9fb1 100644
--- a/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -29,14 +29,17 @@
#include "config.h"
#include "InitializeThreading.h"
-#include "collector.h"
+#include "JSImmediate.h"
+#include "Collector.h"
#include "DateMath.h"
#include "dtoa.h"
-#include "identifier.h"
+#include "Identifier.h"
#include "JSGlobalObject.h"
-#include "ustring.h"
+#include "UString.h"
#include <wtf/Threading.h>
+using namespace WTF;
+
namespace JSC {
#if PLATFORM(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS)
@@ -46,9 +49,9 @@ static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT;
static void initializeThreadingOnce()
{
WTF::initializeThreading();
+ initializeUString();
#if ENABLE(JSC_MULTIPLE_THREADS)
s_dtoaP5Mutex = new Mutex;
- UString::null();
initDateMath();
#endif
}
diff --git a/JavaScriptCore/runtime/InternalFunction.cpp b/JavaScriptCore/runtime/InternalFunction.cpp
index ee81a58..6714cf5 100644
--- a/JavaScriptCore/runtime/InternalFunction.cpp
+++ b/JavaScriptCore/runtime/InternalFunction.cpp
@@ -37,7 +37,7 @@ const ClassInfo* InternalFunction::classInfo() const
return &info;
}
-InternalFunction::InternalFunction(JSGlobalData* globalData, PassRefPtr<StructureID> structure, const Identifier& name)
+InternalFunction::InternalFunction(JSGlobalData* globalData, PassRefPtr<Structure> structure, const Identifier& name)
: JSObject(structure)
{
putDirect(globalData->propertyNames->name, jsString(globalData, name.ustring()), DontDelete | ReadOnly | DontEnum);
diff --git a/JavaScriptCore/runtime/InternalFunction.h b/JavaScriptCore/runtime/InternalFunction.h
index 54d90ae..cc4b917 100644
--- a/JavaScriptCore/runtime/InternalFunction.h
+++ b/JavaScriptCore/runtime/InternalFunction.h
@@ -25,7 +25,7 @@
#define InternalFunction_h
#include "JSObject.h"
-#include "identifier.h"
+#include "Identifier.h"
namespace JSC {
@@ -38,22 +38,22 @@ namespace JSC {
const UString& name(JSGlobalData*);
- static PassRefPtr<StructureID> createStructureID(JSValue* proto)
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto)
{
- return StructureID::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot));
+ return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot));
}
protected:
- InternalFunction(PassRefPtr<StructureID> structure) : JSObject(structure) { }
- InternalFunction(JSGlobalData*, PassRefPtr<StructureID>, const Identifier&);
+ InternalFunction(PassRefPtr<Structure> structure) : JSObject(structure) { }
+ InternalFunction(JSGlobalData*, PassRefPtr<Structure>, const Identifier&);
private:
virtual CallType getCallData(CallData&) = 0;
};
- InternalFunction* asInternalFunction(JSValue*);
+ InternalFunction* asInternalFunction(JSValuePtr);
- inline InternalFunction* asInternalFunction(JSValue* value)
+ inline InternalFunction* asInternalFunction(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&InternalFunction::info));
return static_cast<InternalFunction*>(asObject(value));
diff --git a/JavaScriptCore/runtime/JSActivation.cpp b/JavaScriptCore/runtime/JSActivation.cpp
index 9cb77e8..a2d2634 100644
--- a/JavaScriptCore/runtime/JSActivation.cpp
+++ b/JavaScriptCore/runtime/JSActivation.cpp
@@ -30,7 +30,7 @@
#include "JSActivation.h"
#include "Arguments.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "JSFunction.h"
namespace JSC {
@@ -40,7 +40,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSActivation);
const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 };
JSActivation::JSActivation(CallFrame* callFrame, PassRefPtr<FunctionBodyNode> functionBody)
- : Base(callFrame->globalData().activationStructureID, new JSActivationData(functionBody, callFrame))
+ : Base(callFrame->globalData().activationStructure, new JSActivationData(functionBody, callFrame))
{
}
@@ -57,7 +57,7 @@ void JSActivation::mark()
if (!registerArray)
return;
- size_t numParametersMinusThis = d()->functionBody->generatedByteCode().numParameters - 1;
+ size_t numParametersMinusThis = d()->functionBody->generatedBytecode().m_numParameters - 1;
size_t i = 0;
size_t count = numParametersMinusThis;
@@ -67,7 +67,7 @@ void JSActivation::mark()
r.mark();
}
- size_t numVars = d()->functionBody->generatedByteCode().numVars;
+ size_t numVars = d()->functionBody->generatedBytecode().m_numVars;
// Skip the call frame, which sits between the parameters and vars.
i += RegisterFile::CallFrameHeaderSize;
@@ -85,7 +85,7 @@ bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propert
if (symbolTableGet(propertyName, slot))
return true;
- if (JSValue** location = getDirectLocation(propertyName)) {
+ if (JSValuePtr* location = getDirectLocation(propertyName)) {
slot.setValueSlot(location);
return true;
}
@@ -99,11 +99,11 @@ bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propert
// We don't call through to JSObject because there's no way to give an
// activation object getter properties or a prototype.
ASSERT(!hasGetterSetterProperties());
- ASSERT(prototype()->isNull());
+ ASSERT(prototype().isNull());
return false;
}
-void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+void JSActivation::put(ExecState*, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -118,7 +118,7 @@ void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue* valu
}
// FIXME: Make this function honor ReadOnly (const) and DontEnum
-void JSActivation::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
+void JSActivation::putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -151,7 +151,7 @@ bool JSActivation::isDynamicScope() const
return d()->functionBody->usesEval();
}
-JSValue* JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
JSActivation* activation = asActivation(slot.slotBase());
diff --git a/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h
index 16d131b..5e82bdc 100644
--- a/JavaScriptCore/runtime/JSActivation.h
+++ b/JavaScriptCore/runtime/JSActivation.h
@@ -33,7 +33,7 @@
#include "JSVariableObject.h"
#include "RegisterFile.h"
#include "SymbolTable.h"
-#include "nodes.h"
+#include "Nodes.h"
namespace JSC {
@@ -50,11 +50,13 @@ namespace JSC {
virtual bool isDynamicScope() const;
+ virtual bool isActivationObject() const { return true; }
+
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
- virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
- virtual void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes);
+ virtual void putWithAttributes(ExecState*, const Identifier&, JSValuePtr, unsigned attributes);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual JSObject* toThisObject(ExecState*) const;
@@ -64,12 +66,12 @@ namespace JSC {
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
private:
struct JSActivationData : public JSVariableObjectData {
JSActivationData(PassRefPtr<FunctionBodyNode> functionBody, Register* registers)
- : JSVariableObjectData(&functionBody->symbolTable(), registers)
+ : JSVariableObjectData(&functionBody->generatedBytecode().symbolTable(), registers)
, functionBody(functionBody)
{
}
@@ -77,15 +79,15 @@ namespace JSC {
RefPtr<FunctionBodyNode> functionBody;
};
- static JSValue* argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValuePtr argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); }
};
- JSActivation* asActivation(JSValue*);
+ JSActivation* asActivation(JSValuePtr);
- inline JSActivation* asActivation(JSValue* value)
+ inline JSActivation* asActivation(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&JSActivation::info));
return static_cast<JSActivation*>(asObject(value));
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
index d2d38a4..89a2b45 100644
--- a/JavaScriptCore/runtime/JSArray.cpp
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -27,11 +27,12 @@
#include "PropertyNameArray.h"
#include <wtf/AVLTree.h>
#include <wtf/Assertions.h>
-#include <operations.h>
+#include <Operations.h>
#define CHECK_ARRAY_CONSISTENCY 0
using namespace std;
+using namespace WTF;
namespace JSC {
@@ -64,9 +65,9 @@ ASSERT_CLASS_FITS_IN_CELL(JSArray);
// The definition of MAX_STORAGE_VECTOR_LENGTH is dependant on the definition storageSize
// function below - the MAX_STORAGE_VECTOR_LENGTH limit is defined such that the storage
-// size calculation cannot overflow. (sizeof(ArrayStorage) - sizeof(JSValue*)) +
-// (vectorLength * sizeof(JSValue*)) must be <= 0xFFFFFFFFU (which is maximum value of size_t).
-#define MAX_STORAGE_VECTOR_LENGTH static_cast<unsigned>((0xFFFFFFFFU - (sizeof(ArrayStorage) - sizeof(JSValue*))) / sizeof(JSValue*))
+// size calculation cannot overflow. (sizeof(ArrayStorage) - sizeof(JSValuePtr)) +
+// (vectorLength * sizeof(JSValuePtr)) must be <= 0xFFFFFFFFU (which is maximum value of size_t).
+#define MAX_STORAGE_VECTOR_LENGTH static_cast<unsigned>((0xFFFFFFFFU - (sizeof(ArrayStorage) - sizeof(JSValuePtr))) / sizeof(JSValuePtr))
// These values have to be macros to be used in max() and min() without introducing
// a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
@@ -89,10 +90,10 @@ static inline size_t storageSize(unsigned vectorLength)
// MAX_STORAGE_VECTOR_LENGTH is defined such that provided (vectorLength <= MAX_STORAGE_VECTOR_LENGTH)
// - as asserted above - the following calculation cannot overflow.
- size_t size = (sizeof(ArrayStorage) - sizeof(JSValue*)) + (vectorLength * sizeof(JSValue*));
+ size_t size = (sizeof(ArrayStorage) - sizeof(JSValuePtr)) + (vectorLength * sizeof(JSValuePtr));
// Assertion to detect integer overflow in previous calculation (should not be possible, provided that
// MAX_STORAGE_VECTOR_LENGTH is correctly defined).
- ASSERT(((size - (sizeof(ArrayStorage) - sizeof(JSValue*))) / sizeof(JSValue*) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(JSValue*))));
+ ASSERT(((size - (sizeof(ArrayStorage) - sizeof(JSValuePtr))) / sizeof(JSValuePtr) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(JSValuePtr))));
return size;
}
@@ -125,8 +126,8 @@ inline void JSArray::checkConsistency(ConsistencyCheckType)
#endif
-JSArray::JSArray(PassRefPtr<StructureID> structureID)
- : JSObject(structureID)
+JSArray::JSArray(PassRefPtr<Structure> structure)
+ : JSObject(structure)
{
unsigned initialCapacity = 0;
@@ -138,7 +139,7 @@ JSArray::JSArray(PassRefPtr<StructureID> structureID)
checkConsistency();
}
-JSArray::JSArray(PassRefPtr<StructureID> structure, unsigned initialLength)
+JSArray::JSArray(PassRefPtr<Structure> structure, unsigned initialLength)
: JSObject(structure)
{
unsigned initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
@@ -148,12 +149,12 @@ JSArray::JSArray(PassRefPtr<StructureID> structure, unsigned initialLength)
m_storage->m_vectorLength = initialCapacity;
m_storage->m_length = initialLength;
- Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue*));
+ Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValuePtr));
checkConsistency();
}
-JSArray::JSArray(ExecState* exec, PassRefPtr<StructureID> structure, const ArgList& list)
+JSArray::JSArray(ExecState* exec, PassRefPtr<Structure> structure, const ArgList& list)
: JSObject(structure)
{
unsigned length = list.size();
@@ -174,8 +175,7 @@ JSArray::JSArray(ExecState* exec, PassRefPtr<StructureID> structure, const ArgLi
m_storage = storage;
- // When the array is created non-empty, its cells are filled, so it's really no worse than
- // a property map. Therefore don't report extra memory cost.
+ Heap::heap(this)->reportExtraMemoryCost(storageSize(length));
checkConsistency();
}
@@ -199,7 +199,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot
}
if (i < storage->m_vectorLength) {
- JSValue*& valueSlot = storage->m_vector[i];
+ JSValuePtr& valueSlot = storage->m_vector[i];
if (valueSlot) {
slot.setValueSlot(&valueSlot);
return true;
@@ -233,7 +233,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName
}
// ECMA 15.4.5.1
-void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
bool isArrayIndex;
unsigned i = propertyName.toArrayIndex(&isArrayIndex);
@@ -243,8 +243,8 @@ void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue* valu
}
if (propertyName == exec->propertyNames().length) {
- unsigned newLength = value->toUInt32(exec);
- if (value->toNumber(exec) != static_cast<double>(newLength)) {
+ unsigned newLength = value.toUInt32(exec);
+ if (value.toNumber(exec) != static_cast<double>(newLength)) {
throwError(exec, RangeError, "Invalid array length.");
return;
}
@@ -255,7 +255,7 @@ void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue* valu
JSObject::put(exec, propertyName, value, slot);
}
-void JSArray::put(ExecState* exec, unsigned i, JSValue* value)
+void JSArray::put(ExecState* exec, unsigned i, JSValuePtr value)
{
checkConsistency();
@@ -266,7 +266,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue* value)
}
if (i < m_storage->m_vectorLength) {
- JSValue*& valueSlot = m_storage->m_vector[i];
+ JSValuePtr& valueSlot = m_storage->m_vector[i];
if (valueSlot) {
valueSlot = value;
checkConsistency();
@@ -282,7 +282,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue* value)
putSlowCase(exec, i, value);
}
-NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue* value)
+NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValuePtr value)
{
ArrayStorage* storage = m_storage;
SparseArrayValueMap* map = storage->m_sparseValueMap;
@@ -348,6 +348,9 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue* val
}
unsigned vectorLength = storage->m_vectorLength;
+
+ Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
+
if (newNumValuesInVector == storage->m_numValuesInVector + 1) {
for (unsigned j = vectorLength; j < newVectorLength; ++j)
storage->m_vector[j] = noValue();
@@ -390,7 +393,7 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i)
ArrayStorage* storage = m_storage;
if (i < storage->m_vectorLength) {
- JSValue*& valueSlot = storage->m_vector[i];
+ JSValuePtr& valueSlot = storage->m_vector[i];
if (!valueSlot) {
checkConsistency();
return false;
@@ -461,6 +464,7 @@ bool JSArray::increaseVectorLength(unsigned newLength)
if (!storage)
return false;
+ Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
storage->m_vectorLength = newVectorLength;
for (unsigned i = vectorLength; i < newVectorLength; ++i)
@@ -484,7 +488,7 @@ void JSArray::setLength(unsigned newLength)
unsigned usedVectorLength = min(length, storage->m_vectorLength);
for (unsigned i = newLength; i < usedVectorLength; ++i) {
- JSValue*& valueSlot = storage->m_vector[i];
+ JSValuePtr& valueSlot = storage->m_vector[i];
bool hadValue = valueSlot;
valueSlot = noValue();
storage->m_numValuesInVector -= hadValue;
@@ -509,7 +513,7 @@ void JSArray::setLength(unsigned newLength)
checkConsistency();
}
-JSValue* JSArray::pop()
+JSValuePtr JSArray::pop()
{
checkConsistency();
@@ -519,17 +523,17 @@ JSValue* JSArray::pop()
--length;
- JSValue* result;
+ JSValuePtr result;
if (m_fastAccessCutoff > length) {
- JSValue*& valueSlot = m_storage->m_vector[length];
+ JSValuePtr& valueSlot = m_storage->m_vector[length];
result = valueSlot;
ASSERT(result);
valueSlot = noValue();
--m_storage->m_numValuesInVector;
m_fastAccessCutoff = length;
} else if (length < m_storage->m_vectorLength) {
- JSValue*& valueSlot = m_storage->m_vector[length];
+ JSValuePtr& valueSlot = m_storage->m_vector[length];
result = valueSlot;
valueSlot = noValue();
if (result)
@@ -558,7 +562,7 @@ JSValue* JSArray::pop()
return result;
}
-void JSArray::push(ExecState* exec, JSValue* value)
+void JSArray::push(ExecState* exec, JSValuePtr value)
{
checkConsistency();
@@ -598,30 +602,68 @@ void JSArray::mark()
unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);
for (unsigned i = 0; i < usedVectorLength; ++i) {
- JSValue* value = storage->m_vector[i];
- if (value && !value->marked())
- value->mark();
+ JSValuePtr value = storage->m_vector[i];
+ if (value && !value.marked())
+ value.mark();
}
if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
SparseArrayValueMap::iterator end = map->end();
for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {
- JSValue* value = it->second;
- if (!value->marked())
- value->mark();
+ JSValuePtr value = it->second;
+ if (!value.marked())
+ value.mark();
}
}
}
-typedef std::pair<JSValue*, UString> ArrayQSortPair;
+static int compareNumbersForQSort(const void* a, const void* b)
+{
+ double da = static_cast<const JSValuePtr*>(a)->uncheckedGetNumber();
+ double db = static_cast<const JSValuePtr*>(b)->uncheckedGetNumber();
+ return (da > db) - (da < db);
+}
+
+typedef std::pair<JSValuePtr, UString> ValueStringPair;
static int compareByStringPairForQSort(const void* a, const void* b)
{
- const ArrayQSortPair* va = static_cast<const ArrayQSortPair*>(a);
- const ArrayQSortPair* vb = static_cast<const ArrayQSortPair*>(b);
+ const ValueStringPair* va = static_cast<const ValueStringPair*>(a);
+ const ValueStringPair* vb = static_cast<const ValueStringPair*>(b);
return compare(va->second, vb->second);
}
+void JSArray::sortNumeric(ExecState* exec, JSValuePtr compareFunction, CallType callType, const CallData& callData)
+{
+ unsigned lengthNotIncludingUndefined = compactForSorting();
+ if (m_storage->m_sparseValueMap) {
+ throwOutOfMemoryError(exec);
+ return;
+ }
+
+ if (!lengthNotIncludingUndefined)
+ return;
+
+ bool allValuesAreNumbers = true;
+ size_t size = m_storage->m_numValuesInVector;
+ for (size_t i = 0; i < size; ++i) {
+ if (!m_storage->m_vector[i].isNumber()) {
+ allValuesAreNumbers = false;
+ break;
+ }
+ }
+
+ if (!allValuesAreNumbers)
+ return sort(exec, compareFunction, callType, callData);
+
+ // For numeric comparison, which is fast, qsort is faster than mergesort. We
+ // also don't require mergesort's stability, since there's no user visible
+ // side-effect from swapping the order of equal primitive values.
+ qsort(m_storage->m_vector, size, sizeof(JSValuePtr), compareNumbersForQSort);
+
+ checkConsistency(SortConsistencyCheck);
+}
+
void JSArray::sort(ExecState* exec)
{
unsigned lengthNotIncludingUndefined = compactForSorting();
@@ -638,15 +680,15 @@ void JSArray::sort(ExecState* exec)
// buffer. Besides, this protects us from crashing if some objects have custom toString methods that return
// random or otherwise changing results, effectively making compare function inconsistent.
- Vector<ArrayQSortPair> values(lengthNotIncludingUndefined);
+ Vector<ValueStringPair> values(lengthNotIncludingUndefined);
if (!values.begin()) {
throwOutOfMemoryError(exec);
return;
}
for (size_t i = 0; i < lengthNotIncludingUndefined; i++) {
- JSValue* value = m_storage->m_vector[i];
- ASSERT(!value->isUndefined());
+ JSValuePtr value = m_storage->m_vector[i];
+ ASSERT(!value.isUndefined());
values[i].first = value;
}
@@ -657,7 +699,7 @@ void JSArray::sort(ExecState* exec)
// a toString call raises an exception.
for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
- values[i].second = values[i].first->toString(exec);
+ values[i].second = values[i].first.toString(exec);
if (exec->hadException())
return;
@@ -666,11 +708,11 @@ void JSArray::sort(ExecState* exec)
// than O(N log N).
#if HAVE(MERGESORT)
- mergesort(values.begin(), values.size(), sizeof(ArrayQSortPair), compareByStringPairForQSort);
+ mergesort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
#else
// FIXME: The qsort library function is likely to not be a stable sort.
// ECMAScript-262 does not specify a stable sort, but in practice, browsers perform a stable sort.
- qsort(values.begin(), values.size(), sizeof(ArrayQSortPair), compareByStringPairForQSort);
+ qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort);
#endif
// FIXME: If the toString function changed the length of the array, this might be
@@ -683,7 +725,7 @@ void JSArray::sort(ExecState* exec)
}
struct AVLTreeNodeForArrayCompare {
- JSValue* value;
+ JSValuePtr value;
// Child pointers. The high bit of gt is robbed and used as the
// balance factor sign. The high bit of lt is robbed and used as
@@ -694,15 +736,15 @@ struct AVLTreeNodeForArrayCompare {
struct AVLTreeAbstractorForArrayCompare {
typedef int32_t handle; // Handle is an index into m_nodes vector.
- typedef JSValue* key;
+ typedef JSValuePtr key;
typedef int32_t size;
Vector<AVLTreeNodeForArrayCompare> m_nodes;
ExecState* m_exec;
- JSValue* m_compareFunction;
+ JSValuePtr m_compareFunction;
CallType m_compareCallType;
const CallData* m_compareCallData;
- JSValue* m_globalThisValue;
+ JSValuePtr m_globalThisValue;
handle get_less(handle h) { return m_nodes[h].lt & 0x7FFFFFFF; }
void set_less(handle h, handle lh) { m_nodes[h].lt &= 0x80000000; m_nodes[h].lt |= lh; }
@@ -732,8 +774,8 @@ struct AVLTreeAbstractorForArrayCompare {
int compare_key_key(key va, key vb)
{
- ASSERT(!va->isUndefined());
- ASSERT(!vb->isUndefined());
+ ASSERT(!va.isUndefined());
+ ASSERT(!vb.isUndefined());
if (m_exec->hadException())
return 1;
@@ -741,7 +783,7 @@ struct AVLTreeAbstractorForArrayCompare {
ArgList arguments;
arguments.append(va);
arguments.append(vb);
- double compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments)->toNumber(m_exec);
+ double compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments).toNumber(m_exec);
return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent.
}
@@ -751,7 +793,7 @@ struct AVLTreeAbstractorForArrayCompare {
static handle null() { return 0x7FFFFFFF; }
};
-void JSArray::sort(ExecState* exec, JSValue* compareFunction, CallType callType, const CallData& callData)
+void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callType, const CallData& callData)
{
checkConsistency();
@@ -789,15 +831,16 @@ void JSArray::sort(ExecState* exec, JSValue* compareFunction, CallType callType,
// Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
for (; numDefined < usedVectorLength; ++numDefined) {
- JSValue* v = m_storage->m_vector[numDefined];
- if (!v || v->isUndefined())
+ JSValuePtr v = m_storage->m_vector[numDefined];
+ if (!v || v.isUndefined())
break;
tree.abstractor().m_nodes[numDefined].value = v;
tree.insert(numDefined);
}
for (unsigned i = numDefined; i < usedVectorLength; ++i) {
- if (JSValue* v = m_storage->m_vector[i]) {
- if (v->isUndefined())
+ JSValuePtr v = m_storage->m_vector[i];
+ if (v) {
+ if (v.isUndefined())
++numUndefined;
else {
tree.abstractor().m_nodes[numDefined].value = v;
@@ -879,13 +922,14 @@ unsigned JSArray::compactForSorting()
unsigned numUndefined = 0;
for (; numDefined < usedVectorLength; ++numDefined) {
- JSValue* v = storage->m_vector[numDefined];
- if (!v || v->isUndefined())
+ JSValuePtr v = storage->m_vector[numDefined];
+ if (!v || v.isUndefined())
break;
}
for (unsigned i = numDefined; i < usedVectorLength; ++i) {
- if (JSValue* v = storage->m_vector[i]) {
- if (v->isUndefined())
+ JSValuePtr v = storage->m_vector[i];
+ if (v) {
+ if (v.isUndefined())
++numUndefined;
else
storage->m_vector[numDefined++] = v;
@@ -948,7 +992,7 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
unsigned numValuesInVector = 0;
for (unsigned i = 0; i < m_storage->m_vectorLength; ++i) {
- if (JSValue* value = m_storage->m_vector[i]) {
+ if (JSValuePtr value = m_storage->m_vector[i]) {
ASSERT(i < m_storage->m_length);
if (type != DestructorConsistencyCheck)
value->type(); // Likely to crash if the object was deallocated.
@@ -987,7 +1031,7 @@ JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
}
-JSArray* constructArray(ExecState* exec, JSValue* singleItemValue)
+JSArray* constructArray(ExecState* exec, JSValuePtr singleItemValue)
{
ArgList values;
values.append(singleItemValue);
diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h
index 165fafd..7eecf33 100644
--- a/JavaScriptCore/runtime/JSArray.h
+++ b/JavaScriptCore/runtime/JSArray.h
@@ -25,7 +25,7 @@
namespace JSC {
- typedef HashMap<unsigned, JSValue*> SparseArrayValueMap;
+ typedef HashMap<unsigned, JSValuePtr> SparseArrayValueMap;
struct ArrayStorage {
unsigned m_length;
@@ -33,21 +33,21 @@ namespace JSC {
unsigned m_numValuesInVector;
SparseArrayValueMap* m_sparseValueMap;
void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily.
- JSValue* m_vector[1];
+ JSValuePtr m_vector[1];
};
class JSArray : public JSObject {
- friend class CTI;
+ friend class JIT;
public:
- explicit JSArray(PassRefPtr<StructureID>);
- JSArray(PassRefPtr<StructureID>, unsigned initialLength);
- JSArray(ExecState*, PassRefPtr<StructureID>, const ArgList& initialValues);
+ explicit JSArray(PassRefPtr<Structure>);
+ JSArray(PassRefPtr<Structure>, unsigned initialLength);
+ JSArray(ExecState*, PassRefPtr<Structure>, const ArgList& initialValues);
virtual ~JSArray();
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- virtual void put(ExecState*, unsigned propertyName, JSValue*); // FIXME: Make protected and add setItem.
+ virtual void put(ExecState*, unsigned propertyName, JSValuePtr); // FIXME: Make protected and add setItem.
static const ClassInfo info;
@@ -55,20 +55,21 @@ namespace JSC {
void setLength(unsigned); // OK to use on new arrays, but not if it might be a RegExpMatchArray.
void sort(ExecState*);
- void sort(ExecState*, JSValue* compareFunction, CallType, const CallData&);
+ void sort(ExecState*, JSValuePtr compareFunction, CallType, const CallData&);
+ void sortNumeric(ExecState*, JSValuePtr compareFunction, CallType, const CallData&);
- void push(ExecState*, JSValue*);
- JSValue* pop();
+ void push(ExecState*, JSValuePtr);
+ JSValuePtr pop();
bool canGetIndex(unsigned i) { return i < m_fastAccessCutoff; }
- JSValue* getIndex(unsigned i)
+ JSValuePtr getIndex(unsigned i)
{
ASSERT(canGetIndex(i));
return m_storage->m_vector[i];
}
bool canSetIndex(unsigned i) { return i < m_fastAccessCutoff; }
- JSValue* setIndex(unsigned i, JSValue* v)
+ JSValuePtr setIndex(unsigned i, JSValuePtr v)
{
ASSERT(canSetIndex(i));
return m_storage->m_vector[i] = v;
@@ -76,13 +77,13 @@ namespace JSC {
void fillArgList(ExecState*, ArgList&);
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType));
}
protected:
- virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
@@ -95,7 +96,7 @@ namespace JSC {
virtual const ClassInfo* classInfo() const { return &info; }
bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
- void putSlowCase(ExecState*, unsigned propertyName, JSValue*);
+ void putSlowCase(ExecState*, unsigned propertyName, JSValuePtr);
bool increaseVectorLength(unsigned newLength);
@@ -108,14 +109,14 @@ namespace JSC {
ArrayStorage* m_storage;
};
- JSArray* asArray(JSValue*);
+ JSArray* asArray(JSValuePtr);
JSArray* constructEmptyArray(ExecState*);
JSArray* constructEmptyArray(ExecState*, unsigned initialLength);
- JSArray* constructArray(ExecState*, JSValue* singleItemValue);
+ JSArray* constructArray(ExecState*, JSValuePtr singleItemValue);
JSArray* constructArray(ExecState*, const ArgList& values);
- inline JSArray* asArray(JSValue* value)
+ inline JSArray* asArray(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&JSArray::info));
return static_cast<JSArray*>(asObject(value));
diff --git a/JavaScriptCore/runtime/JSByteArray.cpp b/JavaScriptCore/runtime/JSByteArray.cpp
new file mode 100644
index 0000000..54cf7cb
--- /dev/null
+++ b/JavaScriptCore/runtime/JSByteArray.cpp
@@ -0,0 +1,97 @@
+/*
+ * 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 "JSByteArray.h"
+
+#include "JSGlobalObject.h"
+#include "PropertyNameArray.h"
+
+using namespace WTF;
+
+namespace JSC {
+
+const ClassInfo JSByteArray::s_defaultInfo = { "ByteArray", 0, 0, 0 };
+
+JSByteArray::JSByteArray(ExecState* exec, PassRefPtr<Structure> structure, ByteArray* storage, const JSC::ClassInfo* classInfo)
+ : JSObject(structure)
+ , m_storage(storage)
+ , m_classInfo(classInfo)
+{
+ putDirect(exec->globalData().propertyNames->length, jsNumber(exec, m_storage->length()), ReadOnly | DontDelete);
+}
+
+PassRefPtr<Structure> JSByteArray::createStructure(JSValuePtr prototype)
+{
+ PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType));
+ return result;
+}
+
+bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+ bool ok;
+ unsigned index = propertyName.toUInt32(&ok, false);
+ if (ok && canAccessIndex(index)) {
+ slot.setValue(getIndex(exec, index));
+ return true;
+ }
+ return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+}
+
+bool JSByteArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+{
+ if (canAccessIndex(propertyName)) {
+ slot.setValue(getIndex(exec, propertyName));
+ return true;
+ }
+ return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
+}
+
+void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+{
+ bool ok;
+ unsigned index = propertyName.toUInt32(&ok, false);
+ if (ok) {
+ setIndex(exec, index, value);
+ return;
+ }
+ JSObject::put(exec, propertyName, value, slot);
+}
+
+void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValuePtr value)
+{
+ setIndex(exec, propertyName, value);
+}
+
+void JSByteArray::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+{
+ unsigned length = m_storage->length();
+ for (unsigned i = 0; i < length; ++i)
+ propertyNames.add(Identifier::from(exec, i));
+ JSObject::getPropertyNames(exec, propertyNames);
+}
+
+}
+
diff --git a/JavaScriptCore/runtime/JSByteArray.h b/JavaScriptCore/runtime/JSByteArray.h
new file mode 100644
index 0000000..19c8f0e
--- /dev/null
+++ b/JavaScriptCore/runtime/JSByteArray.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSByteArray_h
+#define JSByteArray_h
+
+#include "JSObject.h"
+
+#include <wtf/ByteArray.h>
+
+namespace JSC {
+
+ class JSByteArray : public JSObject {
+ friend class Interpreter;
+ public:
+ bool canAccessIndex(unsigned i) { return i < m_storage->length(); }
+ JSValuePtr getIndex(ExecState* exec, unsigned i)
+ {
+ ASSERT(canAccessIndex(i));
+ return jsNumber(exec, m_storage->data()[i]);
+ }
+
+ void setIndex(unsigned i, int value)
+ {
+ ASSERT(canAccessIndex(i));
+ if (value & ~0xFF) {
+ if (value < 0)
+ value = 0;
+ else
+ value = 255;
+ }
+ m_storage->data()[i] = static_cast<unsigned char>(value);
+ }
+
+ void setIndex(unsigned i, double value)
+ {
+ ASSERT(canAccessIndex(i));
+ if (!(value > 0)) // Clamp NaN to 0
+ value = 0;
+ else if (value > 255)
+ value = 255;
+ m_storage->data()[i] = static_cast<unsigned char>(value + 0.5);
+ }
+
+ void setIndex(ExecState* exec, unsigned i, JSValuePtr value)
+ {
+ double byteValue = value.toNumber(exec);
+ if (exec->hadException())
+ return;
+ if (canAccessIndex(i))
+ setIndex(i, byteValue);
+ }
+
+ JSByteArray(ExecState* exec, PassRefPtr<Structure>, WTF::ByteArray* storage, const JSC::ClassInfo* = &s_defaultInfo);
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype);
+
+ virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
+ virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
+ virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValuePtr, JSC::PutPropertySlot&);
+ virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValuePtr);
+
+ virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
+
+ virtual const ClassInfo* classInfo() const { return m_classInfo; }
+ static const ClassInfo s_defaultInfo;
+
+ size_t length() const { return m_storage->length(); }
+
+ private:
+ enum VPtrStealingHackType { VPtrStealingHack };
+ JSByteArray(VPtrStealingHackType)
+ : JSObject(createStructure(jsNull()))
+ , m_classInfo(0)
+ {
+ }
+
+ RefPtr<WTF::ByteArray> m_storage;
+ const ClassInfo* m_classInfo;
+ };
+
+ JSByteArray* asByteArray(JSValuePtr value);
+ inline JSByteArray* asByteArray(JSValuePtr value)
+ {
+ return static_cast<JSByteArray*>(asCell(value));
+ }
+}
+
+#endif
diff --git a/JavaScriptCore/runtime/JSCell.cpp b/JavaScriptCore/runtime/JSCell.cpp
index cfe2f72..d449deb 100644
--- a/JavaScriptCore/runtime/JSCell.cpp
+++ b/JavaScriptCore/runtime/JSCell.cpp
@@ -100,19 +100,6 @@ bool JSCell::getTruncatedUInt32(uint32_t&) const
return false;
}
-bool JSCell::getNumber(double& numericValue) const
-{
- if (!isNumber())
- return false;
- numericValue = static_cast<const JSNumberCell*>(this)->value();
- return true;
-}
-
-double JSCell::getNumber() const
-{
- return isNumber() ? static_cast<const JSNumberCell*>(this)->value() : NaN;
-}
-
bool JSCell::getString(UString&stringValue) const
{
if (!isString())
@@ -170,12 +157,12 @@ bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySl
return true;
}
-void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue* value, PutPropertySlot& slot)
+void JSCell::put(ExecState* exec, const Identifier& identifier, JSValuePtr value, PutPropertySlot& slot)
{
toObject(exec)->put(exec, identifier, value, slot);
}
-void JSCell::put(ExecState* exec, unsigned identifier, JSValue* value)
+void JSCell::put(ExecState* exec, unsigned identifier, JSValuePtr value)
{
toObject(exec)->put(exec, identifier, value);
}
@@ -210,7 +197,7 @@ const ClassInfo* JSCell::classInfo() const
return 0;
}
-JSValue* JSCell::getJSNumber()
+JSValuePtr JSCell::getJSNumber()
{
return noValue();
}
diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h
index 108dab6..43d81a5 100644
--- a/JavaScriptCore/runtime/JSCell.h
+++ b/JavaScriptCore/runtime/JSCell.h
@@ -23,25 +23,27 @@
#ifndef JSCell_h
#define JSCell_h
-#include "StructureID.h"
+#include <wtf/Noncopyable.h>
+#include "Structure.h"
#include "JSValue.h"
-#include "collector.h"
+#include "JSImmediate.h"
+#include "Collector.h"
namespace JSC {
- class JSCell : public JSValue {
- friend class CTI;
+ class JSCell : Noncopyable {
+ friend class JIT;
friend class GetterSetter;
friend class Heap;
friend class JSNumberCell;
friend class JSObject;
friend class JSPropertyNameIterator;
friend class JSString;
- friend class JSValue;
- friend class Machine;
+ friend class JSValuePtr;
+ friend class Interpreter;
private:
- explicit JSCell(StructureID*);
+ explicit JSCell(Structure*);
virtual ~JSCell();
public:
@@ -52,11 +54,9 @@ namespace JSC {
virtual bool isGetterSetter() const;
virtual bool isObject(const ClassInfo*) const;
- StructureID* structureID() const;
+ Structure* structure() const;
// Extracting the value.
- bool getNumber(double&) const;
- double getNumber() const; // NaN if not a number
bool getString(UString&) const;
UString getString() const; // null string if not a string
JSObject* getObject(); // NULL if not an object
@@ -66,13 +66,14 @@ namespace JSC {
virtual ConstructType getConstructData(ConstructData&);
// Extracting integer values.
+ // FIXME: remove these methods, can check isNumberCell in JSValuePtr && then call asNumberCell::*.
virtual bool getUInt32(uint32_t&) const;
virtual bool getTruncatedInt32(int32_t&) const;
virtual bool getTruncatedUInt32(uint32_t&) const;
// Basic conversions.
- virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&) = 0;
+ virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&) = 0;
virtual bool toBoolean(ExecState*) const = 0;
virtual double toNumber(ExecState*) const = 0;
virtual UString toString(ExecState*) const = 0;
@@ -87,15 +88,15 @@ namespace JSC {
// Object operations, with the toObject operation included.
virtual const ClassInfo* classInfo() const;
- virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
- virtual void put(ExecState*, unsigned propertyName, JSValue*);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+ virtual void put(ExecState*, unsigned propertyName, JSValuePtr);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
virtual JSObject* toThisObject(ExecState*) const;
virtual UString toThisString(ExecState*) const;
virtual JSString* toThisJSString(ExecState*);
- virtual JSValue* getJSNumber();
+ virtual JSValuePtr getJSNumber();
void* vptr() { return *reinterpret_cast<void**>(this); }
private:
@@ -104,19 +105,18 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- StructureID* m_structureID;
+ Structure* m_structure;
};
- JSCell* asCell(JSValue*);
+ JSCell* asCell(JSValuePtr);
- inline JSCell* asCell(JSValue* value)
+ inline JSCell* asCell(JSValuePtr value)
{
- ASSERT(!JSImmediate::isImmediate(value));
- return static_cast<JSCell*>(value);
+ return value.asCell();
}
- inline JSCell::JSCell(StructureID* structureID)
- : m_structureID(structureID)
+ inline JSCell::JSCell(Structure* structure)
+ : m_structure(structure)
{
}
@@ -131,17 +131,17 @@ namespace JSC {
inline bool JSCell::isObject() const
{
- return m_structureID->typeInfo().type() == ObjectType;
+ return m_structure->typeInfo().type() == ObjectType;
}
inline bool JSCell::isString() const
{
- return m_structureID->typeInfo().type() == StringType;
+ return m_structure->typeInfo().type() == StringType;
}
- inline StructureID* JSCell::structureID() const
+ inline Structure* JSCell::structure() const
{
- return m_structureID;
+ return m_structure;
}
inline bool JSCell::marked() const
@@ -154,10 +154,10 @@ namespace JSC {
return Heap::markCell(this);
}
- ALWAYS_INLINE JSCell* JSValue::asCell() const
+ ALWAYS_INLINE JSCell* JSValuePtr::asCell() const
{
- ASSERT(!JSImmediate::isImmediate(asValue()));
- return reinterpret_cast<JSCell*>(const_cast<JSValue*>(this));
+ ASSERT(isCell());
+ return m_ptr;
}
inline void* JSCell::operator new(size_t size, JSGlobalData* globalData)
@@ -171,87 +171,77 @@ namespace JSC {
// --- JSValue inlines ----------------------------
- inline bool JSValue::isNumber() const
- {
- return JSImmediate::isNumber(asValue()) || (!JSImmediate::isImmediate(asValue()) && asCell()->isNumber());
- }
-
- inline bool JSValue::isString() const
+ inline bool JSValuePtr::isString() const
{
return !JSImmediate::isImmediate(asValue()) && asCell()->isString();
}
- inline bool JSValue::isGetterSetter() const
+ inline bool JSValuePtr::isGetterSetter() const
{
return !JSImmediate::isImmediate(asValue()) && asCell()->isGetterSetter();
}
- inline bool JSValue::isObject() const
+ inline bool JSValuePtr::isObject() const
{
return !JSImmediate::isImmediate(asValue()) && asCell()->isObject();
}
- inline double JSValue::getNumber() const
- {
- return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->getNumber();
- }
-
- inline bool JSValue::getString(UString& s) const
+ inline bool JSValuePtr::getString(UString& s) const
{
return !JSImmediate::isImmediate(asValue()) && asCell()->getString(s);
}
- inline UString JSValue::getString() const
+ inline UString JSValuePtr::getString() const
{
return JSImmediate::isImmediate(asValue()) ? UString() : asCell()->getString();
}
- inline JSObject* JSValue::getObject() const
+ inline JSObject* JSValuePtr::getObject() const
{
return JSImmediate::isImmediate(asValue()) ? 0 : asCell()->getObject();
}
- inline CallType JSValue::getCallData(CallData& callData)
+ inline CallType JSValuePtr::getCallData(CallData& callData)
{
return JSImmediate::isImmediate(asValue()) ? CallTypeNone : asCell()->getCallData(callData);
}
- inline ConstructType JSValue::getConstructData(ConstructData& constructData)
+ inline ConstructType JSValuePtr::getConstructData(ConstructData& constructData)
{
return JSImmediate::isImmediate(asValue()) ? ConstructTypeNone : asCell()->getConstructData(constructData);
}
- ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
+ ALWAYS_INLINE bool JSValuePtr::getUInt32(uint32_t& v) const
{
return JSImmediate::isImmediate(asValue()) ? JSImmediate::getUInt32(asValue(), v) : asCell()->getUInt32(v);
}
- ALWAYS_INLINE bool JSValue::getTruncatedInt32(int32_t& v) const
+ ALWAYS_INLINE bool JSValuePtr::getTruncatedInt32(int32_t& v) const
{
return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedInt32(asValue(), v) : asCell()->getTruncatedInt32(v);
}
- inline bool JSValue::getTruncatedUInt32(uint32_t& v) const
+ inline bool JSValuePtr::getTruncatedUInt32(uint32_t& v) const
{
return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedUInt32(asValue(), v) : asCell()->getTruncatedUInt32(v);
}
- inline void JSValue::mark()
+ inline void JSValuePtr::mark()
{
asCell()->mark(); // callers should check !marked() before calling mark(), so this should only be called with cells
}
- inline bool JSValue::marked() const
+ inline bool JSValuePtr::marked() const
{
return JSImmediate::isImmediate(asValue()) || asCell()->marked();
}
- inline JSValue* JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
+ inline JSValuePtr JSValuePtr::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
{
return JSImmediate::isImmediate(asValue()) ? asValue() : asCell()->toPrimitive(exec, preferredType);
}
- inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value)
+ inline bool JSValuePtr::getPrimitiveNumber(ExecState* exec, double& number, JSValuePtr& value)
{
if (JSImmediate::isImmediate(asValue())) {
number = JSImmediate::toDouble(asValue());
@@ -261,48 +251,47 @@ namespace JSC {
return asCell()->getPrimitiveNumber(exec, number, value);
}
- inline bool JSValue::toBoolean(ExecState* exec) const
+ inline bool JSValuePtr::toBoolean(ExecState* exec) const
{
return JSImmediate::isImmediate(asValue()) ? JSImmediate::toBoolean(asValue()) : asCell()->toBoolean(exec);
}
- ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
+ ALWAYS_INLINE double JSValuePtr::toNumber(ExecState* exec) const
{
return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->toNumber(exec);
}
- inline UString JSValue::toString(ExecState* exec) const
+ inline UString JSValuePtr::toString(ExecState* exec) const
{
return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toString(exec);
}
- inline JSObject* JSValue::toObject(ExecState* exec) const
+ inline JSObject* JSValuePtr::toObject(ExecState* exec) const
{
return JSImmediate::isImmediate(asValue()) ? JSImmediate::toObject(asValue(), exec) : asCell()->toObject(exec);
}
- inline JSObject* JSValue::toThisObject(ExecState* exec) const
+ inline JSObject* JSValuePtr::toThisObject(ExecState* exec) const
{
if (UNLIKELY(JSImmediate::isImmediate(asValue())))
- return JSImmediate::toObject(asValue(), exec);
+ return JSImmediate::toThisObject(asValue(), exec);
return asCell()->toThisObject(exec);
}
- inline bool JSValue::needsThisConversion() const
+ inline bool JSValuePtr::needsThisConversion() const
{
if (UNLIKELY(JSImmediate::isImmediate(asValue())))
return true;
- return asCell()->structureID()->typeInfo().needsThisConversion();
+ return asCell()->structure()->typeInfo().needsThisConversion();
}
- inline UString JSValue::toThisString(ExecState* exec) const
+ inline UString JSValuePtr::toThisString(ExecState* exec) const
{
return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toThisString(exec);
}
- inline JSValue* JSValue::getJSNumber()
+ inline JSValuePtr JSValuePtr::getJSNumber()
{
-
return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? noValue() : asCell()->getJSNumber();
}
diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp
index 2973d2d..cb18115 100644
--- a/JavaScriptCore/runtime/JSFunction.cpp
+++ b/JavaScriptCore/runtime/JSFunction.cpp
@@ -27,10 +27,10 @@
#include "CodeBlock.h"
#include "CommonIdentifiers.h"
-#include "ExecState.h"
+#include "CallFrame.h"
#include "FunctionPrototype.h"
#include "JSGlobalObject.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "ObjectPrototype.h"
#include "Parser.h"
#include "PropertyNameArray.h"
@@ -43,7 +43,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSFunction);
-const ClassInfo JSFunction::info = { "Function", 0, 0, 0 };
+const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* body, ScopeChainNode* scopeChainNode)
: Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), name)
@@ -54,12 +54,12 @@ JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode
JSFunction::~JSFunction()
{
-#if ENABLE(CTI)
+#if ENABLE(JIT)
// JIT code for other functions may have had calls linked directly to the code for this function; these links
// are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
// this memory is freed and may be reused (potentially for another, different JSFunction).
- if (m_body.get() && m_body->isGenerated())
- m_body->generatedByteCode().unlinkCallers();
+ if (m_body && m_body->isGenerated())
+ m_body->generatedBytecode().unlinkCallers();
#endif
}
@@ -77,24 +77,24 @@ CallType JSFunction::getCallData(CallData& callData)
return CallTypeJS;
}
-JSValue* JSFunction::call(ExecState* exec, JSValue* thisValue, const ArgList& args)
+JSValuePtr JSFunction::call(ExecState* exec, JSValuePtr thisValue, const ArgList& args)
{
- return exec->machine()->execute(m_body.get(), exec, this, thisValue->toThisObject(exec), args, m_scopeChain.node(), exec->exceptionSlot());
+ return exec->interpreter()->execute(m_body.get(), exec, this, thisValue.toThisObject(exec), args, m_scopeChain.node(), exec->exceptionSlot());
}
-JSValue* JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
JSFunction* thisObj = asFunction(slot.slotBase());
- return exec->machine()->retrieveArguments(exec, thisObj);
+ return exec->interpreter()->retrieveArguments(exec, thisObj);
}
-JSValue* JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
JSFunction* thisObj = asFunction(slot.slotBase());
- return exec->machine()->retrieveCaller(exec, thisObj);
+ return exec->interpreter()->retrieveCaller(exec, thisObj);
}
-JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
JSFunction* thisObj = asFunction(slot.slotBase());
return jsNumber(exec, thisObj->m_body->parameterCount());
@@ -103,7 +103,7 @@ JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const Prop
bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
if (propertyName == exec->propertyNames().prototype) {
- JSValue** location = getDirectLocation(propertyName);
+ JSValuePtr* location = getDirectLocation(propertyName);
if (!location) {
JSObject* prototype = new (exec) JSObject(m_scopeChain.globalObject()->emptyObjectStructure());
@@ -133,7 +133,7 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
return Base::getOwnPropertySlot(exec, propertyName, slot);
}
-void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
return;
@@ -147,32 +147,6 @@ bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
return Base::deleteProperty(exec, propertyName);
}
-/* Returns the parameter name corresponding to the given index. eg:
- * function f1(x, y, z): getParameterName(0) --> x
- *
- * If a name appears more than once, only the last index at which
- * it appears associates with it. eg:
- * function f2(x, x): getParameterName(0) --> null
- */
-const Identifier& JSFunction::getParameterName(int index)
-{
- const Identifier* parameters = m_body->parameters();
-
- if (static_cast<size_t>(index) >= m_body->parameterCount())
- return m_scopeChain.globalObject()->globalData()->propertyNames->nullIdentifier;
-
- const Identifier& name = parameters[index];
-
- // Are there any subsequent parameters with the same name?
- size_t size = m_body->parameterCount();
- for (size_t i = index + 1; i < size; ++i) {
- if (parameters[i] == name)
- return m_scopeChain.globalObject()->globalData()->propertyNames->nullIdentifier;
- }
-
- return name;
-}
-
// ECMA 13.2.2 [[Construct]]
ConstructType JSFunction::getConstructData(ConstructData& constructData)
{
@@ -183,16 +157,16 @@ ConstructType JSFunction::getConstructData(ConstructData& constructData)
JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
{
- StructureID* structure;
- JSValue* prototype = get(exec, exec->propertyNames().prototype);
- if (prototype->isObject())
+ Structure* structure;
+ JSValuePtr prototype = get(exec, exec->propertyNames().prototype);
+ if (prototype.isObject())
structure = asObject(prototype)->inheritorID();
else
structure = exec->lexicalGlobalObject()->emptyObjectStructure();
JSObject* thisObj = new (exec) JSObject(structure);
- JSValue* result = exec->machine()->execute(m_body.get(), exec, this, thisObj, args, m_scopeChain.node(), exec->exceptionSlot());
- if (exec->hadException() || !result->isObject())
+ JSValuePtr result = exec->interpreter()->execute(m_body.get(), exec, this, thisObj, args, m_scopeChain.node(), exec->exceptionSlot());
+ if (exec->hadException() || !result.isObject())
return thisObj;
return asObject(result);
}
diff --git a/JavaScriptCore/runtime/JSFunction.h b/JavaScriptCore/runtime/JSFunction.h
index 694a0f4..6a43737 100644
--- a/JavaScriptCore/runtime/JSFunction.h
+++ b/JavaScriptCore/runtime/JSFunction.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
*
@@ -27,7 +27,7 @@
#include "InternalFunction.h"
#include "JSVariableObject.h"
#include "SymbolTable.h"
-#include "nodes.h"
+#include "Nodes.h"
#include "JSObject.h"
namespace JSC {
@@ -38,39 +38,42 @@ namespace JSC {
class JSGlobalObject;
class JSFunction : public InternalFunction {
- friend class CTI;
- friend class Machine;
+ friend class JIT;
+ friend class Interpreter;
typedef InternalFunction Base;
- JSFunction(PassRefPtr<JSC::StructureID> st) : InternalFunction(st), m_scopeChain(NoScopeChain()) {}
+
+ JSFunction(PassRefPtr<Structure> structure)
+ : InternalFunction(structure)
+ , m_scopeChain(NoScopeChain())
+ {
+ }
+
public:
JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
~JSFunction();
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
- virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
JSObject* construct(ExecState*, const ArgList&);
- JSValue* call(ExecState*, JSValue* thisValue, const ArgList&);
-
- // Note: Returns a null identifier for any parameters that will never get set
- // due to a later parameter with the same name.
- const Identifier& getParameterName(int index);
+ JSValuePtr call(ExecState*, JSValuePtr thisValue, const ArgList&);
void setScope(const ScopeChain& scopeChain) { m_scopeChain = scopeChain; }
ScopeChain& scope() { return m_scopeChain; }
+ void setBody(FunctionBodyNode* body) { m_body = body; }
+ void setBody(PassRefPtr<FunctionBodyNode> body) { m_body = body; }
+ FunctionBodyNode* body() const { return m_body.get(); }
+
virtual void mark();
static const ClassInfo info;
- // FIXME: This should be private
- RefPtr<FunctionBodyNode> m_body;
-
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
+ return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
}
private:
@@ -79,21 +82,22 @@ namespace JSC {
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
- 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 JSValuePtr argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValuePtr callerGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValuePtr lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
+ RefPtr<FunctionBodyNode> m_body;
ScopeChain m_scopeChain;
};
- JSFunction* asFunction(JSValue*);
+ JSFunction* asFunction(JSValuePtr);
- inline JSFunction* asFunction(JSValue* value)
+ inline JSFunction* asFunction(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&JSFunction::info));
return static_cast<JSFunction*>(asObject(value));
}
-} // namespace kJS
+} // namespace JSC
#endif // JSFunction_h
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 8910679..10b584d 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -30,18 +30,19 @@
#include "JSGlobalData.h"
#include "ArgList.h"
+#include "Collector.h"
#include "CommonIdentifiers.h"
+#include "FunctionConstructor.h"
+#include "Interpreter.h"
#include "JSActivation.h"
#include "JSClassRef.h"
#include "JSLock.h"
#include "JSNotAnObject.h"
#include "JSStaticScopeObject.h"
-#include "Machine.h"
#include "Parser.h"
-#include "collector.h"
-#include "lexer.h"
-#include "lookup.h"
-#include "nodes.h"
+#include "Lexer.h"
+#include "Lookup.h"
+#include "Nodes.h"
#if ENABLE(JSC_MULTIPLE_THREADS)
#include <wtf/Threading.h>
@@ -64,7 +65,8 @@ extern const HashTable regExpConstructorTable;
extern const HashTable stringTable;
JSGlobalData::JSGlobalData(bool isShared)
- : machine(new Machine)
+ : initializingLazyNumericCompareFunction(false)
+ , interpreter(new Interpreter)
, exception(noValue())
, arrayTable(new HashTable(JSC::arrayTable))
, dateTable(new HashTable(JSC::dateTable))
@@ -73,13 +75,15 @@ JSGlobalData::JSGlobalData(bool isShared)
, regExpTable(new HashTable(JSC::regExpTable))
, regExpConstructorTable(new HashTable(JSC::regExpConstructorTable))
, stringTable(new HashTable(JSC::stringTable))
- , activationStructureID(JSActivation::createStructureID(jsNull()))
- , interruptedExecutionErrorStructure(JSObject::createStructureID(jsNull()))
- , staticScopeStructureID(JSStaticScopeObject::createStructureID(jsNull()))
- , stringStructureID(JSString::createStructureID(jsNull()))
- , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructureID(jsNull()))
- , notAnObjectStructure(JSNotAnObject::createStructureID(jsNull()))
- , numberStructureID(JSNumberCell::createStructureID(jsNull()))
+ , activationStructure(JSActivation::createStructure(jsNull()))
+ , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
+ , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
+ , stringStructure(JSString::createStructure(jsNull()))
+ , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
+ , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
+#if !USE(ALTERNATE_JSIMMEDIATE)
+ , numberStructure(JSNumberCell::createStructure(jsNull()))
+#endif
, identifierTable(createIdentifierTable())
, propertyNames(new CommonIdentifiers(this))
, emptyList(new ArgList)
@@ -91,21 +95,23 @@ JSGlobalData::JSGlobalData(bool isShared)
, dynamicGlobalObject(0)
, isSharedInstance(isShared)
, clientData(0)
+ , scopeNodeBeingReparsed(0)
, heap(this)
{
#if PLATFORM(MAC)
startProfilerServerIfNeeded();
#endif
+ interpreter->initialize(this);
}
JSGlobalData::~JSGlobalData()
{
// By the time this is destroyed, heap.destroy() must already have been called.
- delete machine;
+ delete interpreter;
#ifndef NDEBUG
// Zeroing out to make the behavior more predictable when someone attempts to use a deleted instance.
- machine = 0;
+ interpreter = 0;
#endif
arrayTable->deleteTable();
@@ -147,9 +153,9 @@ PassRefPtr<JSGlobalData> JSGlobalData::create()
PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
{
#ifndef NDEBUG
- StructureID::startIgnoringLeaks();
+ Structure::startIgnoringLeaks();
RefPtr<JSGlobalData> data = create();
- StructureID::stopIgnoringLeaks();
+ Structure::stopIgnoringLeaks();
return data.release();
#else
return create();
@@ -164,8 +170,12 @@ bool JSGlobalData::sharedInstanceExists()
JSGlobalData& JSGlobalData::sharedInstance()
{
JSGlobalData*& instance = sharedInstanceInternal();
- if (!instance)
+ if (!instance) {
instance = new JSGlobalData(true);
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ instance->makeUsableFromMultipleThreads();
+#endif
+ }
return *instance;
}
@@ -176,8 +186,22 @@ JSGlobalData*& JSGlobalData::sharedInstanceInternal()
return sharedInstance;
}
-JSGlobalData::ClientData::~ClientData()
+// FIXME: We can also detect forms like v1 < v2 ? -1 : 0, reverse comparison, etc.
+const Vector<Instruction>& JSGlobalData::numericCompareFunction(ExecState* exec)
{
+ if (!lazyNumericCompareFunction.size() && !initializingLazyNumericCompareFunction) {
+ initializingLazyNumericCompareFunction = true;
+ RefPtr<ProgramNode> programNode = parser->parse<ProgramNode>(exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
+ RefPtr<FunctionBodyNode> functionBody = extractFunctionBody(programNode.get());
+ lazyNumericCompareFunction = functionBody->bytecode(exec->scopeChain()).instructions();
+ initializingLazyNumericCompareFunction = false;
+ }
+
+ return lazyNumericCompareFunction;
}
+JSGlobalData::ClientData::~ClientData()
+{
}
+
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 3210149..4223191 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -32,8 +32,10 @@
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
-#include "collector.h"
+#include "Collector.h"
+#include "ExecutableAllocator.h"
#include "SmallStrings.h"
+#include "JSValue.h"
struct OpaqueJSClass;
struct OpaqueJSClassContextData;
@@ -44,13 +46,15 @@ namespace JSC {
class CommonIdentifiers;
class Heap;
class IdentifierTable;
+ class Instruction;
+ class Interpreter;
class JSGlobalObject;
class JSObject;
class Lexer;
- class Machine;
class Parser;
class ParserRefCounted;
- class StructureID;
+ class ScopeNode;
+ class Structure;
class UString;
struct HashTable;
@@ -63,11 +67,20 @@ namespace JSC {
static PassRefPtr<JSGlobalData> createLeaked();
~JSGlobalData();
- Machine* machine;
+#if ENABLE(JSC_MULTIPLE_THREADS)
+ // Will start tracking threads that use the heap, which is resource-heavy.
+ void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); }
+#endif
+
+ const Vector<Instruction>& numericCompareFunction(ExecState*);
+ Vector<Instruction> lazyNumericCompareFunction;
+ bool initializingLazyNumericCompareFunction;
- JSValue* exception;
-#if ENABLE(CTI)
- void* throwReturnAddress;
+ Interpreter* interpreter;
+
+ JSValuePtr exception;
+#if ENABLE(JIT)
+ void* exceptionLocation;
#endif
const HashTable* arrayTable;
@@ -78,13 +91,15 @@ namespace JSC {
const HashTable* regExpConstructorTable;
const HashTable* stringTable;
- RefPtr<StructureID> activationStructureID;
- RefPtr<StructureID> interruptedExecutionErrorStructure;
- RefPtr<StructureID> staticScopeStructureID;
- RefPtr<StructureID> stringStructureID;
- RefPtr<StructureID> notAnObjectErrorStubStructure;
- RefPtr<StructureID> notAnObjectStructure;
- RefPtr<StructureID> numberStructureID;
+ RefPtr<Structure> activationStructure;
+ RefPtr<Structure> interruptedExecutionErrorStructure;
+ RefPtr<Structure> staticScopeStructure;
+ RefPtr<Structure> stringStructure;
+ RefPtr<Structure> notAnObjectErrorStubStructure;
+ RefPtr<Structure> notAnObjectStructure;
+#if !USE(ALTERNATE_JSIMMEDIATE)
+ RefPtr<Structure> numberStructure;
+#endif
IdentifierTable* identifierTable;
CommonIdentifiers* propertyNames;
@@ -113,10 +128,17 @@ namespace JSC {
HashSet<JSObject*> arrayVisitedElements;
- Heap heap;
+ ScopeNode* scopeNodeBeingReparsed;
+ Heap heap;
+#if ENABLE(ASSEMBLER)
+ PassRefPtr<ExecutablePool> poolForSize(size_t n) { return m_executableAllocator.poolForSize(n); }
+#endif
private:
JSGlobalData(bool isShared = false);
+#if ENABLE(ASSEMBLER)
+ ExecutableAllocator m_executableAllocator;
+#endif
static JSGlobalData*& sharedInstanceInternal();
};
diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp
index 89c32fd..eb2b349 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
*
* Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,7 @@
#include "GlobalEvalFunction.h"
#include "JSGlobalObjectFunctions.h"
#include "JSLock.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "MathObject.h"
#include "NativeErrorConstructor.h"
#include "NativeErrorPrototype.h"
@@ -78,13 +78,13 @@ static const int initialTickCountThreshold = 255;
// Preferred number of milliseconds between each timeout check
static const int preferredScriptCheckTimeInterval = 1000;
-static inline void markIfNeeded(JSValue* v)
+static inline void markIfNeeded(JSValuePtr v)
{
- if (v && !v->marked())
- v->mark();
+ if (v && !v.marked())
+ v.mark();
}
-static inline void markIfNeeded(const RefPtr<StructureID>& s)
+static inline void markIfNeeded(const RefPtr<Structure>& s)
{
if (s)
s->mark();
@@ -112,9 +112,9 @@ JSGlobalObject::~JSGlobalObject()
HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
- (*it)->globalObject = 0;
+ (*it)->clearGlobalObject();
- RegisterFile& registerFile = globalData()->machine->registerFile();
+ RegisterFile& registerFile = globalData()->interpreter->registerFile();
if (registerFile.globalObject() == this) {
registerFile.setGlobalObject(0);
registerFile.setNumGlobals(0);
@@ -147,7 +147,7 @@ void JSGlobalObject::init(JSObject* thisValue)
reset(prototype());
}
-void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -156,18 +156,19 @@ void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValu
JSVariableObject::put(exec, propertyName, value, slot);
}
-void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue* value, unsigned attributes)
+void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
if (symbolTablePutWithAttributes(propertyName, value, attributes))
return;
- JSValue* valueBefore = getDirect(propertyName);
+ JSValuePtr valueBefore = getDirect(propertyName);
PutPropertySlot slot;
JSVariableObject::put(exec, propertyName, value, slot);
if (!valueBefore) {
- if (JSValue* valueAfter = getDirect(propertyName))
+ JSValuePtr valueAfter = getDirect(propertyName);
+ if (valueAfter)
putDirect(propertyName, valueAfter, attributes);
}
}
@@ -189,54 +190,54 @@ void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyNam
static inline JSObject* lastInPrototypeChain(JSObject* object)
{
JSObject* o = object;
- while (o->prototype()->isObject())
+ while (o->prototype().isObject())
o = asObject(o->prototype());
return o;
}
-void JSGlobalObject::reset(JSValue* prototype)
+void JSGlobalObject::reset(JSValuePtr prototype)
{
ExecState* exec = JSGlobalObject::globalExec();
// Prototypes
- d()->functionPrototype = new (exec) FunctionPrototype(exec, FunctionPrototype::createStructureID(jsNull())); // The real prototype will be set once ObjectPrototype is created.
- d()->prototypeFunctionStructure = PrototypeFunction::createStructureID(d()->functionPrototype);
+ d()->functionPrototype = new (exec) FunctionPrototype(exec, FunctionPrototype::createStructure(jsNull())); // The real prototype will be set once ObjectPrototype is created.
+ d()->prototypeFunctionStructure = PrototypeFunction::createStructure(d()->functionPrototype);
d()->functionPrototype->addFunctionProperties(exec, d()->prototypeFunctionStructure.get());
- d()->objectPrototype = new (exec) ObjectPrototype(exec, ObjectPrototype::createStructureID(jsNull()), d()->prototypeFunctionStructure.get());
- d()->functionPrototype->structureID()->setPrototypeWithoutTransition(d()->objectPrototype);
+ d()->objectPrototype = new (exec) ObjectPrototype(exec, ObjectPrototype::createStructure(jsNull()), d()->prototypeFunctionStructure.get());
+ d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype);
d()->emptyObjectStructure = d()->objectPrototype->inheritorID();
- d()->functionStructure = JSFunction::createStructureID(d()->functionPrototype);
- d()->callbackFunctionStructure = JSCallbackFunction::createStructureID(d()->functionPrototype);
- d()->argumentsStructure = Arguments::createStructureID(d()->objectPrototype);
- d()->callbackConstructorStructure = JSCallbackConstructor::createStructureID(d()->objectPrototype);
- d()->callbackObjectStructure = JSCallbackObject<JSObject>::createStructureID(d()->objectPrototype);
+ d()->functionStructure = JSFunction::createStructure(d()->functionPrototype);
+ d()->callbackFunctionStructure = JSCallbackFunction::createStructure(d()->functionPrototype);
+ d()->argumentsStructure = Arguments::createStructure(d()->objectPrototype);
+ d()->callbackConstructorStructure = JSCallbackConstructor::createStructure(d()->objectPrototype);
+ d()->callbackObjectStructure = JSCallbackObject<JSObject>::createStructure(d()->objectPrototype);
- d()->arrayPrototype = new (exec) ArrayPrototype(ArrayPrototype::createStructureID(d()->objectPrototype));
- d()->arrayStructure = JSArray::createStructureID(d()->arrayPrototype);
- d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructureID(d()->arrayPrototype);
+ d()->arrayPrototype = new (exec) ArrayPrototype(ArrayPrototype::createStructure(d()->objectPrototype));
+ d()->arrayStructure = JSArray::createStructure(d()->arrayPrototype);
+ d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(d()->arrayPrototype);
- d()->stringPrototype = new (exec) StringPrototype(exec, StringPrototype::createStructureID(d()->objectPrototype));
- d()->stringObjectStructure = StringObject::createStructureID(d()->stringPrototype);
+ d()->stringPrototype = new (exec) StringPrototype(exec, StringPrototype::createStructure(d()->objectPrototype));
+ d()->stringObjectStructure = StringObject::createStructure(d()->stringPrototype);
- d()->booleanPrototype = new (exec) BooleanPrototype(exec, BooleanPrototype::createStructureID(d()->objectPrototype), d()->prototypeFunctionStructure.get());
- d()->booleanObjectStructure = BooleanObject::createStructureID(d()->booleanPrototype);
+ d()->booleanPrototype = new (exec) BooleanPrototype(exec, BooleanPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+ d()->booleanObjectStructure = BooleanObject::createStructure(d()->booleanPrototype);
- d()->numberPrototype = new (exec) NumberPrototype(exec, NumberPrototype::createStructureID(d()->objectPrototype), d()->prototypeFunctionStructure.get());
- d()->numberObjectStructure = NumberObject::createStructureID(d()->numberPrototype);
+ d()->numberPrototype = new (exec) NumberPrototype(exec, NumberPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+ d()->numberObjectStructure = NumberObject::createStructure(d()->numberPrototype);
- d()->datePrototype = new (exec) DatePrototype(exec, DatePrototype::createStructureID(d()->objectPrototype));
- d()->dateStructure = DateInstance::createStructureID(d()->datePrototype);
+ d()->datePrototype = new (exec) DatePrototype(exec, DatePrototype::createStructure(d()->objectPrototype));
+ d()->dateStructure = DateInstance::createStructure(d()->datePrototype);
- d()->regExpPrototype = new (exec) RegExpPrototype(exec, RegExpPrototype::createStructureID(d()->objectPrototype), d()->prototypeFunctionStructure.get());
- d()->regExpStructure = RegExpObject::createStructureID(d()->regExpPrototype);
+ d()->regExpPrototype = new (exec) RegExpPrototype(exec, RegExpPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+ d()->regExpStructure = RegExpObject::createStructure(d()->regExpPrototype);
- ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructureID(d()->objectPrototype), d()->prototypeFunctionStructure.get());
- d()->errorStructure = ErrorInstance::createStructureID(errorPrototype);
+ ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
+ d()->errorStructure = ErrorInstance::createStructure(errorPrototype);
- RefPtr<StructureID> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructureID(errorPrototype);
+ RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(errorPrototype);
NativeErrorPrototype* evalErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "EvalError", "EvalError");
NativeErrorPrototype* rangeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "RangeError", "RangeError");
@@ -247,19 +248,19 @@ void JSGlobalObject::reset(JSValue* prototype)
// Constructors
- JSValue* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructureID(d()->functionPrototype), d()->objectPrototype);
- JSValue* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructureID(d()->functionPrototype), d()->functionPrototype);
- JSValue* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructureID(d()->functionPrototype), d()->arrayPrototype);
- JSValue* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructureID(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
- JSValue* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructureID(d()->functionPrototype), d()->booleanPrototype);
- JSValue* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructureID(d()->functionPrototype), d()->numberPrototype);
- JSValue* dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructureID(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype);
+ JSValuePtr objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype);
+ JSValuePtr functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype);
+ JSValuePtr arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype);
+ JSValuePtr stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
+ JSValuePtr booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype);
+ JSValuePtr numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype);
+ JSValuePtr dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype);
- d()->regExpConstructor = new (exec) RegExpConstructor(exec, RegExpConstructor::createStructureID(d()->functionPrototype), d()->regExpPrototype);
+ d()->regExpConstructor = new (exec) RegExpConstructor(exec, RegExpConstructor::createStructure(d()->functionPrototype), d()->regExpPrototype);
- d()->errorConstructor = new (exec) ErrorConstructor(exec, ErrorConstructor::createStructureID(d()->functionPrototype), errorPrototype);
+ d()->errorConstructor = new (exec) ErrorConstructor(exec, ErrorConstructor::createStructure(d()->functionPrototype), errorPrototype);
- RefPtr<StructureID> nativeErrorStructure = NativeErrorConstructor::createStructureID(d()->functionPrototype);
+ RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(d()->functionPrototype);
d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, evalErrorPrototype);
d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, rangeErrorPrototype);
@@ -307,7 +308,7 @@ void JSGlobalObject::reset(JSValue* prototype)
// Set global values.
GlobalPropertyInfo staticGlobals[] = {
- GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, MathObject::createStructureID(d()->objectPrototype)), DontEnum | DontDelete),
+ 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)
@@ -317,7 +318,7 @@ void JSGlobalObject::reset(JSValue* prototype)
// Set global functions.
- d()->evalFunction = new (exec) GlobalEvalFunction(exec, GlobalEvalFunction::createStructureID(d()->functionPrototype), 1, exec->propertyNames().eval, globalFuncEval, this);
+ d()->evalFunction = new (exec) GlobalEvalFunction(exec, GlobalEvalFunction::createStructure(d()->functionPrototype), 1, exec->propertyNames().eval, globalFuncEval, this);
putDirectFunctionWithoutTransition(exec, d()->evalFunction, DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
@@ -330,14 +331,14 @@ void JSGlobalObject::reset(JSValue* prototype)
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
#ifndef NDEBUG
- putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "kjsprint"), globalFuncKJSPrint), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
#endif
resetPrototype(prototype);
}
// Set prototype, and also insert the object prototype at the end of the chain.
-void JSGlobalObject::resetPrototype(JSValue* prototype)
+void JSGlobalObject::resetPrototype(JSValuePtr prototype)
{
setPrototype(prototype);
lastInPrototypeChain(this)->setPrototype(d()->objectPrototype);
@@ -345,17 +346,17 @@ void JSGlobalObject::resetPrototype(JSValue* prototype)
void JSGlobalObject::setTimeoutTime(unsigned timeoutTime)
{
- globalData()->machine->setTimeoutTime(timeoutTime);
+ globalData()->interpreter->setTimeoutTime(timeoutTime);
}
void JSGlobalObject::startTimeoutCheck()
{
- globalData()->machine->startTimeoutCheck();
+ globalData()->interpreter->startTimeoutCheck();
}
void JSGlobalObject::stopTimeoutCheck()
{
- globalData()->machine->stopTimeoutCheck();
+ globalData()->interpreter->stopTimeoutCheck();
}
void JSGlobalObject::mark()
@@ -366,7 +367,7 @@ void JSGlobalObject::mark()
for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
(*it)->mark();
- RegisterFile& registerFile = globalData()->machine->registerFile();
+ RegisterFile& registerFile = globalData()->interpreter->registerFile();
if (registerFile.globalObject() == this)
registerFile.markGlobals(&globalData()->heap);
@@ -407,16 +408,6 @@ void JSGlobalObject::mark()
}
}
-void JSGlobalObject::markCrossHeapDependentObjects()
-{
- // Overridden by subclasses.
-}
-
-JSGlobalObject* JSGlobalObject::toGlobalObject(ExecState*) const
-{
- return const_cast<JSGlobalObject*>(this);
-}
-
ExecState* JSGlobalObject::globalExec()
{
return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize);
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index d8a072a..4a10f64 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -114,21 +114,21 @@ namespace JSC {
DatePrototype* datePrototype;
RegExpPrototype* regExpPrototype;
- RefPtr<StructureID> argumentsStructure;
- RefPtr<StructureID> arrayStructure;
- RefPtr<StructureID> booleanObjectStructure;
- RefPtr<StructureID> callbackConstructorStructure;
- RefPtr<StructureID> callbackFunctionStructure;
- RefPtr<StructureID> callbackObjectStructure;
- RefPtr<StructureID> dateStructure;
- RefPtr<StructureID> emptyObjectStructure;
- RefPtr<StructureID> errorStructure;
- RefPtr<StructureID> functionStructure;
- RefPtr<StructureID> numberObjectStructure;
- RefPtr<StructureID> prototypeFunctionStructure;
- RefPtr<StructureID> regExpMatchesArrayStructure;
- RefPtr<StructureID> regExpStructure;
- RefPtr<StructureID> stringObjectStructure;
+ RefPtr<Structure> argumentsStructure;
+ RefPtr<Structure> arrayStructure;
+ RefPtr<Structure> booleanObjectStructure;
+ RefPtr<Structure> callbackConstructorStructure;
+ RefPtr<Structure> callbackFunctionStructure;
+ RefPtr<Structure> callbackObjectStructure;
+ RefPtr<Structure> dateStructure;
+ RefPtr<Structure> emptyObjectStructure;
+ RefPtr<Structure> errorStructure;
+ RefPtr<Structure> functionStructure;
+ RefPtr<Structure> numberObjectStructure;
+ RefPtr<Structure> prototypeFunctionStructure;
+ RefPtr<Structure> regExpMatchesArrayStructure;
+ RefPtr<Structure> regExpStructure;
+ RefPtr<Structure> stringObjectStructure;
SymbolTable symbolTable;
unsigned profileGroup;
@@ -142,13 +142,13 @@ namespace JSC {
void* operator new(size_t, JSGlobalData*);
explicit JSGlobalObject()
- : JSVariableObject(JSGlobalObject::createStructureID(jsNull()), new JSGlobalObjectData)
+ : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData)
{
init(this);
}
protected:
- JSGlobalObject(PassRefPtr<StructureID> structure, JSGlobalObjectData* data, JSObject* thisValue)
+ JSGlobalObject(PassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue)
: JSVariableObject(structure, data)
{
init(thisValue);
@@ -158,12 +158,11 @@ namespace JSC {
virtual ~JSGlobalObject();
virtual void mark();
- virtual void markCrossHeapDependentObjects();
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
- virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
- virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes);
+ virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
+ virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes);
virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc);
virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc);
@@ -196,21 +195,21 @@ namespace JSC {
DatePrototype* datePrototype() const { return d()->datePrototype; }
RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; }
- StructureID* argumentsStructure() const { return d()->argumentsStructure.get(); }
- StructureID* arrayStructure() const { return d()->arrayStructure.get(); }
- StructureID* booleanObjectStructure() const { return d()->booleanObjectStructure.get(); }
- StructureID* callbackConstructorStructure() const { return d()->callbackConstructorStructure.get(); }
- StructureID* callbackFunctionStructure() const { return d()->callbackFunctionStructure.get(); }
- StructureID* callbackObjectStructure() const { return d()->callbackObjectStructure.get(); }
- StructureID* dateStructure() const { return d()->dateStructure.get(); }
- StructureID* emptyObjectStructure() const { return d()->emptyObjectStructure.get(); }
- StructureID* errorStructure() const { return d()->errorStructure.get(); }
- StructureID* functionStructure() const { return d()->functionStructure.get(); }
- StructureID* numberObjectStructure() const { return d()->numberObjectStructure.get(); }
- StructureID* prototypeFunctionStructure() const { return d()->prototypeFunctionStructure.get(); }
- StructureID* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); }
- StructureID* regExpStructure() const { return d()->regExpStructure.get(); }
- StructureID* stringObjectStructure() const { return d()->stringObjectStructure.get(); }
+ Structure* argumentsStructure() const { return d()->argumentsStructure.get(); }
+ Structure* arrayStructure() const { return d()->arrayStructure.get(); }
+ Structure* booleanObjectStructure() const { return d()->booleanObjectStructure.get(); }
+ Structure* callbackConstructorStructure() const { return d()->callbackConstructorStructure.get(); }
+ Structure* callbackFunctionStructure() const { return d()->callbackFunctionStructure.get(); }
+ Structure* callbackObjectStructure() const { return d()->callbackObjectStructure.get(); }
+ Structure* dateStructure() const { return d()->dateStructure.get(); }
+ Structure* emptyObjectStructure() const { return d()->emptyObjectStructure.get(); }
+ Structure* errorStructure() const { return d()->errorStructure.get(); }
+ Structure* functionStructure() const { return d()->functionStructure.get(); }
+ Structure* numberObjectStructure() const { return d()->numberObjectStructure.get(); }
+ Structure* prototypeFunctionStructure() const { return d()->prototypeFunctionStructure.get(); }
+ Structure* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); }
+ Structure* regExpStructure() const { return d()->regExpStructure.get(); }
+ Structure* stringObjectStructure() const { return d()->stringObjectStructure.get(); }
void setProfileGroup(unsigned value) { d()->profileGroup = value; }
unsigned profileGroup() const { return d()->profileGroup; }
@@ -231,7 +230,6 @@ namespace JSC {
ScopeChain& globalScopeChain() { return d()->globalScopeChain; }
virtual bool isGlobalObject() const { return true; }
- virtual JSGlobalObject* toGlobalObject(ExecState*) const;
virtual ExecState* globalExec();
@@ -246,19 +244,19 @@ namespace JSC {
void copyGlobalsFrom(RegisterFile&);
void copyGlobalsTo(RegisterFile&);
- void resetPrototype(JSValue* prototype);
+ void resetPrototype(JSValuePtr prototype);
JSGlobalData* globalData() { return d()->globalData.get(); }
JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType));
}
protected:
struct GlobalPropertyInfo {
- GlobalPropertyInfo(const Identifier& i, JSValue* v, unsigned a)
+ GlobalPropertyInfo(const Identifier& i, JSValuePtr v, unsigned a)
: identifier(i)
, value(v)
, attributes(a)
@@ -266,7 +264,7 @@ namespace JSC {
}
const Identifier identifier;
- JSValue* value;
+ JSValuePtr value;
unsigned attributes;
};
void addStaticGlobals(GlobalPropertyInfo*, int count);
@@ -274,16 +272,16 @@ namespace JSC {
private:
// FIXME: Fold reset into init.
void init(JSObject* thisValue);
- void reset(JSValue* prototype);
+ void reset(JSValuePtr prototype);
void setRegisters(Register* registers, Register* registerArray, size_t count);
void* operator new(size_t); // can only be allocated with JSGlobalData
};
- JSGlobalObject* asGlobalObject(JSValue*);
+ JSGlobalObject* asGlobalObject(JSValuePtr);
- inline JSGlobalObject* asGlobalObject(JSValue* value)
+ inline JSGlobalObject* asGlobalObject(JSValuePtr value)
{
ASSERT(asObject(value)->isGlobalObject());
return static_cast<JSGlobalObject*>(asObject(value));
@@ -335,7 +333,7 @@ namespace JSC {
return asGlobalObject(n->object);
}
- inline JSValue* StructureID::prototypeForLookup(ExecState* exec)
+ inline JSValuePtr Structure::prototypeForLookup(ExecState* exec)
{
if (typeInfo().type() == ObjectType)
return m_prototype;
@@ -357,7 +355,26 @@ namespace JSC {
ASSERT(globalData().dynamicGlobalObject);
return globalData().dynamicGlobalObject;
}
-
+
+ class DynamicGlobalObjectScope : Noncopyable {
+ public:
+ DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject)
+ : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
+ , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
+ {
+ m_dynamicGlobalObjectSlot = dynamicGlobalObject;
+ }
+
+ ~DynamicGlobalObjectScope()
+ {
+ m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject;
+ }
+
+ private:
+ JSGlobalObject*& m_dynamicGlobalObjectSlot;
+ JSGlobalObject* m_savedDynamicGlobalObject;
+ };
+
} // namespace JSC
#endif // JSGlobalObject_h
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index 8bb1c6b..91ea130 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
*
@@ -25,16 +25,15 @@
#include "config.h"
#include "JSGlobalObjectFunctions.h"
-#include "ExecState.h"
+#include "CallFrame.h"
#include "GlobalEvalFunction.h"
#include "JSGlobalObject.h"
#include "JSString.h"
-#include "Machine.h"
+#include "Interpreter.h"
#include "Parser.h"
#include "dtoa.h"
-#include "lexer.h"
-#include "nodes.h"
-#include <errno.h>
+#include "Lexer.h"
+#include "Nodes.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -48,9 +47,9 @@ using namespace Unicode;
namespace JSC {
-static JSValue* encode(ExecState* exec, const ArgList& args, const char* doNotEscape)
+static JSValuePtr encode(ExecState* exec, const ArgList& args, const char* doNotEscape)
{
- UString str = args.at(exec, 0)->toString(exec);
+ UString str = args.at(exec, 0).toString(exec);
CString cstr = str.UTF8String(true);
if (!cstr.c_str())
return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
@@ -70,10 +69,10 @@ static JSValue* encode(ExecState* exec, const ArgList& args, const char* doNotEs
return jsString(exec, result);
}
-static JSValue* decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
+static JSValuePtr decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
{
UString result = "";
- UString str = args.at(exec, 0)->toString(exec);
+ UString str = args.at(exec, 0).toString(exec);
int k = 0;
int len = str.size();
const UChar* d = str.data();
@@ -239,7 +238,7 @@ static double parseInt(const UString& s, int radix)
if (number >= mantissaOverflowLowerBound) {
if (radix == 10)
- number = strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
+ number = WTF::strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
number = parseIntOverflow(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), p - firstDigitPosition, radix);
}
@@ -269,18 +268,18 @@ static double parseFloat(const UString& s)
return s.toDouble(true /*tolerant*/, false /* NaN for empty string */);
}
-JSValue* globalFuncEval(ExecState* exec, JSObject* function, JSValue* thisValue, const ArgList& args)
+JSValuePtr globalFuncEval(ExecState* exec, JSObject* function, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObject = thisValue->toThisObject(exec);
- JSGlobalObject* globalObject = thisObject->toGlobalObject(exec);
- if (!globalObject || globalObject->evalFunction() != function)
+ JSObject* thisObject = thisValue.toThisObject(exec);
+ JSObject* unwrappedObject = thisObject->unwrappedObject();
+ if (!unwrappedObject->isGlobalObject() || static_cast<JSGlobalObject*>(unwrappedObject)->evalFunction() != function)
return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
- JSValue* x = args.at(exec, 0);
- if (!x->isString())
+ JSValuePtr x = args.at(exec, 0);
+ if (!x.isString())
return x;
- UString s = x->toString(exec);
+ UString s = x.toString(exec);
int errLine;
UString errMsg;
@@ -291,43 +290,45 @@ JSValue* globalFuncEval(ExecState* exec, JSObject* function, JSValue* thisValue,
if (!evalNode)
return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), NULL);
- return exec->machine()->execute(evalNode.get(), exec, thisObject, globalObject->globalScopeChain().node(), exec->exceptionSlot());
+ return exec->interpreter()->execute(evalNode.get(), exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot());
}
-JSValue* globalFuncParseInt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncParseInt(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- JSValue* value = args.at(exec, 0);
- int32_t radix = args.at(exec, 1)->toInt32(exec);
+ JSValuePtr value = args.at(exec, 0);
+ int32_t radix = args.at(exec, 1).toInt32(exec);
- if (value->isNumber() && (radix == 0 || radix == 10)) {
- if (JSImmediate::isImmediate(value))
+ if (value.isNumber() && (radix == 0 || radix == 10)) {
+ if (value.isInt32Fast())
return value;
- double d = value->uncheckedGetNumber();
- if (!isfinite(d))
- return JSImmediate::zeroImmediate();
- return jsNumber(exec, floor(d));
+ double d = value.uncheckedGetNumber();
+ if (isfinite(d))
+ return jsNumber(exec, floor(d));
+ if (isnan(d) || isinf(d))
+ return jsNaN(&exec->globalData());
+ return js0();
}
- return jsNumber(exec, parseInt(value->toString(exec), radix));
+ return jsNumber(exec, parseInt(value.toString(exec), radix));
}
-JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncParseFloat(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, parseFloat(args.at(exec, 0)->toString(exec)));
+ return jsNumber(exec, parseFloat(args.at(exec, 0).toString(exec)));
}
-JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncIsNaN(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsBoolean(isnan(args.at(exec, 0)->toNumber(exec)));
+ return jsBoolean(isnan(args.at(exec, 0).toNumber(exec)));
}
-JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncIsFinite(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- double n = args.at(exec, 0)->toNumber(exec);
+ double n = args.at(exec, 0).toNumber(exec);
return jsBoolean(!isnan(n) && !isinf(n));
}
-JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncDecodeURI(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
static const char do_not_unescape_when_decoding_URI[] =
"#$&+,/:;=?@";
@@ -335,12 +336,12 @@ JSValue* globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList
return decode(exec, args, do_not_unescape_when_decoding_URI, true);
}
-JSValue* globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
return decode(exec, args, "", true);
}
-JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncEncodeURI(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
static const char do_not_escape_when_encoding_URI[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -351,7 +352,7 @@ JSValue* globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue*, const ArgList
return encode(exec, args, do_not_escape_when_encoding_URI);
}
-JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
static const char do_not_escape_when_encoding_URI_component[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -362,7 +363,7 @@ JSValue* globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue*, cons
return encode(exec, args, do_not_escape_when_encoding_URI_component);
}
-JSValue* globalFuncEscape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncEscape(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
static const char do_not_escape[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -372,7 +373,7 @@ JSValue* globalFuncEscape(ExecState* exec, JSObject*, JSValue*, const ArgList& a
UString result = "";
UString s;
- UString str = args.at(exec, 0)->toString(exec);
+ UString str = args.at(exec, 0).toString(exec);
const UChar* c = str.data();
for (int k = 0; k < str.size(); k++, c++) {
int u = c[0];
@@ -393,10 +394,10 @@ JSValue* globalFuncEscape(ExecState* exec, JSObject*, JSValue*, const ArgList& a
return jsString(exec, result);
}
-JSValue* globalFuncUnescape(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncUnescape(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
UString result = "";
- UString str = args.at(exec, 0)->toString(exec);
+ UString str = args.at(exec, 0).toString(exec);
int k = 0;
int len = str.size();
while (k < len) {
@@ -421,10 +422,10 @@ JSValue* globalFuncUnescape(ExecState* exec, JSObject*, JSValue*, const ArgList&
}
#ifndef NDEBUG
-JSValue* globalFuncKJSPrint(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr globalFuncJSCPrint(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
CStringBuffer string;
- args.at(exec, 0)->toString(exec).getCString(string);
+ args.at(exec, 0).toString(exec).getCString(string);
puts(string.data());
return jsUndefined();
}
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.h b/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
index 8df700d..0929b17 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
*
@@ -24,34 +24,36 @@
#ifndef JSGlobalObjectFunctions_h
#define JSGlobalObjectFunctions_h
-#include "JSImmediate.h" // temporary until JSValue* becomes a class we can forward-declare
+#include <wtf/unicode/Unicode.h>
namespace JSC {
class ArgList;
class ExecState;
class JSObject;
+ class JSValuePtr;
// FIXME: These functions should really be in JSGlobalObject.cpp, but putting them there
// is a 0.5% reduction.
- JSValue* globalFuncEval(ExecState*, JSObject*, JSValue*, const ArgList&);
- JSValue* globalFuncParseInt(ExecState*, JSObject*, JSValue*, const ArgList&);
- JSValue* globalFuncParseFloat(ExecState*, JSObject*, JSValue*, const ArgList&);
- JSValue* globalFuncIsNaN(ExecState*, JSObject*, JSValue*, const ArgList&);
- JSValue* globalFuncIsFinite(ExecState*, JSObject*, JSValue*, const ArgList&);
- JSValue* globalFuncDecodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
- JSValue* globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
- JSValue* globalFuncEncodeURI(ExecState*, JSObject*, JSValue*, const ArgList&);
- JSValue* globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValue*, const ArgList&);
- JSValue* globalFuncEscape(ExecState*, JSObject*, JSValue*, const ArgList&);
- JSValue* globalFuncUnescape(ExecState*, JSObject*, JSValue*, const ArgList&);
+ JSValuePtr globalFuncEval(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValuePtr globalFuncParseInt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValuePtr globalFuncParseFloat(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValuePtr globalFuncIsNaN(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValuePtr globalFuncIsFinite(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValuePtr globalFuncDecodeURI(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValuePtr globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValuePtr globalFuncEncodeURI(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValuePtr globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValuePtr globalFuncEscape(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+ JSValuePtr globalFuncUnescape(ExecState*, JSObject*, JSValuePtr, const ArgList&);
#ifndef NDEBUG
- JSValue* globalFuncKJSPrint(ExecState*, JSObject*, JSValue*, const ArgList&);
+ JSValuePtr globalFuncJSCPrint(ExecState*, JSObject*, JSValuePtr, const ArgList&);
#endif
static const double mantissaOverflowLowerBound = 9007199254740992.0;
double parseIntOverflow(const char*, int length, int radix);
+ bool isStrWhiteSpace(UChar);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSImmediate.cpp b/JavaScriptCore/runtime/JSImmediate.cpp
index e70d66a..c6cca80 100644
--- a/JavaScriptCore/runtime/JSImmediate.cpp
+++ b/JavaScriptCore/runtime/JSImmediate.cpp
@@ -32,20 +32,35 @@
namespace JSC {
-JSObject* JSImmediate::toObject(JSValue* v, ExecState* exec)
+JSObject* JSImmediate::toThisObject(JSValuePtr v, ExecState* exec)
{
ASSERT(isImmediate(v));
if (isNumber(v))
- return constructNumberFromImmediateNumber(exec, v);
+ return constructNumber(exec, v);
if (isBoolean(v))
return constructBooleanFromImmediateBoolean(exec, v);
+ if (v.isNull())
+ return exec->globalThisValue();
- JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v->isNull());
+ JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
exec->setException(exception);
return new (exec) JSNotAnObject(exec, exception);
}
-JSObject* JSImmediate::prototype(JSValue* v, ExecState* exec)
+JSObject* JSImmediate::toObject(JSValuePtr v, ExecState* exec)
+{
+ ASSERT(isImmediate(v));
+ if (isNumber(v))
+ return constructNumber(exec, v);
+ if (isBoolean(v))
+ return constructBooleanFromImmediateBoolean(exec, v);
+
+ JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
+ exec->setException(exception);
+ return new (exec) JSNotAnObject(exec, exception);
+}
+
+JSObject* JSImmediate::prototype(JSValuePtr v, ExecState* exec)
{
ASSERT(isImmediate(v));
if (isNumber(v))
@@ -53,23 +68,34 @@ JSObject* JSImmediate::prototype(JSValue* v, ExecState* exec)
if (isBoolean(v))
return exec->lexicalGlobalObject()->booleanPrototype();
- JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v->isNull());
+ JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
exec->setException(exception);
return new (exec) JSNotAnObject(exec, exception);
}
-UString JSImmediate::toString(JSValue* v)
+UString JSImmediate::toString(JSValuePtr v)
{
ASSERT(isImmediate(v));
- if (isNumber(v))
+ if (isIntegerNumber(v))
return UString::from(getTruncatedInt32(v));
- if (v == jsBoolean(false))
+#if USE(ALTERNATE_JSIMMEDIATE)
+ if (isNumber(v)) {
+ ASSERT(isDoubleNumber(v));
+ double value = doubleValue(v);
+ if (value == 0.0) // +0.0 or -0.0
+ return "0";
+ return UString::from(value);
+ }
+#else
+ ASSERT(!isNumber(v));
+#endif
+ if (jsBoolean(false) == v)
return "false";
- if (v == jsBoolean(true))
+ if (jsBoolean(true) == v)
return "true";
- if (v->isNull())
+ if (v.isNull())
return "null";
- ASSERT(v == jsUndefined());
+ ASSERT(v.isUndefined());
return "undefined";
}
diff --git a/JavaScriptCore/runtime/JSImmediate.h b/JavaScriptCore/runtime/JSImmediate.h
index 5214df5..3a44825 100644
--- a/JavaScriptCore/runtime/JSImmediate.h
+++ b/JavaScriptCore/runtime/JSImmediate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
*
* This library is free software; you can redistribute it and/or
@@ -19,12 +19,14 @@
*
*/
-#ifndef KJS_JS_IMMEDIATE_H
-#define KJS_JS_IMMEDIATE_H
+#ifndef JSImmediate_h
+#define JSImmediate_h
#include <wtf/Assertions.h>
#include <wtf/AlwaysInline.h>
#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
+#include "JSValue.h"
#include <limits>
#include <limits.h>
#include <stdarg.h>
@@ -35,12 +37,48 @@ namespace JSC {
class ExecState;
class JSCell;
+ class JSFastMath;
+ class JSGlobalData;
class JSObject;
- class JSValue;
class UString;
- inline JSValue* noValue() { return 0; }
- inline void* asPointer(JSValue* value) { return value; }
+ JSValuePtr js0();
+ JSValuePtr jsNull();
+ JSValuePtr jsBoolean(bool b);
+ JSValuePtr jsUndefined();
+ JSValuePtr jsImpossibleValue();
+ JSValuePtr jsNumber(ExecState* exec, double d);
+ JSValuePtr jsNumber(ExecState*, char i);
+ JSValuePtr jsNumber(ExecState*, unsigned char i);
+ JSValuePtr jsNumber(ExecState*, short i);
+ JSValuePtr jsNumber(ExecState*, unsigned short i);
+ JSValuePtr jsNumber(ExecState* exec, int i);
+ JSValuePtr jsNumber(ExecState* exec, unsigned i);
+ JSValuePtr jsNumber(ExecState* exec, long i);
+ JSValuePtr jsNumber(ExecState* exec, unsigned long i);
+ JSValuePtr jsNumber(ExecState* exec, long long i);
+ JSValuePtr jsNumber(ExecState* exec, unsigned long long i);
+ JSValuePtr jsNumber(JSGlobalData* globalData, double d);
+ JSValuePtr jsNumber(JSGlobalData* globalData, short i);
+ JSValuePtr jsNumber(JSGlobalData* globalData, unsigned short i);
+ JSValuePtr jsNumber(JSGlobalData* globalData, int i);
+ JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i);
+ JSValuePtr jsNumber(JSGlobalData* globalData, long i);
+ JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i);
+ JSValuePtr jsNumber(JSGlobalData* globalData, long long i);
+ JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i);
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ inline intptr_t reinterpretDoubleToIntptr(double value)
+ {
+ return WTF::bitwise_cast<intptr_t>(value);
+ }
+
+ inline double reinterpretIntptrToDouble(intptr_t value)
+ {
+ return WTF::bitwise_cast<double>(value);
+ }
+#endif
/*
* A JSValue* is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged
@@ -84,385 +122,716 @@ namespace JSC {
* [ zero ] [ zero ] [ tag 'other' ]
*/
+ /*
+ * On 64-bit platforms, we support an alternative encoding form for immediates, if
+ * USE(ALTERNATE_JSIMMEDIATE) is defined. When this format is used, double precision
+ * floating point values may also be encoded as JSImmediates.
+ *
+ * The encoding makes use of unused NaN space in the IEEE754 representation. Any value
+ * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values
+ * can encode a 51-bit payload. Hardware produced and C-library payloads typically
+ * have a payload of zero. We assume that non-zero payloads are available to encode
+ * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are
+ * all set represents a NaN with a non-zero payload, we can use this space in the NaN
+ * ranges to encode other values (however there are also other ranges of NaN space that
+ * could have been selected). This range of NaN space is represented by 64-bit numbers
+ * begining with the 16-bit hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no
+ * valid double-precision numbers will begin fall in these ranges.
+ *
+ * The scheme we have implemented encodes double precision values by adding 2^48 to the
+ * 64-bit integer representation of the number. After this manipulation, no encoded
+ * double-precision value will begin with the pattern 0x0000 or 0xFFFF.
+ *
+ * The top 16-bits denote the type of the encoded JSImmediate:
+ *
+ * Pointer: 0000:PPPP:PPPP:PPPP
+ * 0001:****:****:****
+ * Double:{ ...
+ * FFFE:****:****:****
+ * Integer: FFFF:0000:IIII:IIII
+ *
+ * 32-bit signed integers are marked with the 16-bit tag 0xFFFF. The tag 0x0000
+ * denotes a pointer, or another form of tagged immediate. Boolean, null and undefined
+ * values are encoded in the same manner as the default format.
+ */
+
class JSImmediate {
private:
- friend class CTI; // Whooo!
-
- static const uintptr_t TagMask = 0x3u; // primary tag is 2 bits long
- static const uintptr_t TagBitTypeInteger = 0x1u; // bottom bit set indicates integer, this dominates the following bit
- static const uintptr_t TagBitTypeOther = 0x2u; // second bit set indicates immediate other than an integer
-
- static const uintptr_t ExtendedTagMask = 0xCu; // extended tag holds a further two bits
- static const uintptr_t ExtendedTagBitBool = 0x4u;
- static const uintptr_t ExtendedTagBitUndefined = 0x8u;
-
- static const uintptr_t FullTagTypeMask = TagMask | ExtendedTagMask;
- static const uintptr_t FullTagTypeBool = TagBitTypeOther | ExtendedTagBitBool;
- static const uintptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
- static const uintptr_t FullTagTypeNull = TagBitTypeOther;
+ friend class JIT;
+ friend class JSValuePtr;
+ friend class JSFastMath;
+ friend JSValuePtr js0();
+ friend JSValuePtr jsNull();
+ friend JSValuePtr jsBoolean(bool b);
+ friend JSValuePtr jsUndefined();
+ friend JSValuePtr jsImpossibleValue();
+ friend JSValuePtr jsNumber(ExecState* exec, double d);
+ friend JSValuePtr jsNumber(ExecState*, char i);
+ friend JSValuePtr jsNumber(ExecState*, unsigned char i);
+ friend JSValuePtr jsNumber(ExecState*, short i);
+ friend JSValuePtr jsNumber(ExecState*, unsigned short i);
+ friend JSValuePtr jsNumber(ExecState* exec, int i);
+ friend JSValuePtr jsNumber(ExecState* exec, unsigned i);
+ friend JSValuePtr jsNumber(ExecState* exec, long i);
+ friend JSValuePtr jsNumber(ExecState* exec, unsigned long i);
+ friend JSValuePtr jsNumber(ExecState* exec, long long i);
+ friend JSValuePtr jsNumber(ExecState* exec, unsigned long long i);
+ friend JSValuePtr jsNumber(JSGlobalData* globalData, double d);
+ friend JSValuePtr jsNumber(JSGlobalData* globalData, short i);
+ friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned short i);
+ friend JSValuePtr jsNumber(JSGlobalData* globalData, int i);
+ friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i);
+ friend JSValuePtr jsNumber(JSGlobalData* globalData, long i);
+ friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i);
+ friend JSValuePtr jsNumber(JSGlobalData* globalData, long long i);
+ friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i);
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ // If all bits in the mask are set, this indicates an integer number,
+ // if any but not all are set this value is a double precision number.
+ static const intptr_t TagTypeNumber = 0xffff000000000000ll;
+ // This value is 2^48, used to encode doubles such that the encoded value will begin
+ // with a 16-bit pattern within the range 0x0001..0xFFFE.
+ static const intptr_t DoubleEncodeOffset = 0x1000000000000ll;
+#else
+ static const intptr_t TagTypeNumber = 0x1; // bottom bit set indicates integer, this dominates the following bit
+#endif
+ static const intptr_t TagBitTypeOther = 0x2; // second bit set indicates immediate other than an integer
+ static const intptr_t TagMask = TagTypeNumber | TagBitTypeOther;
+
+ static const intptr_t ExtendedTagMask = 0xC; // extended tag holds a further two bits
+ static const intptr_t ExtendedTagBitBool = 0x4;
+ static const intptr_t ExtendedTagBitUndefined = 0x8;
+
+ static const intptr_t FullTagTypeMask = TagMask | ExtendedTagMask;
+ static const intptr_t FullTagTypeBool = TagBitTypeOther | ExtendedTagBitBool;
+ static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
+ static const intptr_t FullTagTypeNull = TagBitTypeOther;
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static const int32_t IntegerPayloadShift = 0;
+#else
+ static const int32_t IntegerPayloadShift = 1;
+#endif
+ static const int32_t ExtendedPayloadShift = 4;
- static const uint32_t IntegerPayloadShift = 1u;
- static const uint32_t ExtendedPayloadShift = 4u;
+ static const intptr_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift;
- static const uintptr_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift;
+ static const int32_t signBit = 0x80000000;
- public:
- static ALWAYS_INLINE bool isImmediate(JSValue* v)
+ static ALWAYS_INLINE bool isImmediate(JSValuePtr v)
{
return rawValue(v) & TagMask;
}
- static ALWAYS_INLINE bool isNumber(JSValue* v)
+ static ALWAYS_INLINE bool isNumber(JSValuePtr v)
{
- return rawValue(v) & TagBitTypeInteger;
+ return rawValue(v) & TagTypeNumber;
+ }
+
+ static ALWAYS_INLINE bool isIntegerNumber(JSValuePtr v)
+ {
+#if USE(ALTERNATE_JSIMMEDIATE)
+ return (rawValue(v) & TagTypeNumber) == TagTypeNumber;
+#else
+ return isNumber(v);
+#endif
}
- static ALWAYS_INLINE bool isPositiveNumber(JSValue* v)
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static ALWAYS_INLINE bool isDoubleNumber(JSValuePtr v)
+ {
+ return isNumber(v) && !isIntegerNumber(v);
+ }
+#endif
+
+ static ALWAYS_INLINE bool isPositiveIntegerNumber(JSValuePtr v)
{
// A single mask to check for the sign bit and the number tag all at once.
- return (rawValue(v) & (0x80000000 | TagBitTypeInteger)) == TagBitTypeInteger;
+ return (rawValue(v) & (signBit | TagTypeNumber)) == TagTypeNumber;
}
- static ALWAYS_INLINE bool isBoolean(JSValue* v)
+ static ALWAYS_INLINE bool isBoolean(JSValuePtr v)
{
return (rawValue(v) & FullTagTypeMask) == FullTagTypeBool;
}
- static ALWAYS_INLINE bool isUndefinedOrNull(JSValue* v)
+ static ALWAYS_INLINE bool isUndefinedOrNull(JSValuePtr v)
{
// Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
return (rawValue(v) & ~ExtendedTagBitUndefined) == FullTagTypeNull;
}
- static bool isNegative(JSValue* v)
- {
- ASSERT(isNumber(v));
- return rawValue(v) & 0x80000000;
- }
-
- static JSValue* from(char);
- static JSValue* from(signed char);
- static JSValue* from(unsigned char);
- static JSValue* from(short);
- static JSValue* from(unsigned short);
- static JSValue* from(int);
- static JSValue* from(unsigned);
- static JSValue* from(long);
- static JSValue* from(unsigned long);
- static JSValue* from(long long);
- static JSValue* from(unsigned long long);
- static JSValue* from(double);
-
- static ALWAYS_INLINE bool isEitherImmediate(JSValue* v1, JSValue* v2)
+ static JSValuePtr from(char);
+ static JSValuePtr from(signed char);
+ static JSValuePtr from(unsigned char);
+ static JSValuePtr from(short);
+ static JSValuePtr from(unsigned short);
+ static JSValuePtr from(int);
+ static JSValuePtr from(unsigned);
+ static JSValuePtr from(long);
+ static JSValuePtr from(unsigned long);
+ static JSValuePtr from(long long);
+ static JSValuePtr from(unsigned long long);
+ static JSValuePtr from(double);
+
+ static ALWAYS_INLINE bool isEitherImmediate(JSValuePtr v1, JSValuePtr v2)
{
return (rawValue(v1) | rawValue(v2)) & TagMask;
}
- static ALWAYS_INLINE bool isAnyImmediate(JSValue* v1, JSValue* v2, JSValue* v3)
- {
- return (rawValue(v1) | rawValue(v2) | rawValue(v3)) & TagMask;
- }
-
- static ALWAYS_INLINE bool areBothImmediate(JSValue* v1, JSValue* v2)
+ static ALWAYS_INLINE bool areBothImmediate(JSValuePtr v1, JSValuePtr v2)
{
return isImmediate(v1) & isImmediate(v2);
}
- static ALWAYS_INLINE bool areBothImmediateNumbers(JSValue* v1, JSValue* v2)
+ static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValuePtr v1, JSValuePtr v2)
{
- return rawValue(v1) & rawValue(v2) & TagBitTypeInteger;
- }
-
- static ALWAYS_INLINE JSValue* andImmediateNumbers(JSValue* v1, JSValue* v2)
- {
- ASSERT(areBothImmediateNumbers(v1, v2));
- return makeValue(rawValue(v1) & rawValue(v2));
- }
-
- static ALWAYS_INLINE JSValue* xorImmediateNumbers(JSValue* v1, JSValue* v2)
- {
- ASSERT(areBothImmediateNumbers(v1, v2));
- return makeValue((rawValue(v1) ^ rawValue(v2)) | TagBitTypeInteger);
- }
-
- static ALWAYS_INLINE JSValue* orImmediateNumbers(JSValue* v1, JSValue* v2)
- {
- ASSERT(areBothImmediateNumbers(v1, v2));
- return makeValue(rawValue(v1) | rawValue(v2));
- }
-
- static ALWAYS_INLINE JSValue* rightShiftImmediateNumbers(JSValue* val, JSValue* shift)
- {
- ASSERT(areBothImmediateNumbers(val, shift));
- return makeValue((static_cast<intptr_t>(rawValue(val)) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f)) | TagBitTypeInteger);
- }
-
- static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValue* v)
- {
- // Number is non-negative and an operation involving two of these can't overflow.
- // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
- return (rawValue(v) & (TagBitTypeInteger + (3u << 30))) == TagBitTypeInteger;
- }
-
- static ALWAYS_INLINE JSValue* addImmediateNumbers(JSValue* v1, JSValue* v2)
- {
- ASSERT(canDoFastAdditiveOperations(v1));
- ASSERT(canDoFastAdditiveOperations(v2));
- return makeValue(rawValue(v1) + rawValue(v2) - TagBitTypeInteger);
- }
-
- static ALWAYS_INLINE JSValue* subImmediateNumbers(JSValue* v1, JSValue* v2)
- {
- ASSERT(canDoFastAdditiveOperations(v1));
- ASSERT(canDoFastAdditiveOperations(v2));
- return makeValue(rawValue(v1) - rawValue(v2) + TagBitTypeInteger);
- }
-
- static ALWAYS_INLINE JSValue* incImmediateNumber(JSValue* v)
- {
- ASSERT(canDoFastAdditiveOperations(v));
- return makeValue(rawValue(v) + (1 << IntegerPayloadShift));
- }
-
- static ALWAYS_INLINE JSValue* decImmediateNumber(JSValue* v)
- {
- ASSERT(canDoFastAdditiveOperations(v));
- return makeValue(rawValue(v) - (1 << IntegerPayloadShift));
+#if USE(ALTERNATE_JSIMMEDIATE)
+ return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber;
+#else
+ return rawValue(v1) & rawValue(v2) & TagTypeNumber;
+#endif
}
- static double toDouble(JSValue*);
- static bool toBoolean(JSValue*);
- static JSObject* toObject(JSValue*, ExecState*);
- static UString toString(JSValue*);
+ static double toDouble(JSValuePtr);
+ static bool toBoolean(JSValuePtr);
+ static JSObject* toObject(JSValuePtr, ExecState*);
+ static JSObject* toThisObject(JSValuePtr, ExecState*);
+ static UString toString(JSValuePtr);
- static bool getUInt32(JSValue*, uint32_t&);
- static bool getTruncatedInt32(JSValue*, int32_t&);
- static bool getTruncatedUInt32(JSValue*, uint32_t&);
+ static bool getUInt32(JSValuePtr, uint32_t&);
+ static bool getTruncatedInt32(JSValuePtr, int32_t&);
+ static bool getTruncatedUInt32(JSValuePtr, uint32_t&);
- static int32_t getTruncatedInt32(JSValue*);
- static uint32_t getTruncatedUInt32(JSValue*);
+ static int32_t getTruncatedInt32(JSValuePtr);
+ static uint32_t getTruncatedUInt32(JSValuePtr);
- static JSValue* trueImmediate();
- static JSValue* falseImmediate();
- static JSValue* undefinedImmediate();
- static JSValue* nullImmediate();
- static JSValue* zeroImmediate();
- static JSValue* oneImmediate();
+ static JSValuePtr trueImmediate();
+ static JSValuePtr falseImmediate();
+ static JSValuePtr undefinedImmediate();
+ static JSValuePtr nullImmediate();
+ static JSValuePtr zeroImmediate();
+ static JSValuePtr oneImmediate();
- static JSValue* impossibleValue();
+ static JSValuePtr impossibleValue();
- static JSObject* prototype(JSValue*, ExecState*);
+ static JSObject* prototype(JSValuePtr, ExecState*);
private:
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static const int minImmediateInt = ((-INT_MAX) - 1);
+ static const int maxImmediateInt = INT_MAX;
+#else
static const int minImmediateInt = ((-INT_MAX) - 1) >> IntegerPayloadShift;
static const int maxImmediateInt = INT_MAX >> IntegerPayloadShift;
+#endif
static const unsigned maxImmediateUInt = maxImmediateInt;
- static ALWAYS_INLINE JSValue* makeValue(uintptr_t integer)
+ static ALWAYS_INLINE JSValuePtr makeValue(intptr_t integer)
{
- return reinterpret_cast<JSValue*>(integer);
+ return JSValuePtr::makeImmediate(integer);
}
- static ALWAYS_INLINE JSValue* makeInt(int32_t value)
+ // With USE(ALTERNATE_JSIMMEDIATE) we want the argument to be zero extended, so the
+ // integer doesn't interfere with the tag bits in the upper word. In the default encoding,
+ // if intptr_t id larger then int32_t we sign extend the value through the upper word.
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static ALWAYS_INLINE JSValuePtr makeInt(uint32_t value)
+#else
+ static ALWAYS_INLINE JSValuePtr makeInt(int32_t value)
+#endif
{
- return makeValue((value << IntegerPayloadShift) | TagBitTypeInteger);
+ return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeNumber);
}
- static ALWAYS_INLINE JSValue* makeBool(bool b)
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static ALWAYS_INLINE JSValuePtr makeDouble(double value)
{
- return makeValue((static_cast<uintptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool);
+ return makeValue(reinterpretDoubleToIntptr(value) + DoubleEncodeOffset);
}
+#endif
- static ALWAYS_INLINE JSValue* makeUndefined()
+ static ALWAYS_INLINE JSValuePtr makeBool(bool b)
+ {
+ return makeValue((static_cast<intptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool);
+ }
+
+ static ALWAYS_INLINE JSValuePtr makeUndefined()
{
return makeValue(FullTagTypeUndefined);
}
- static ALWAYS_INLINE JSValue* makeNull()
+ static ALWAYS_INLINE JSValuePtr makeNull()
{
return makeValue(FullTagTypeNull);
}
-
- static ALWAYS_INLINE int32_t intValue(JSValue* v)
+
+ template<typename T>
+ static JSValuePtr fromNumberOutsideIntegerRange(T);
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ static ALWAYS_INLINE double doubleValue(JSValuePtr v)
{
- return static_cast<int32_t>(static_cast<intptr_t>(rawValue(v)) >> IntegerPayloadShift);
+ return reinterpretIntptrToDouble(rawValue(v) - DoubleEncodeOffset);
+ }
+#endif
+
+ static ALWAYS_INLINE int32_t intValue(JSValuePtr v)
+ {
+ return static_cast<int32_t>(rawValue(v) >> IntegerPayloadShift);
}
- static ALWAYS_INLINE uint32_t uintValue(JSValue* v)
+ static ALWAYS_INLINE uint32_t uintValue(JSValuePtr v)
{
return static_cast<uint32_t>(rawValue(v) >> IntegerPayloadShift);
}
- static ALWAYS_INLINE bool boolValue(JSValue* v)
+ static ALWAYS_INLINE bool boolValue(JSValuePtr v)
{
return rawValue(v) & ExtendedPayloadBitBoolValue;
}
- static ALWAYS_INLINE uintptr_t rawValue(JSValue* v)
+ static ALWAYS_INLINE intptr_t rawValue(JSValuePtr v)
{
- return reinterpret_cast<uintptr_t>(v);
+ return v.immediateValue();
}
static double nonInlineNaN();
};
- ALWAYS_INLINE JSValue* JSImmediate::trueImmediate() { return makeBool(true); }
- ALWAYS_INLINE JSValue* JSImmediate::falseImmediate() { return makeBool(false); }
- ALWAYS_INLINE JSValue* JSImmediate::undefinedImmediate() { return makeUndefined(); }
- ALWAYS_INLINE JSValue* JSImmediate::nullImmediate() { return makeNull(); }
- ALWAYS_INLINE JSValue* JSImmediate::zeroImmediate() { return makeInt(0); }
- ALWAYS_INLINE JSValue* JSImmediate::oneImmediate() { return makeInt(1); }
+ ALWAYS_INLINE JSValuePtr JSImmediate::trueImmediate() { return makeBool(true); }
+ ALWAYS_INLINE JSValuePtr JSImmediate::falseImmediate() { return makeBool(false); }
+ ALWAYS_INLINE JSValuePtr JSImmediate::undefinedImmediate() { return makeUndefined(); }
+ ALWAYS_INLINE JSValuePtr JSImmediate::nullImmediate() { return makeNull(); }
+ ALWAYS_INLINE JSValuePtr JSImmediate::zeroImmediate() { return makeInt(0); }
+ ALWAYS_INLINE JSValuePtr JSImmediate::oneImmediate() { return makeInt(1); }
// This value is impossible because 0x4 is not a valid pointer but a tag of 0 would indicate non-immediate
- ALWAYS_INLINE JSValue* JSImmediate::impossibleValue() { return makeValue(0x4); }
+ ALWAYS_INLINE JSValuePtr JSImmediate::impossibleValue() { return makeValue(0x4); }
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ inline bool doubleToBoolean(double value)
+ {
+ return value < 0.0 || value > 0.0;
+ }
- ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue* v)
+ ALWAYS_INLINE bool JSImmediate::toBoolean(JSValuePtr v)
+ {
+ ASSERT(isImmediate(v));
+ return isNumber(v) ? isIntegerNumber(v) ? v != zeroImmediate()
+ : doubleToBoolean(doubleValue(v)) : v == trueImmediate();
+ }
+#else
+ ALWAYS_INLINE bool JSImmediate::toBoolean(JSValuePtr v)
{
ASSERT(isImmediate(v));
- uintptr_t bits = rawValue(v);
- return (bits & TagBitTypeInteger)
- ? bits != TagBitTypeInteger // !0 ints
- : bits == (FullTagTypeBool | ExtendedPayloadBitBoolValue); // bool true
+ return isIntegerNumber(v) ? v != zeroImmediate() : v == trueImmediate();
}
+#endif
- ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue* v)
+ ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValuePtr v)
{
- ASSERT(isNumber(v));
+ // FIXME: should probably be asserting isPositiveIntegerNumber here.
+ ASSERT(isIntegerNumber(v));
return intValue(v);
}
- ALWAYS_INLINE JSValue* JSImmediate::from(char i)
+#if USE(ALTERNATE_JSIMMEDIATE)
+ template<typename T>
+ inline JSValuePtr JSImmediate::fromNumberOutsideIntegerRange(T value)
+ {
+ return makeDouble(static_cast<double>(value));
+ }
+#else
+ template<typename T>
+ inline JSValuePtr JSImmediate::fromNumberOutsideIntegerRange(T)
+ {
+ return noValue();
+ }
+#endif
+
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(char i)
{
return makeInt(i);
}
- ALWAYS_INLINE JSValue* JSImmediate::from(signed char i)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(signed char i)
{
return makeInt(i);
}
- ALWAYS_INLINE JSValue* JSImmediate::from(unsigned char i)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned char i)
{
return makeInt(i);
}
- ALWAYS_INLINE JSValue* JSImmediate::from(short i)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(short i)
{
return makeInt(i);
}
- ALWAYS_INLINE JSValue* JSImmediate::from(unsigned short i)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned short i)
{
return makeInt(i);
}
- ALWAYS_INLINE JSValue* JSImmediate::from(int i)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(int i)
{
+#if !USE(ALTERNATE_JSIMMEDIATE)
if ((i < minImmediateInt) | (i > maxImmediateInt))
- return noValue();
+ return fromNumberOutsideIntegerRange(i);
+#endif
return makeInt(i);
}
- ALWAYS_INLINE JSValue* JSImmediate::from(unsigned i)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned i)
{
if (i > maxImmediateUInt)
- return noValue();
+ return fromNumberOutsideIntegerRange(i);
return makeInt(i);
}
- ALWAYS_INLINE JSValue* JSImmediate::from(long i)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(long i)
{
if ((i < minImmediateInt) | (i > maxImmediateInt))
- return noValue();
+ return fromNumberOutsideIntegerRange(i);
return makeInt(i);
}
- ALWAYS_INLINE JSValue* JSImmediate::from(unsigned long i)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned long i)
{
if (i > maxImmediateUInt)
- return noValue();
+ return fromNumberOutsideIntegerRange(i);
return makeInt(i);
}
- ALWAYS_INLINE JSValue* JSImmediate::from(long long i)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(long long i)
{
if ((i < minImmediateInt) | (i > maxImmediateInt))
return noValue();
- return makeInt(static_cast<uintptr_t>(i));
+ return makeInt(static_cast<intptr_t>(i));
}
- ALWAYS_INLINE JSValue* JSImmediate::from(unsigned long long i)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned long long i)
{
if (i > maxImmediateUInt)
- return noValue();
- return makeInt(static_cast<uintptr_t>(i));
+ return fromNumberOutsideIntegerRange(i);
+ return makeInt(static_cast<intptr_t>(i));
}
- ALWAYS_INLINE JSValue* JSImmediate::from(double d)
+ ALWAYS_INLINE JSValuePtr JSImmediate::from(double d)
{
const int intVal = static_cast<int>(d);
- if ((intVal < minImmediateInt) | (intVal > maxImmediateInt))
- return noValue();
-
// Check for data loss from conversion to int.
if (intVal != d || (!intVal && signbit(d)))
- return noValue();
+ return fromNumberOutsideIntegerRange(d);
- return makeInt(intVal);
+ return from(intVal);
}
- ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValue* v)
+ ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValuePtr v)
{
- ASSERT(isNumber(v));
+ ASSERT(isIntegerNumber(v));
return intValue(v);
}
- ALWAYS_INLINE double JSImmediate::toDouble(JSValue* v)
+ ALWAYS_INLINE double JSImmediate::toDouble(JSValuePtr v)
{
ASSERT(isImmediate(v));
- int i;
- if (isNumber(v))
- i = intValue(v);
- else if (rawValue(v) == FullTagTypeUndefined)
+
+ if (isIntegerNumber(v))
+ return intValue(v);
+
+#if USE(ALTERNATE_JSIMMEDIATE)
+ if (isNumber(v)) {
+ ASSERT(isDoubleNumber(v));
+ return doubleValue(v);
+ }
+#else
+ ASSERT(!isNumber(v));
+#endif
+
+ if (rawValue(v) == FullTagTypeUndefined)
return nonInlineNaN();
- else
- i = rawValue(v) >> ExtendedPayloadShift;
- return i;
+
+ ASSERT(JSImmediate::isBoolean(v) || (v == JSImmediate::nullImmediate()));
+ return rawValue(v) >> ExtendedPayloadShift;
}
- ALWAYS_INLINE bool JSImmediate::getUInt32(JSValue* v, uint32_t& i)
+ ALWAYS_INLINE bool JSImmediate::getUInt32(JSValuePtr v, uint32_t& i)
{
i = uintValue(v);
- return isPositiveNumber(v);
+ return isPositiveIntegerNumber(v);
}
- ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValue* v, int32_t& i)
+ ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValuePtr v, int32_t& i)
{
i = intValue(v);
- return isNumber(v);
+ return isIntegerNumber(v);
}
- ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValue* v, uint32_t& i)
+ ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValuePtr v, uint32_t& i)
{
return getUInt32(v, i);
}
- ALWAYS_INLINE JSValue* jsUndefined()
+ inline JSValuePtr js0()
{
- return JSImmediate::undefinedImmediate();
+ return JSImmediate::zeroImmediate();
}
- inline JSValue* jsNull()
+ inline JSValuePtr jsNull()
{
return JSImmediate::nullImmediate();
}
- inline JSValue* jsBoolean(bool b)
+ inline JSValuePtr jsBoolean(bool b)
{
return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate();
}
-} // namespace JSC
+ inline JSValuePtr jsUndefined()
+ {
+ return JSImmediate::undefinedImmediate();
+ }
+
+ inline JSValuePtr jsImpossibleValue()
+ {
+ return JSImmediate::impossibleValue();
+ }
+
+ // These are identical logic to the JSValue functions above, and faster than jsNumber(number).toInt32().
+ int32_t toInt32(double);
+ uint32_t toUInt32(double);
+ int32_t toInt32SlowCase(double, bool& ok);
+ uint32_t toUInt32SlowCase(double, bool& ok);
+
+ inline bool JSValuePtr::isUndefined() const
+ {
+ return asValue() == jsUndefined();
+ }
+
+ inline bool JSValuePtr::isNull() const
+ {
+ return asValue() == jsNull();
+ }
+
+ inline bool JSValuePtr::isUndefinedOrNull() const
+ {
+ return JSImmediate::isUndefinedOrNull(asValue());
+ }
+
+ inline bool JSValuePtr::isBoolean() const
+ {
+ return JSImmediate::isBoolean(asValue());
+ }
+
+ inline bool JSValuePtr::getBoolean(bool& v) const
+ {
+ if (JSImmediate::isBoolean(asValue())) {
+ v = JSImmediate::toBoolean(asValue());
+ return true;
+ }
+
+ return false;
+ }
+
+ inline bool JSValuePtr::getBoolean() const
+ {
+ return asValue() == jsBoolean(true);
+ }
+
+ ALWAYS_INLINE int32_t JSValuePtr::toInt32(ExecState* exec) const
+ {
+ int32_t i;
+ if (getTruncatedInt32(i))
+ return i;
+ bool ignored;
+ return toInt32SlowCase(toNumber(exec), ignored);
+ }
+
+ inline uint32_t JSValuePtr::toUInt32(ExecState* exec) const
+ {
+ uint32_t i;
+ if (getTruncatedUInt32(i))
+ return i;
+ bool ignored;
+ return toUInt32SlowCase(toNumber(exec), ignored);
+ }
+
+ inline int32_t toInt32(double val)
+ {
+ if (!(val >= -2147483648.0 && val < 2147483648.0)) {
+ bool ignored;
+ return toInt32SlowCase(val, ignored);
+ }
+ return static_cast<int32_t>(val);
+ }
+
+ inline uint32_t toUInt32(double val)
+ {
+ if (!(val >= 0.0 && val < 4294967296.0)) {
+ bool ignored;
+ return toUInt32SlowCase(val, ignored);
+ }
+ return static_cast<uint32_t>(val);
+ }
+
+ inline int32_t JSValuePtr::toInt32(ExecState* exec, bool& ok) const
+ {
+ int32_t i;
+ if (getTruncatedInt32(i)) {
+ ok = true;
+ return i;
+ }
+ return toInt32SlowCase(toNumber(exec), ok);
+ }
+
+ inline uint32_t JSValuePtr::toUInt32(ExecState* exec, bool& ok) const
+ {
+ uint32_t i;
+ if (getTruncatedUInt32(i)) {
+ ok = true;
+ return i;
+ }
+ return toUInt32SlowCase(toNumber(exec), ok);
+ }
+
+ inline bool JSValuePtr::isCell() const
+ {
+ return !JSImmediate::isImmediate(asValue());
+ }
+
+ inline bool JSValuePtr::isInt32Fast() const
+ {
+ return JSImmediate::isIntegerNumber(asValue());
+ }
+
+ inline int32_t JSValuePtr::getInt32Fast() const
+ {
+ ASSERT(isInt32Fast());
+ return JSImmediate::getTruncatedInt32(asValue());
+ }
+
+ inline bool JSValuePtr::isUInt32Fast() const
+ {
+ return JSImmediate::isPositiveIntegerNumber(asValue());
+ }
+
+ inline uint32_t JSValuePtr::getUInt32Fast() const
+ {
+ ASSERT(isUInt32Fast());
+ return JSImmediate::getTruncatedUInt32(asValue());
+ }
+
+ inline JSValuePtr JSValuePtr::makeInt32Fast(int32_t i)
+ {
+ return JSImmediate::from(i);
+ }
+ inline bool JSValuePtr::areBothInt32Fast(JSValuePtr v1, JSValuePtr v2)
+ {
+ return JSImmediate::areBothImmediateIntegerNumbers(v1, v2);
+ }
+
+ class JSFastMath {
+ public:
+ static ALWAYS_INLINE bool canDoFastBitwiseOperations(JSValuePtr v1, JSValuePtr v2)
+ {
+ return JSImmediate::areBothImmediateIntegerNumbers(v1, v2);
+ }
+
+ static ALWAYS_INLINE JSValuePtr equal(JSValuePtr v1, JSValuePtr v2)
+ {
+ ASSERT(canDoFastBitwiseOperations(v1, v2));
+ return jsBoolean(v1 == v2);
+ }
+
+ static ALWAYS_INLINE JSValuePtr notEqual(JSValuePtr v1, JSValuePtr v2)
+ {
+ ASSERT(canDoFastBitwiseOperations(v1, v2));
+ return jsBoolean(v1 != v2);
+ }
+
+ static ALWAYS_INLINE JSValuePtr andImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
+ {
+ ASSERT(canDoFastBitwiseOperations(v1, v2));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v1) & JSImmediate::rawValue(v2));
+ }
+
+ static ALWAYS_INLINE JSValuePtr xorImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
+ {
+ ASSERT(canDoFastBitwiseOperations(v1, v2));
+ return JSImmediate::makeValue((JSImmediate::rawValue(v1) ^ JSImmediate::rawValue(v2)) | JSImmediate::TagTypeNumber);
+ }
+
+ static ALWAYS_INLINE JSValuePtr orImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
+ {
+ ASSERT(canDoFastBitwiseOperations(v1, v2));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v1) | JSImmediate::rawValue(v2));
+ }
+
+ static ALWAYS_INLINE bool canDoFastRshift(JSValuePtr v1, JSValuePtr v2)
+ {
+ return JSImmediate::areBothImmediateIntegerNumbers(v1, v2);
+ }
+
+ static ALWAYS_INLINE bool canDoFastUrshift(JSValuePtr v1, JSValuePtr v2)
+ {
+ return JSImmediate::areBothImmediateIntegerNumbers(v1, v2) && !(JSImmediate::rawValue(v1) & JSImmediate::signBit);
+ }
+
+ static ALWAYS_INLINE JSValuePtr rightShiftImmediateNumbers(JSValuePtr val, JSValuePtr shift)
+ {
+ ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift));
+#if USE(ALTERNATE_JSIMMEDIATE)
+ return JSImmediate::makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(JSImmediate::rawValue(val)) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f))) | JSImmediate::TagTypeNumber);
+#else
+ return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagTypeNumber);
#endif
+ }
+
+ static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v)
+ {
+ // Number is non-negative and an operation involving two of these can't overflow.
+ // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
+ return (JSImmediate::rawValue(v) & (JSImmediate::TagTypeNumber + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeNumber;
+ }
+
+ static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v1, JSValuePtr v2)
+ {
+ // Number is non-negative and an operation involving two of these can't overflow.
+ // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
+ return canDoFastAdditiveOperations(v1) && canDoFastAdditiveOperations(v2);
+ }
+
+ static ALWAYS_INLINE JSValuePtr addImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
+ {
+ ASSERT(canDoFastAdditiveOperations(v1, v2));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v1) + JSImmediate::rawValue(v2) - JSImmediate::TagTypeNumber);
+ }
+
+ static ALWAYS_INLINE JSValuePtr subImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
+ {
+ ASSERT(canDoFastAdditiveOperations(v1, v2));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v1) - JSImmediate::rawValue(v2) + JSImmediate::TagTypeNumber);
+ }
+
+ static ALWAYS_INLINE JSValuePtr incImmediateNumber(JSValuePtr v)
+ {
+ ASSERT(canDoFastAdditiveOperations(v));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v) + (1 << JSImmediate::IntegerPayloadShift));
+ }
+
+ static ALWAYS_INLINE JSValuePtr decImmediateNumber(JSValuePtr v)
+ {
+ ASSERT(canDoFastAdditiveOperations(v));
+ return JSImmediate::makeValue(JSImmediate::rawValue(v) - (1 << JSImmediate::IntegerPayloadShift));
+ }
+ };
+
+} // namespace JSC
+
+#endif // JSImmediate_h
diff --git a/JavaScriptCore/runtime/JSLock.cpp b/JavaScriptCore/runtime/JSLock.cpp
index ee7fb3b..7ece5da 100644
--- a/JavaScriptCore/runtime/JSLock.cpp
+++ b/JavaScriptCore/runtime/JSLock.cpp
@@ -21,8 +21,8 @@
#include "config.h"
#include "JSLock.h"
-#include "collector.h"
-#include "ExecState.h"
+#include "Collector.h"
+#include "CallFrame.h"
#if ENABLE(JSC_MULTIPLE_THREADS)
#include <pthread.h>
@@ -119,11 +119,58 @@ bool JSLock::currentThreadIsHoldingLock()
return !!pthread_getspecific(JSLockCount);
}
+// This is fairly nasty. We allow multiple threads to run on the same
+// context, and we do not require any locking semantics in doing so -
+// clients of the API may simply use the context from multiple threads
+// concurently, and assume this will work. In order to make this work,
+// We lock the context when a thread enters, and unlock it when it leaves.
+// However we do not only unlock when the thread returns from its
+// entry point (evaluate script or call function), we also unlock the
+// context if the thread leaves JSC by making a call out to an external
+// function through a callback.
+//
+// All threads using the context share the same JS stack (the RegisterFile).
+// Whenever a thread calls into JSC it starts using the RegisterFile from the
+// previous 'high water mark' - the maximum point the stack has ever grown to
+// (returned by RegisterFile::end()). So if a first thread calls out to a
+// callback, and a second thread enters JSC, then also exits by calling out
+// to a callback, we can be left with stackframes from both threads in the
+// RegisterFile. As such, a problem may occur should the first thread's
+// callback complete first, and attempt to return to JSC. Were we to allow
+// this to happen, and were its stack to grow further, then it may potentially
+// write over the second thread's call frames.
+//
+// In avoid JS stack corruption we enforce a policy of only ever allowing two
+// threads to use a JS context concurrently, and only allowing the second of
+// these threads to execute until it has completed and fully returned from its
+// outermost call into JSC. We enforce this policy using 'lockDropDepth'. The
+// first time a thread exits it will call DropAllLocks - which will do as expected
+// and drop locks allowing another thread to enter. Should another thread, or the
+// same thread again, enter JSC (through evaluate script or call function), and exit
+// again through a callback, then the locks will not be dropped when DropAllLocks
+// is called (since lockDropDepth is non-zero). Since this thread is still holding
+// the locks, only it will re able to re-enter JSC (either be returning from the
+// callback, or by re-entering through another call to evaulate script or call
+// function).
+//
+// This policy is slightly more restricive than it needs to be for correctness -
+// we could validly allow futher entries into JSC from other threads, we only
+// need ensure that callbacks return in the reverse chronological order of the
+// order in which they were made - though implementing the less restrictive policy
+// would likely increase complexity and overhead.
+//
+static unsigned lockDropDepth = 0;
+
JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
: m_lockingForReal(exec->globalData().isSharedInstance)
{
pthread_once(&createJSLockCountOnce, createJSLockCount);
+ if (lockDropDepth++) {
+ m_lockCount = 0;
+ return;
+ }
+
m_lockCount = JSLock::lockCount();
for (intptr_t i = 0; i < m_lockCount; i++)
JSLock::unlock(m_lockingForReal);
@@ -134,6 +181,11 @@ JSLock::DropAllLocks::DropAllLocks(bool lockingForReal)
{
pthread_once(&createJSLockCountOnce, createJSLockCount);
+ if (lockDropDepth++) {
+ m_lockCount = 0;
+ return;
+ }
+
// It is necessary to drop even "unreal" locks, because having a non-zero lock count
// will prevent a real lock from being taken.
@@ -146,6 +198,8 @@ JSLock::DropAllLocks::~DropAllLocks()
{
for (intptr_t i = 0; i < m_lockCount; i++)
JSLock::lock(m_lockingForReal);
+
+ --lockDropDepth;
}
#else
diff --git a/JavaScriptCore/runtime/JSLock.h b/JavaScriptCore/runtime/JSLock.h
index 0c22ff8..3dde358 100644
--- a/JavaScriptCore/runtime/JSLock.h
+++ b/JavaScriptCore/runtime/JSLock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -18,8 +18,8 @@
*
*/
-#ifndef KJS_JSLock_h
-#define KJS_JSLock_h
+#ifndef JSLock_h
+#define JSLock_h
#include <wtf/Assertions.h>
#include <wtf/Noncopyable.h>
@@ -99,4 +99,4 @@ namespace JSC {
} // namespace
-#endif // KJS_JSLock_h
+#endif // JSLock_h
diff --git a/JavaScriptCore/runtime/JSNotAnObject.cpp b/JavaScriptCore/runtime/JSNotAnObject.cpp
index c4ca8fd..67edfd1 100644
--- a/JavaScriptCore/runtime/JSNotAnObject.cpp
+++ b/JavaScriptCore/runtime/JSNotAnObject.cpp
@@ -37,45 +37,39 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSNotAnObject);
// JSValue methods
-JSValue* JSNotAnObject::toPrimitive(ExecState* exec, PreferredPrimitiveType) const
+JSValuePtr JSNotAnObject::toPrimitive(ExecState* exec, PreferredPrimitiveType) const
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return m_exception;
}
-bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValue*&)
+bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValuePtr&)
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return false;
}
bool JSNotAnObject::toBoolean(ExecState* exec) const
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return false;
}
double JSNotAnObject::toNumber(ExecState* exec) const
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return NaN;
}
UString JSNotAnObject::toString(ExecState* exec) const
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return "";
}
JSObject* JSNotAnObject::toObject(ExecState* exec) const
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return m_exception;
}
@@ -90,48 +84,41 @@ void JSNotAnObject::mark()
// JSObject methods
bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, const Identifier&, PropertySlot&)
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return false;
}
bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, unsigned, PropertySlot&)
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return false;
}
-void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue*, PutPropertySlot&)
+void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValuePtr, PutPropertySlot&)
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
}
-void JSNotAnObject::put(ExecState* exec, unsigned, JSValue*)
+void JSNotAnObject::put(ExecState* exec, unsigned, JSValuePtr)
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
}
bool JSNotAnObject::deleteProperty(ExecState* exec, const Identifier&)
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return false;
}
bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned)
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
return false;
}
void JSNotAnObject::getPropertyNames(ExecState* exec, PropertyNameArray&)
{
- UNUSED_PARAM(exec);
- ASSERT(exec->hadException() && exec->exception() == m_exception);
+ ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSNotAnObject.h b/JavaScriptCore/runtime/JSNotAnObject.h
index b6e2931..c69593f 100644
--- a/JavaScriptCore/runtime/JSNotAnObject.h
+++ b/JavaScriptCore/runtime/JSNotAnObject.h
@@ -50,7 +50,7 @@ namespace JSC {
};
// This unholy class is used to allow us to avoid multiple exception checks
- // in certain SquirrelFish opcodes -- effectively it just silently consumes
+ // in certain SquirrelFish bytecodes -- effectively it just silently consumes
// any operations performed on the result of a failed toObject call.
class JSNotAnObject : public JSObject {
public:
@@ -60,15 +60,15 @@ namespace JSC {
{
}
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType));
}
private:
// JSValue methods
- virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
+ virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&);
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
@@ -81,8 +81,8 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
- virtual void put(ExecState*, unsigned propertyName, JSValue*);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+ virtual void put(ExecState*, unsigned propertyName, JSValuePtr);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
diff --git a/JavaScriptCore/runtime/JSNumberCell.cpp b/JavaScriptCore/runtime/JSNumberCell.cpp
index 5b3f3bd..dd965d5 100644
--- a/JavaScriptCore/runtime/JSNumberCell.cpp
+++ b/JavaScriptCore/runtime/JSNumberCell.cpp
@@ -24,16 +24,18 @@
#include "JSNumberCell.h"
#include "NumberObject.h"
-#include "ustring.h"
+#include "UString.h"
namespace JSC {
-JSValue* JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
+#if !USE(ALTERNATE_JSIMMEDIATE)
+
+JSValuePtr JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
{
return const_cast<JSNumberCell*>(this);
}
-bool JSNumberCell::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
+bool JSNumberCell::getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value)
{
number = m_value;
value = this;
@@ -96,29 +98,29 @@ bool JSNumberCell::getTruncatedUInt32(uint32_t& uint32) const
return true;
}
-JSValue* JSNumberCell::getJSNumber()
+JSValuePtr JSNumberCell::getJSNumber()
{
return this;
}
-NEVER_INLINE JSValue* jsNumberCell(ExecState* exec, double d)
+JSValuePtr jsNumberCell(ExecState* exec, double d)
{
return new (exec) JSNumberCell(exec, d);
}
-NEVER_INLINE JSValue* jsNaN(ExecState* exec)
-{
- return new (exec) JSNumberCell(exec, NaN);
-}
-
-NEVER_INLINE JSValue* jsNumberCell(JSGlobalData* globalData, double d)
+JSValuePtr jsNumberCell(JSGlobalData* globalData, double d)
{
return new (globalData) JSNumberCell(globalData, d);
}
-NEVER_INLINE JSValue* jsNaN(JSGlobalData* globalData)
+#else
+
+JSValuePtr jsNumberCell(ExecState*, double)
{
- return new (globalData) JSNumberCell(globalData, NaN);
+ ASSERT_NOT_REACHED();
+ return noValue();
}
+#endif
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSNumberCell.h b/JavaScriptCore/runtime/JSNumberCell.h
index e2f6990..d2377aa 100644
--- a/JavaScriptCore/runtime/JSNumberCell.h
+++ b/JavaScriptCore/runtime/JSNumberCell.h
@@ -23,15 +23,22 @@
#ifndef JSNumberCell_h
#define JSNumberCell_h
-#include "ExecState.h"
+#include "CallFrame.h"
#include "JSCell.h"
#include "JSImmediate.h"
-#include "collector.h"
-#include "ustring.h"
+#include "Collector.h"
+#include "UString.h"
#include <stddef.h> // for size_t
namespace JSC {
+ extern const double NaN;
+ extern const double Inf;
+
+ JSValuePtr jsNumberCell(ExecState*, double);
+
+#if !USE(ALTERNATE_JSIMMEDIATE)
+
class Identifier;
class JSCell;
class JSObject;
@@ -42,16 +49,14 @@ namespace JSC {
struct Instruction;
class JSNumberCell : public JSCell {
- friend class CTI;
- friend JSValue* jsNumberCell(JSGlobalData*, double);
- friend JSValue* jsNaN(JSGlobalData*);
- friend JSValue* jsNumberCell(ExecState*, double);
- friend JSValue* jsNaN(ExecState*);
+ friend class JIT;
+ friend JSValuePtr jsNumberCell(JSGlobalData*, double);
+ friend JSValuePtr jsNumberCell(ExecState*, double);
public:
double value() const { return m_value; }
- virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+ virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
@@ -59,10 +64,7 @@ namespace JSC {
virtual UString toThisString(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
- virtual JSValue* getJSNumber();
-
- int32_t toInt32() const;
- uint32_t toUInt32() const;
+ virtual JSValuePtr getJSNumber();
void* operator new(size_t size, ExecState* exec)
{
@@ -82,22 +84,17 @@ namespace JSC {
#endif
}
- static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
-
- JSNumberCell(JSGlobalData* globalData)
- : JSCell(globalData->numberStructureID.get())
- {
- }
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
private:
JSNumberCell(JSGlobalData* globalData, double value)
- : JSCell(globalData->numberStructureID.get())
+ : JSCell(globalData->numberStructure.get())
, m_value(value)
{
}
JSNumberCell(ExecState* exec, double value)
- : JSCell(exec->globalData().numberStructureID.get())
+ : JSCell(exec->globalData().numberStructure.get())
, m_value(value)
{
}
@@ -109,157 +106,342 @@ namespace JSC {
double m_value;
};
- extern const double NaN;
- extern const double Inf;
-
- JSNumberCell* asNumberCell(JSValue*);
+ JSValuePtr jsNumberCell(JSGlobalData*, double);
- JSValue* jsNumberCell(JSGlobalData*, double);
- JSValue* jsNaN(JSGlobalData*);
- JSValue* jsNumberCell(ExecState*, double);
- JSValue* jsNaN(ExecState*);
-
- inline JSNumberCell* asNumberCell(JSValue* value)
+ inline bool isNumberCell(JSValuePtr v)
{
- ASSERT(asCell(value)->isNumber());
- return static_cast<JSNumberCell*>(asCell(value));
+ return v.isCell() && v.asCell()->isNumber();
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)
+ inline JSNumberCell* asNumberCell(JSValuePtr v)
{
- JSValue* v = JSImmediate::from(d);
- return v ? v : jsNumberCell(exec, d);
+ ASSERT(isNumberCell(v));
+ return static_cast<JSNumberCell*>(v.asCell());
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, short i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, double d)
{
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, i);
- }
-
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned short i)
- {
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(exec, i);
+ JSValuePtr v = JSImmediate::from(d);
+ return v ? v : jsNumberCell(exec, d);
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, int i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, int i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, i);
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, long long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, static_cast<double>(i));
}
- ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned long long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(exec, static_cast<double>(i));
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, double d)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, double d)
{
- JSValue* v = JSImmediate::from(d);
+ JSValuePtr v = JSImmediate::from(d);
return v ? v : jsNumberCell(globalData, d);
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, short i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, int i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned short i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, int i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i)
{
- JSValue* v = JSImmediate::from(i);
+ JSValuePtr v = JSImmediate::from(i);
return v ? v : jsNumberCell(globalData, i);
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long long i)
{
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, i);
+ JSValuePtr v = JSImmediate::from(i);
+ return v ? v : jsNumberCell(globalData, static_cast<double>(i));
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned long i)
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i)
{
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, i);
+ JSValuePtr v = JSImmediate::from(i);
+ return v ? v : jsNumberCell(globalData, static_cast<double>(i));
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, long long i)
+ inline bool JSValuePtr::isDoubleNumber() const
{
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, static_cast<double>(i));
+ return isNumberCell(asValue());
}
- ALWAYS_INLINE JSValue* jsNumber(JSGlobalData* globalData, unsigned long long i)
+ inline double JSValuePtr::getDoubleNumber() const
{
- JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(globalData, static_cast<double>(i));
+ return asNumberCell(asValue())->value();
+ }
+
+ inline bool JSValuePtr::isNumber() const
+ {
+ return JSImmediate::isNumber(asValue()) || isDoubleNumber();
+ }
+
+ inline double JSValuePtr::uncheckedGetNumber() const
+ {
+ ASSERT(isNumber());
+ return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber();
+ }
+
+#else
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, double d)
+ {
+ JSValuePtr v = JSImmediate::from(d);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, int i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long long i)
+ {
+ JSValuePtr v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long long i)
+ {
+ JSValuePtr v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, double d)
+ {
+ JSValuePtr v = JSImmediate::from(d);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, int i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long i)
+ {
+ JSValuePtr v = JSImmediate::from(i);
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long long i)
+ {
+ JSValuePtr v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ return v;
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long long i)
+ {
+ JSValuePtr v = JSImmediate::from(static_cast<double>(i));
+ ASSERT(v);
+ return v;
+ }
+
+ inline bool JSValuePtr::isDoubleNumber() const
+ {
+ return JSImmediate::isDoubleNumber(asValue());
+ }
+
+ inline double JSValuePtr::getDoubleNumber() const
+ {
+ return JSImmediate::doubleValue(asValue());
+ }
+
+ inline bool JSValuePtr::isNumber() const
+ {
+ return JSImmediate::isNumber(asValue());
+ }
+
+ inline double JSValuePtr::uncheckedGetNumber() const
+ {
+ ASSERT(isNumber());
+ return JSImmediate::toDouble(asValue());
+ }
+
+#endif
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, char i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned char i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned short i)
+ {
+ ASSERT(JSImmediate::from(i));
+ return JSImmediate::from(i);
+ }
+
+ inline JSValuePtr jsNaN(ExecState* exec)
+ {
+ return jsNumber(exec, NaN);
+ }
+
+ inline JSValuePtr jsNaN(JSGlobalData* globalData)
+ {
+ return jsNumber(globalData, NaN);
}
// --- JSValue inlines ----------------------------
- inline double JSValue::uncheckedGetNumber() const
+ ALWAYS_INLINE JSValuePtr JSValuePtr::toJSNumber(ExecState* exec) const
{
- ASSERT(JSImmediate::isImmediate(asValue()) || asCell()->isNumber());
- return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell(asValue())->value();
+ return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
}
- inline int32_t JSNumberCell::toInt32() const
+ inline bool JSValuePtr::getNumber(double &result) const
{
- if (m_value >= -2147483648.0 && m_value < 2147483648.0)
- return static_cast<int32_t>(m_value);
- bool scratch;
- return JSC::toInt32SlowCase(m_value, scratch);
+ if (isInt32Fast())
+ result = getInt32Fast();
+ else if (LIKELY(isDoubleNumber()))
+ result = getDoubleNumber();
+ else {
+ ASSERT(!isNumber());
+ return false;
+ }
+ return true;
}
- inline uint32_t JSNumberCell::toUInt32() const
+ inline bool JSValuePtr::numberToInt32(int32_t& arg)
{
- if (m_value >= 0.0 && m_value < 4294967296.0)
- return static_cast<uint32_t>(m_value);
- bool scratch;
- return JSC::toUInt32SlowCase(m_value, scratch);
+ if (isInt32Fast())
+ arg = getInt32Fast();
+ else if (LIKELY(isDoubleNumber()))
+ arg = JSC::toInt32(getDoubleNumber());
+ else {
+ ASSERT(!isNumber());
+ return false;
+ }
+ return true;
}
- ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const
+ inline bool JSValuePtr::numberToUInt32(uint32_t& arg)
{
- return JSImmediate::isNumber(asValue()) ? asValue() : jsNumber(exec, this->toNumber(exec));
+ if (isUInt32Fast())
+ arg = getUInt32Fast();
+ else if (LIKELY(isDoubleNumber()))
+ arg = JSC::toUInt32(getDoubleNumber());
+ else if (isInt32Fast()) {
+ // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase
+ // on a negative value is equivalent to simple static_casting.
+ bool ignored;
+ arg = toUInt32SlowCase(getInt32Fast(), ignored);
+ } else {
+ ASSERT(!isNumber());
+ return false;
+ }
+ return true;
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSObject.cpp b/JavaScriptCore/runtime/JSObject.cpp
index 82c1c63..e9e95f6 100644
--- a/JavaScriptCore/runtime/JSObject.cpp
+++ b/JavaScriptCore/runtime/JSObject.cpp
@@ -31,9 +31,9 @@
#include "NativeErrorConstructor.h"
#include "ObjectPrototype.h"
#include "PropertyNameArray.h"
-#include "lookup.h"
-#include "nodes.h"
-#include "operations.h"
+#include "Lookup.h"
+#include "Nodes.h"
+#include "Operations.h"
#include <math.h>
#include <wtf/Assertions.h>
@@ -67,13 +67,13 @@ void JSObject::mark()
JSOBJECT_MARK_BEGIN();
JSCell::mark();
- m_structureID->mark();
+ m_structure->mark();
- size_t storageSize = m_structureID->propertyStorageSize();
+ size_t storageSize = m_structure->propertyStorageSize();
for (size_t i = 0; i < storageSize; ++i) {
- JSValue* v = m_propertyStorage[i];
- if (!v->marked())
- v->mark();
+ JSValuePtr v = m_propertyStorage[i];
+ if (!v.marked())
+ v.mark();
}
JSOBJECT_MARK_END();
@@ -98,47 +98,47 @@ static void throwSetterError(ExecState* exec)
}
// ECMA 8.6.2.2
-void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
if (propertyName == exec->propertyNames().underscoreProto) {
- JSObject* proto = value->getObject();
-
// Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
- if (!proto && !value->isNull())
+ if (!value.isObject() && !value.isNull())
return;
-
- while (proto) {
- if (proto == this) {
+
+ JSValuePtr nextPrototypeValue = value;
+ while (nextPrototypeValue && nextPrototypeValue.isObject()) {
+ JSObject* nextPrototype = asObject(nextPrototypeValue)->unwrappedObject();
+ if (nextPrototype == this) {
throwError(exec, GeneralError, "cyclic __proto__ value");
return;
}
- proto = proto->prototype() ? proto->prototype()->getObject() : 0;
+ nextPrototypeValue = nextPrototype->prototype();
}
-
+
setPrototype(value);
return;
}
-
+
// Check if there are any setters or getters in the prototype chain
- JSValue* prototype;
- for (JSObject* obj = this; !obj->structureID()->hasGetterSetterProperties(); obj = asObject(prototype)) {
+ JSValuePtr prototype;
+ for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) {
prototype = obj->prototype();
- if (prototype->isNull()) {
+ if (prototype.isNull()) {
putDirect(propertyName, value, 0, true, slot);
return;
}
}
unsigned attributes;
- if ((m_structureID->get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
+ if ((m_structure->get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
return;
for (JSObject* obj = this; ; obj = asObject(prototype)) {
- if (JSValue* gs = obj->getDirect(propertyName)) {
- if (gs->isGetterSetter()) {
+ if (JSValuePtr gs = obj->getDirect(propertyName)) {
+ if (gs.isGetterSetter()) {
JSObject* setterFunc = asGetterSetter(gs)->setter();
if (!setterFunc) {
throwSetterError(exec);
@@ -159,7 +159,7 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* val
}
prototype = obj->prototype();
- if (prototype->isNull())
+ if (prototype.isNull())
break;
}
@@ -167,18 +167,18 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* val
return;
}
-void JSObject::put(ExecState* exec, unsigned propertyName, JSValue* value)
+void JSObject::put(ExecState* exec, unsigned propertyName, JSValuePtr value)
{
PutPropertySlot slot;
put(exec, Identifier::from(exec, propertyName), value, slot);
}
-void JSObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
+void JSObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
{
putDirect(propertyName, value, attributes);
}
-void JSObject::putWithAttributes(ExecState* exec, unsigned propertyName, JSValue* value, unsigned attributes)
+void JSObject::putWithAttributes(ExecState* exec, unsigned propertyName, JSValuePtr value, unsigned attributes)
{
putWithAttributes(exec, Identifier::from(exec, propertyName), value, attributes);
}
@@ -199,7 +199,7 @@ bool JSObject::hasProperty(ExecState* exec, unsigned propertyName) const
bool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
unsigned attributes;
- if (m_structureID->get(propertyName, attributes) != WTF::notFound) {
+ if (m_structure->get(propertyName, attributes) != WTF::notFound) {
if ((attributes & DontDelete))
return false;
removeDirect(propertyName);
@@ -226,11 +226,11 @@ bool JSObject::deleteProperty(ExecState* exec, unsigned propertyName)
return deleteProperty(exec, Identifier::from(exec, propertyName));
}
-static ALWAYS_INLINE JSValue* callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
+static ALWAYS_INLINE JSValuePtr callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
{
- JSValue* function = object->get(exec, propertyName);
+ JSValuePtr function = object->get(exec, propertyName);
CallData callData;
- CallType callType = function->getCallData(callData);
+ CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return exec->exception();
@@ -239,35 +239,39 @@ static ALWAYS_INLINE JSValue* callDefaultValueFunction(ExecState* exec, const JS
if (exec->hadException())
return exec->exception();
- JSValue* result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList());
- ASSERT(!result->isGetterSetter());
+ JSValuePtr result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList());
+ ASSERT(!result.isGetterSetter());
if (exec->hadException())
return exec->exception();
- if (result->isObject())
+ if (result.isObject())
return noValue();
return result;
}
-bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& result)
+bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValuePtr& result)
{
result = defaultValue(exec, PreferNumber);
- number = result->toNumber(exec);
- return !result->isString();
+ number = result.toNumber(exec);
+ return !result.isString();
}
// ECMA 8.6.2.6
-JSValue* JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
+JSValuePtr JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
{
// Must call toString first for Date objects.
if ((hint == PreferString) || (hint != PreferNumber && prototype() == exec->lexicalGlobalObject()->datePrototype())) {
- if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString))
+ JSValuePtr value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
+ if (value)
return value;
- if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf))
+ value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
+ if (value)
return value;
} else {
- if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf))
+ JSValuePtr value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
+ if (value)
return value;
- if (JSValue* value = callDefaultValueFunction(exec, this, exec->propertyNames().toString))
+ value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
+ if (value)
return value;
}
@@ -289,9 +293,9 @@ const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifi
void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)
{
- JSValue* object = getDirect(propertyName);
- if (object && object->isGetterSetter()) {
- ASSERT(m_structureID->hasGetterSetterProperties());
+ JSValuePtr object = getDirect(propertyName);
+ if (object && object.isGetterSetter()) {
+ ASSERT(m_structure->hasGetterSetterProperties());
asGetterSetter(object)->setGetter(getterFunction);
return;
}
@@ -300,25 +304,25 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO
GetterSetter* getterSetter = new (exec) GetterSetter;
putDirect(propertyName, getterSetter, None, true, slot);
- // putDirect will change our StructureID if we add a new property. For
- // getters and setters, though, we also need to change our StructureID
+ // putDirect will change our Structure if we add a new property. For
+ // getters and setters, though, we also need to change our Structure
// if we override an existing non-getter or non-setter.
if (slot.type() != PutPropertySlot::NewProperty) {
- if (!m_structureID->isDictionary()) {
- RefPtr<StructureID> structureID = StructureID::getterSetterTransition(m_structureID);
- setStructureID(structureID.release());
+ if (!m_structure->isDictionary()) {
+ RefPtr<Structure> structure = Structure::getterSetterTransition(m_structure);
+ setStructure(structure.release());
}
}
- m_structureID->setHasGetterSetterProperties(true);
+ m_structure->setHasGetterSetterProperties(true);
getterSetter->setGetter(getterFunction);
}
void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction)
{
- JSValue* object = getDirect(propertyName);
- if (object && object->isGetterSetter()) {
- ASSERT(m_structureID->hasGetterSetterProperties());
+ JSValuePtr object = getDirect(propertyName);
+ if (object && object.isGetterSetter()) {
+ ASSERT(m_structure->hasGetterSetterProperties());
asGetterSetter(object)->setSetter(setterFunction);
return;
}
@@ -327,27 +331,26 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO
GetterSetter* getterSetter = new (exec) GetterSetter;
putDirect(propertyName, getterSetter, None, true, slot);
- // putDirect will change our StructureID if we add a new property. For
- // getters and setters, though, we also need to change our StructureID
+ // putDirect will change our Structure if we add a new property. For
+ // getters and setters, though, we also need to change our Structure
// if we override an existing non-getter or non-setter.
if (slot.type() != PutPropertySlot::NewProperty) {
- if (!m_structureID->isDictionary()) {
- RefPtr<StructureID> structureID = StructureID::getterSetterTransition(m_structureID);
- setStructureID(structureID.release());
+ if (!m_structure->isDictionary()) {
+ RefPtr<Structure> structure = Structure::getterSetterTransition(m_structure);
+ setStructure(structure.release());
}
}
- m_structureID->setHasGetterSetterProperties(true);
+ m_structure->setHasGetterSetterProperties(true);
getterSetter->setSetter(setterFunction);
}
-JSValue* JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
+JSValuePtr JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
{
JSObject* object = this;
while (true) {
- JSValue* value = object->getDirect(propertyName);
- if (value) {
- if (!value->isGetterSetter())
+ if (JSValuePtr value = object->getDirect(propertyName)) {
+ if (!value.isGetterSetter())
return jsUndefined();
JSObject* functionObject = asGetterSetter(value)->getter();
if (!functionObject)
@@ -355,19 +358,18 @@ JSValue* JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
return functionObject;
}
- if (!object->prototype() || !object->prototype()->isObject())
+ if (!object->prototype() || !object->prototype().isObject())
return jsUndefined();
object = asObject(object->prototype());
}
}
-JSValue* JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
+JSValuePtr JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
{
JSObject* object = this;
while (true) {
- JSValue* value = object->getDirect(propertyName);
- if (value) {
- if (!value->isGetterSetter())
+ if (JSValuePtr value = object->getDirect(propertyName)) {
+ if (!value.isGetterSetter())
return jsUndefined();
JSObject* functionObject = asGetterSetter(value)->setter();
if (!functionObject)
@@ -375,25 +377,25 @@ JSValue* JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
return functionObject;
}
- if (!object->prototype() || !object->prototype()->isObject())
+ if (!object->prototype() || !object->prototype().isObject())
return jsUndefined();
object = asObject(object->prototype());
}
}
-bool JSObject::hasInstance(ExecState* exec, JSValue* value, JSValue* proto)
+bool JSObject::hasInstance(ExecState* exec, JSValuePtr value, JSValuePtr proto)
{
- if (!proto->isObject()) {
+ if (!proto.isObject()) {
throwError(exec, TypeError, "instanceof called on an object with an invalid prototype property.");
return false;
}
- if (!value->isObject())
+ if (!value.isObject())
return false;
JSObject* object = asObject(value);
- while ((object = object->prototype()->getObject())) {
- if (object == proto)
+ while ((object = object->prototype().getObject())) {
+ if (proto == object)
return true;
}
return false;
@@ -409,7 +411,7 @@ bool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyN
bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
{
- if (m_structureID->get(propertyName, attributes) != WTF::notFound)
+ if (m_structure->get(propertyName, attributes) != WTF::notFound)
return true;
// Look in the static hashtable of properties
@@ -424,7 +426,7 @@ bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& property
void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
{
- m_structureID->getEnumerablePropertyNames(exec, propertyNames, this);
+ m_structure->getEnumerablePropertyNames(exec, propertyNames, this);
}
bool JSObject::toBoolean(ExecState*) const
@@ -434,18 +436,18 @@ bool JSObject::toBoolean(ExecState*) const
double JSObject::toNumber(ExecState* exec) const
{
- JSValue* primitive = toPrimitive(exec, PreferNumber);
- if (exec->hadException()) // should be picked up soon in nodes.cpp
+ JSValuePtr primitive = toPrimitive(exec, PreferNumber);
+ if (exec->hadException()) // should be picked up soon in Nodes.cpp
return 0.0;
- return primitive->toNumber(exec);
+ return primitive.toNumber(exec);
}
UString JSObject::toString(ExecState* exec) const
{
- JSValue* primitive = toPrimitive(exec, PreferString);
+ JSValuePtr primitive = toPrimitive(exec, PreferString);
if (exec->hadException())
return "";
- return primitive->toString(exec);
+ return primitive.toString(exec);
}
JSObject* JSObject::toObject(ExecState*) const
@@ -458,25 +460,25 @@ JSObject* JSObject::toThisObject(ExecState*) const
return const_cast<JSObject*>(this);
}
-JSGlobalObject* JSObject::toGlobalObject(ExecState*) const
+JSObject* JSObject::unwrappedObject()
{
- return 0;
+ return this;
}
void JSObject::removeDirect(const Identifier& propertyName)
{
size_t offset;
- if (m_structureID->isDictionary()) {
- offset = m_structureID->removePropertyWithoutTransition(propertyName);
+ if (m_structure->isDictionary()) {
+ offset = m_structure->removePropertyWithoutTransition(propertyName);
if (offset != WTF::notFound)
m_propertyStorage[offset] = jsUndefined();
return;
}
- RefPtr<StructureID> structureID = StructureID::removePropertyTransition(m_structureID, propertyName, offset);
+ RefPtr<Structure> structure = Structure::removePropertyTransition(m_structure, propertyName, offset);
if (offset != WTF::notFound)
m_propertyStorage[offset] = jsUndefined();
- setStructureID(structureID.release());
+ setStructure(structure.release());
}
void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr)
@@ -489,7 +491,7 @@ void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunct
putDirectWithoutTransition(Identifier(exec, function->name(&exec->globalData())), function, attr);
}
-NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue** location)
+NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValuePtr* location)
{
if (JSObject* getterFunction = asGetterSetter(*location)->getter())
slot.setGetterSlot(getterFunction);
@@ -497,9 +499,9 @@ NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue**
slot.setUndefined();
}
-StructureID* JSObject::createInheritorID()
+Structure* JSObject::createInheritorID()
{
- m_inheritorID = JSObject::createStructureID(this);
+ m_inheritorID = JSObject::createStructure(this);
return m_inheritorID.get();
}
diff --git a/JavaScriptCore/runtime/JSObject.h b/JavaScriptCore/runtime/JSObject.h
index d280b64..20242ce 100644
--- a/JavaScriptCore/runtime/JSObject.h
+++ b/JavaScriptCore/runtime/JSObject.h
@@ -26,18 +26,18 @@
#include "ArgList.h"
#include "ClassInfo.h"
#include "CommonIdentifiers.h"
-#include "ExecState.h"
+#include "CallFrame.h"
#include "JSNumberCell.h"
#include "PropertySlot.h"
#include "PutPropertySlot.h"
#include "ScopeChain.h"
-#include "StructureID.h"
+#include "Structure.h"
namespace JSC {
class InternalFunction;
class PropertyNameArray;
- class StructureID;
+ class Structure;
struct HashEntry;
struct HashTable;
@@ -51,15 +51,15 @@ namespace JSC {
Function = 1 << 4, // property is a function - only used by static hashtables
};
- typedef JSValue** PropertyStorage;
+ typedef JSValuePtr* PropertyStorage;
class JSObject : public JSCell {
friend class BatchedTransitionOptimizer;
- friend class CTI;
+ friend class JIT;
friend class JSCell;
public:
- explicit JSObject(PassRefPtr<StructureID>);
+ explicit JSObject(PassRefPtr<Structure>);
virtual void mark();
@@ -69,18 +69,18 @@ namespace JSC {
bool inherits(const ClassInfo* classInfo) const { return JSCell::isObject(classInfo); }
- JSValue* prototype() const;
- void setPrototype(JSValue* prototype);
+ JSValuePtr prototype() const;
+ void setPrototype(JSValuePtr prototype);
- void setStructureID(PassRefPtr<StructureID>);
- StructureID* inheritorID();
+ void setStructure(PassRefPtr<Structure>);
+ Structure* inheritorID();
PropertyStorage& propertyStorage() { return m_propertyStorage; }
virtual UString className() const;
- JSValue* get(ExecState*, const Identifier& propertyName) const;
- JSValue* get(ExecState*, unsigned propertyName) const;
+ JSValuePtr get(ExecState*, const Identifier& propertyName) const;
+ JSValuePtr get(ExecState*, unsigned propertyName) const;
bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
@@ -88,11 +88,11 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot&);
- virtual void put(ExecState*, unsigned propertyName, JSValue* value);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr value, PutPropertySlot&);
+ virtual void put(ExecState*, unsigned propertyName, JSValuePtr value);
- virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes);
- virtual void putWithAttributes(ExecState*, unsigned propertyName, JSValue* value, unsigned attributes);
+ virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes);
+ virtual void putWithAttributes(ExecState*, unsigned propertyName, JSValuePtr value, unsigned attributes);
bool propertyIsEnumerable(ExecState*, const Identifier& propertyName) const;
@@ -103,78 +103,79 @@ namespace JSC {
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
- virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const;
+ virtual JSValuePtr defaultValue(ExecState*, PreferredPrimitiveType) const;
- virtual bool hasInstance(ExecState*, JSValue*, JSValue* prototypeProperty);
+ virtual bool hasInstance(ExecState*, JSValuePtr, JSValuePtr prototypeProperty);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
- virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+ virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
virtual JSObject* toObject(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
- virtual JSGlobalObject* toGlobalObject(ExecState*) const;
+ virtual JSObject* unwrappedObject();
virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
// This get function only looks at the property map.
- JSValue* getDirect(const Identifier& propertyName) const
+ JSValuePtr getDirect(const Identifier& propertyName) const
{
- size_t offset = m_structureID->get(propertyName);
+ size_t offset = m_structure->get(propertyName);
return offset != WTF::notFound ? m_propertyStorage[offset] : noValue();
}
- JSValue** getDirectLocation(const Identifier& propertyName)
+ JSValuePtr* getDirectLocation(const Identifier& propertyName)
{
- size_t offset = m_structureID->get(propertyName);
+ size_t offset = m_structure->get(propertyName);
return offset != WTF::notFound ? locationForOffset(offset) : 0;
}
- JSValue** getDirectLocation(const Identifier& propertyName, unsigned& attributes)
+ JSValuePtr* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
{
- size_t offset = m_structureID->get(propertyName, attributes);
+ size_t offset = m_structure->get(propertyName, attributes);
return offset != WTF::notFound ? locationForOffset(offset) : 0;
}
- size_t offsetForLocation(JSValue** location)
+ size_t offsetForLocation(JSValuePtr* location)
{
return location - m_propertyStorage;
}
- JSValue** locationForOffset(size_t offset)
+ JSValuePtr* locationForOffset(size_t offset)
{
return &m_propertyStorage[offset];
}
- void transitionTo(StructureID*);
+ void transitionTo(Structure*);
void removeDirect(const Identifier& propertyName);
- bool hasCustomProperties() { return !m_structureID->isEmpty(); }
- bool hasGetterSetterProperties() { return m_structureID->hasGetterSetterProperties(); }
+ bool hasCustomProperties() { return !m_structure->isEmpty(); }
+ bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); }
- void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr = 0);
- void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+ void putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr = 0);
+ void putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0);
- void putDirectWithoutTransition(const Identifier& propertyName, JSValue* value, unsigned attr = 0);
+ void putDirectWithoutTransition(const Identifier& propertyName, JSValuePtr value, unsigned attr = 0);
void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr = 0);
// Fast access to known property offsets.
- JSValue* getDirectOffset(size_t offset) { return m_propertyStorage[offset]; }
- void putDirectOffset(size_t offset, JSValue* value) { m_propertyStorage[offset] = value; }
+ JSValuePtr getDirectOffset(size_t offset) { return m_propertyStorage[offset]; }
+ void putDirectOffset(size_t offset, JSValuePtr value) { m_propertyStorage[offset] = value; }
- void fillGetterPropertySlot(PropertySlot&, JSValue** location);
+ void fillGetterPropertySlot(PropertySlot&, JSValuePtr* location);
virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction);
virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction);
- virtual JSValue* lookupGetter(ExecState*, const Identifier& propertyName);
- virtual JSValue* lookupSetter(ExecState*, const Identifier& propertyName);
+ virtual JSValuePtr lookupGetter(ExecState*, const Identifier& propertyName);
+ virtual JSValuePtr lookupSetter(ExecState*, const Identifier& propertyName);
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; }
@@ -185,9 +186,9 @@ namespace JSC {
static const size_t inlineStorageCapacity = 2;
static const size_t nonInlineBaseStorageCapacity = 16;
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
+ return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
}
protected:
@@ -197,61 +198,61 @@ namespace JSC {
bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
- StructureID* createInheritorID();
+ Structure* createInheritorID();
- RefPtr<StructureID> m_inheritorID;
+ RefPtr<Structure> m_inheritorID;
PropertyStorage m_propertyStorage;
- JSValue* m_inlineStorage[inlineStorageCapacity];
+ JSValuePtr m_inlineStorage[inlineStorageCapacity];
};
- JSObject* asObject(JSValue*);
+ JSObject* asObject(JSValuePtr);
JSObject* constructEmptyObject(ExecState*);
-inline JSObject* asObject(JSValue* value)
+inline JSObject* asObject(JSValuePtr value)
{
ASSERT(asCell(value)->isObject());
return static_cast<JSObject*>(asCell(value));
}
-inline JSObject::JSObject(PassRefPtr<StructureID> structureID)
- : JSCell(structureID.releaseRef()) // ~JSObject balances this ref()
+inline JSObject::JSObject(PassRefPtr<Structure> structure)
+ : JSCell(structure.releaseRef()) // ~JSObject balances this ref()
, m_propertyStorage(m_inlineStorage)
{
- ASSERT(m_structureID);
- ASSERT(m_structureID->propertyStorageCapacity() == inlineStorageCapacity);
- ASSERT(m_structureID->isEmpty());
- ASSERT(prototype()->isNull() || Heap::heap(this) == Heap::heap(prototype()));
+ ASSERT(m_structure);
+ ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity);
+ ASSERT(m_structure->isEmpty());
+ ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
}
inline JSObject::~JSObject()
{
- ASSERT(m_structureID);
+ ASSERT(m_structure);
if (m_propertyStorage != m_inlineStorage)
delete [] m_propertyStorage;
- m_structureID->deref();
+ m_structure->deref();
}
-inline JSValue* JSObject::prototype() const
+inline JSValuePtr JSObject::prototype() const
{
- return m_structureID->storedPrototype();
+ return m_structure->storedPrototype();
}
-inline void JSObject::setPrototype(JSValue* prototype)
+inline void JSObject::setPrototype(JSValuePtr prototype)
{
ASSERT(prototype);
- RefPtr<StructureID> newStructureID = StructureID::changePrototypeTransition(m_structureID, prototype);
- setStructureID(newStructureID.release());
+ RefPtr<Structure> newStructure = Structure::changePrototypeTransition(m_structure, prototype);
+ setStructure(newStructure.release());
}
-inline void JSObject::setStructureID(PassRefPtr<StructureID> structureID)
+inline void JSObject::setStructure(PassRefPtr<Structure> structure)
{
- m_structureID->deref();
- m_structureID = structureID.releaseRef(); // ~JSObject balances this ref()
+ m_structure->deref();
+ m_structure = structure.releaseRef(); // ~JSObject balances this ref()
}
-inline StructureID* JSObject::inheritorID()
+inline Structure* JSObject::inheritorID()
{
if (m_inheritorID)
return m_inheritorID.get();
@@ -268,15 +269,15 @@ inline bool JSCell::isObject(const ClassInfo* info) const
}
// this method is here to be after the inline declaration of JSCell::isObject
-inline bool JSValue::isObject(const ClassInfo* classInfo) const
+inline bool JSValuePtr::isObject(const ClassInfo* classInfo) const
{
- return !JSImmediate::isImmediate(asValue()) && asCell()->isObject(classInfo);
+ return isCell() && asCell()->isObject(classInfo);
}
ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
- if (JSValue** location = getDirectLocation(propertyName)) {
- if (m_structureID->hasGetterSetterProperties() && location[0]->isGetterSetter())
+ if (JSValuePtr* location = getDirectLocation(propertyName)) {
+ if (m_structure->hasGetterSetterProperties() && location[0].isGetterSetter())
fillGetterPropertySlot(slot, location);
else
slot.setValueSlot(this, location, offsetForLocation(location));
@@ -295,8 +296,8 @@ ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Ide
ALWAYS_INLINE bool JSObject::getOwnPropertySlotForWrite(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
{
unsigned attributes;
- if (JSValue** location = getDirectLocation(propertyName, attributes)) {
- if (m_structureID->hasGetterSetterProperties() && location[0]->isGetterSetter()) {
+ if (JSValuePtr* location = getDirectLocation(propertyName, attributes)) {
+ if (m_structure->hasGetterSetterProperties() && location[0].isGetterSetter()) {
slotIsWriteable = false;
fillGetterPropertySlot(slot, location);
} else {
@@ -326,7 +327,7 @@ ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifie
ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
- if (structureID()->typeInfo().hasStandardGetOwnPropertySlot())
+ if (structure()->typeInfo().hasStandardGetOwnPropertySlot())
return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot);
return getOwnPropertySlot(exec, propertyName, slot);
}
@@ -339,8 +340,8 @@ inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propert
while (true) {
if (object->fastGetOwnPropertySlot(exec, propertyName, slot))
return true;
- JSValue* prototype = object->prototype();
- if (!prototype->isObject())
+ JSValuePtr prototype = object->prototype();
+ if (!prototype.isObject())
return false;
object = asObject(prototype);
}
@@ -352,14 +353,14 @@ inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, Pr
while (true) {
if (object->getOwnPropertySlot(exec, propertyName, slot))
return true;
- JSValue* prototype = object->prototype();
- if (!prototype->isObject())
+ JSValuePtr prototype = object->prototype();
+ if (!prototype.isObject())
return false;
object = asObject(prototype);
}
}
-inline JSValue* JSObject::get(ExecState* exec, const Identifier& propertyName) const
+inline JSValuePtr JSObject::get(ExecState* exec, const Identifier& propertyName) const
{
PropertySlot slot(this);
if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
@@ -368,7 +369,7 @@ inline JSValue* JSObject::get(ExecState* exec, const Identifier& propertyName) c
return jsUndefined();
}
-inline JSValue* JSObject::get(ExecState* exec, unsigned propertyName) const
+inline JSValuePtr JSObject::get(ExecState* exec, unsigned propertyName) const
{
PropertySlot slot(this);
if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
@@ -377,19 +378,19 @@ inline JSValue* JSObject::get(ExecState* exec, unsigned propertyName) const
return jsUndefined();
}
-inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value, unsigned attr)
+inline void JSObject::putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr)
{
PutPropertySlot slot;
putDirect(propertyName, value, attr, false, slot);
}
-inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+inline void JSObject::putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
- if (m_structureID->isDictionary()) {
+ if (m_structure->isDictionary()) {
unsigned currentAttributes;
- size_t offset = m_structureID->get(propertyName, currentAttributes);
+ size_t offset = m_structure->get(propertyName, currentAttributes);
if (offset != WTF::notFound) {
if (checkReadOnly && currentAttributes & ReadOnly)
return;
@@ -398,19 +399,33 @@ inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value,
return;
}
- size_t currentCapacity = m_structureID->propertyStorageCapacity();
- offset = m_structureID->addPropertyWithoutTransition(propertyName, attributes);
- if (currentCapacity != m_structureID->propertyStorageCapacity())
- allocatePropertyStorage(currentCapacity, m_structureID->propertyStorageCapacity());
+ size_t currentCapacity = m_structure->propertyStorageCapacity();
+ offset = m_structure->addPropertyWithoutTransition(propertyName, attributes);
+ if (currentCapacity != m_structure->propertyStorageCapacity())
+ allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
- ASSERT(offset < m_structureID->propertyStorageCapacity());
+ ASSERT(offset < m_structure->propertyStorageCapacity());
m_propertyStorage[offset] = value;
slot.setNewProperty(this, offset);
return;
}
+ size_t offset;
+ size_t currentCapacity = m_structure->propertyStorageCapacity();
+ if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, offset)) {
+ if (currentCapacity != structure->propertyStorageCapacity())
+ allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
+
+ ASSERT(offset < structure->propertyStorageCapacity());
+ m_propertyStorage[offset] = value;
+ slot.setNewProperty(this, offset);
+ slot.setWasTransition(true);
+ setStructure(structure.release());
+ return;
+ }
+
unsigned currentAttributes;
- size_t offset = m_structureID->get(propertyName, currentAttributes);
+ offset = m_structure->get(propertyName, currentAttributes);
if (offset != WTF::notFound) {
if (checkReadOnly && currentAttributes & ReadOnly)
return;
@@ -419,48 +434,47 @@ inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value,
return;
}
- size_t currentCapacity = m_structureID->propertyStorageCapacity();
- RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, attributes, offset);
- if (currentCapacity != structureID->propertyStorageCapacity())
- allocatePropertyStorage(currentCapacity, structureID->propertyStorageCapacity());
+ RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, offset);
+ if (currentCapacity != structure->propertyStorageCapacity())
+ allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
- ASSERT(offset < structureID->propertyStorageCapacity());
+ ASSERT(offset < structure->propertyStorageCapacity());
m_propertyStorage[offset] = value;
slot.setNewProperty(this, offset);
slot.setWasTransition(true);
- setStructureID(structureID.release());
+ setStructure(structure.release());
}
-inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValue* value, unsigned attributes)
+inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValuePtr value, unsigned attributes)
{
- size_t currentCapacity = m_structureID->propertyStorageCapacity();
- size_t offset = m_structureID->addPropertyWithoutTransition(propertyName, attributes);
- if (currentCapacity != m_structureID->propertyStorageCapacity())
- allocatePropertyStorage(currentCapacity, m_structureID->propertyStorageCapacity());
+ size_t currentCapacity = m_structure->propertyStorageCapacity();
+ size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes);
+ if (currentCapacity != m_structure->propertyStorageCapacity())
+ allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
m_propertyStorage[offset] = value;
}
-inline void JSObject::transitionTo(StructureID* newStructureID)
+inline void JSObject::transitionTo(Structure* newStructure)
{
- if (m_structureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity())
- allocatePropertyStorage(m_structureID->propertyStorageCapacity(), newStructureID->propertyStorageCapacity());
- setStructureID(newStructureID);
+ if (m_structure->propertyStorageCapacity() != newStructure->propertyStorageCapacity())
+ allocatePropertyStorage(m_structure->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
+ setStructure(newStructure);
}
-inline JSValue* JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
+inline JSValuePtr JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
{
return defaultValue(exec, preferredType);
}
-inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName) const
+inline JSValuePtr JSValuePtr::get(ExecState* exec, const Identifier& propertyName) const
{
- PropertySlot slot(this);
+ PropertySlot slot(asValue());
return get(exec, propertyName, slot);
}
-inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
+inline JSValuePtr JSValuePtr::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
{
- if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+ if (UNLIKELY(!isCell())) {
JSObject* prototype = JSImmediate::prototype(asValue(), exec);
if (!prototype->getPropertySlot(exec, propertyName, slot))
return jsUndefined();
@@ -471,22 +485,22 @@ inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName, Pr
if (cell->fastGetOwnPropertySlot(exec, propertyName, slot))
return slot.getValue(exec, propertyName);
ASSERT(cell->isObject());
- JSValue* prototype = static_cast<JSObject*>(cell)->prototype();
- if (!prototype->isObject())
+ JSValuePtr prototype = static_cast<JSObject*>(cell)->prototype();
+ if (!prototype.isObject())
return jsUndefined();
cell = asObject(prototype);
}
}
-inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName) const
+inline JSValuePtr JSValuePtr::get(ExecState* exec, unsigned propertyName) const
{
- PropertySlot slot(this);
+ PropertySlot slot(asValue());
return get(exec, propertyName, slot);
}
-inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
+inline JSValuePtr JSValuePtr::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
{
- if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+ if (UNLIKELY(!isCell())) {
JSObject* prototype = JSImmediate::prototype(asValue(), exec);
if (!prototype->getPropertySlot(exec, propertyName, slot))
return jsUndefined();
@@ -497,25 +511,25 @@ inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName, PropertySlo
if (cell->getOwnPropertySlot(exec, propertyName, slot))
return slot.getValue(exec, propertyName);
ASSERT(cell->isObject());
- JSValue* prototype = static_cast<JSObject*>(cell)->prototype();
- if (!prototype->isObject())
+ JSValuePtr prototype = static_cast<JSObject*>(cell)->prototype();
+ if (!prototype.isObject())
return jsUndefined();
- cell = prototype->asCell();
+ cell = prototype.asCell();
}
}
-inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+inline void JSValuePtr::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
- if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+ if (UNLIKELY(!isCell())) {
JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value, slot);
return;
}
asCell()->put(exec, propertyName, value, slot);
}
-inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue* value)
+inline void JSValuePtr::put(ExecState* exec, unsigned propertyName, JSValuePtr value)
{
- if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
+ if (UNLIKELY(!isCell())) {
JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value);
return;
}
@@ -526,8 +540,8 @@ ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_
{
ASSERT(newSize > oldSize);
- JSValue** oldPropertyStorage = m_propertyStorage;
- m_propertyStorage = new JSValue*[newSize];
+ JSValuePtr* oldPropertyStorage = m_propertyStorage;
+ m_propertyStorage = new JSValuePtr[newSize];
for (unsigned i = 0; i < oldSize; ++i)
m_propertyStorage[i] = oldPropertyStorage[i];
diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index 55f4ced..ec8efea 100644
--- a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -37,13 +37,13 @@ JSPropertyNameIterator::~JSPropertyNameIterator()
{
}
-JSValue* JSPropertyNameIterator::toPrimitive(ExecState*, PreferredPrimitiveType) const
+JSValuePtr JSPropertyNameIterator::toPrimitive(ExecState*, PreferredPrimitiveType) const
{
ASSERT_NOT_REACHED();
return noValue();
}
-bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValue*&)
+bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValuePtr&)
{
ASSERT_NOT_REACHED();
return false;
diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.h b/JavaScriptCore/runtime/JSPropertyNameIterator.h
index 1853999..a6d6cd2 100644
--- a/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -40,12 +40,12 @@ namespace JSC {
class JSPropertyNameIterator : public JSCell {
public:
- static JSPropertyNameIterator* create(ExecState*, JSValue*);
+ static JSPropertyNameIterator* create(ExecState*, JSValuePtr);
virtual ~JSPropertyNameIterator();
- virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double&, JSValue*&);
+ virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
+ virtual bool getPrimitiveNumber(ExecState*, double&, JSValuePtr&);
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
@@ -53,7 +53,7 @@ namespace JSC {
virtual void mark();
- JSValue* next(ExecState*);
+ JSValuePtr next(ExecState*);
void invalidate();
private:
@@ -83,23 +83,23 @@ inline JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, PassRefP
{
}
-inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue* v)
+inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValuePtr v)
{
- if (v->isUndefinedOrNull())
+ if (v.isUndefinedOrNull())
return new (exec) JSPropertyNameIterator;
- JSObject* o = v->toObject(exec);
+ JSObject* o = v.toObject(exec);
PropertyNameArray propertyNames(exec);
o->getPropertyNames(exec, propertyNames);
return new (exec) JSPropertyNameIterator(o, propertyNames.releaseData());
}
-inline JSValue* JSPropertyNameIterator::next(ExecState* exec)
+inline JSValuePtr JSPropertyNameIterator::next(ExecState* exec)
{
if (m_position == m_end)
return noValue();
- if (m_data->cachedStructureID() == m_object->structureID() && structureIDChainsAreEqual(m_data->cachedPrototypeChain(), m_object->structureID()->cachedPrototypeChain()))
+ if (m_data->cachedStructure() == m_object->structure() && structureChainsAreEqual(m_data->cachedPrototypeChain(), m_object->structure()->cachedPrototypeChain()))
return jsOwnedString(exec, (*m_position++).ustring());
do {
diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/JavaScriptCore/runtime/JSStaticScopeObject.cpp
index 0698250..4196822 100644
--- a/JavaScriptCore/runtime/JSStaticScopeObject.cpp
+++ b/JavaScriptCore/runtime/JSStaticScopeObject.cpp
@@ -44,7 +44,7 @@ JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const
return exec->globalThisValue();
}
-void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot&)
+void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValuePtr value, PutPropertySlot&)
{
if (symbolTablePut(propertyName, value))
return;
@@ -52,7 +52,7 @@ void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValu
ASSERT_NOT_REACHED();
}
-void JSStaticScopeObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
+void JSStaticScopeObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
{
if (symbolTablePutWithAttributes(propertyName, value, attributes))
return;
diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.h b/JavaScriptCore/runtime/JSStaticScopeObject.h
index b152862..e1400b7 100644
--- a/JavaScriptCore/runtime/JSStaticScopeObject.h
+++ b/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -43,8 +43,8 @@ namespace JSC{
};
public:
- JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValue* value, unsigned attributes)
- : JSVariableObject(exec->globalData().staticScopeStructureID, new JSStaticScopeObjectData())
+ JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValuePtr value, unsigned attributes)
+ : JSVariableObject(exec->globalData().staticScopeStructure, new JSStaticScopeObjectData())
{
d()->registerStore = value;
symbolTable().add(ident.ustring().rep(), SymbolTableEntry(-1, attributes));
@@ -55,10 +55,10 @@ namespace JSC{
virtual JSObject* toThisObject(ExecState*) const;
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
- virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
- void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes);
+ virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
+ void putWithAttributes(ExecState*, const Identifier&, JSValuePtr, unsigned attributes);
- static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
private:
JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); }
diff --git a/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp
index 49503d5..48391de 100644
--- a/JavaScriptCore/runtime/JSString.cpp
+++ b/JavaScriptCore/runtime/JSString.cpp
@@ -30,12 +30,12 @@
namespace JSC {
-JSValue* JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
+JSValuePtr JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
{
return const_cast<JSString*>(this);
}
-bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
+bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value)
{
value = this;
number = m_value.toDouble();
@@ -90,7 +90,7 @@ bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNam
return true;
slot.setBase(this);
JSObject* object;
- for (JSValue* prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype->isNull(); prototype = object->prototype()) {
+ for (JSValuePtr prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype.isNull(); prototype = object->prototype()) {
object = asObject(prototype);
if (object->getOwnPropertySlot(exec, propertyName, slot))
return true;
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index b6275e7..e4baa73 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -24,10 +24,10 @@
#define JSString_h
#include "CommonIdentifiers.h"
-#include "ExecState.h"
+#include "CallFrame.h"
+#include "Identifier.h"
#include "JSNumberCell.h"
#include "PropertySlot.h"
-#include "identifier.h"
namespace JSC {
@@ -59,12 +59,12 @@ namespace JSC {
JSString* jsOwnedString(ExecState*, const UString&);
class JSString : public JSCell {
- friend class CTI;
- friend class Machine;
+ friend class JIT;
+ friend class Interpreter;
public:
JSString(JSGlobalData* globalData, const UString& value)
- : JSCell(globalData->stringStructureID.get())
+ : JSCell(globalData->stringStructure.get())
, m_value(value)
{
Heap::heap(this)->reportExtraMemoryCost(value.cost());
@@ -72,12 +72,12 @@ namespace JSC {
enum HasOtherOwnerType { HasOtherOwner };
JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType)
- : JSCell(globalData->stringStructureID.get())
+ : JSCell(globalData->stringStructure.get())
, m_value(value)
{
}
JSString(JSGlobalData* globalData, PassRefPtr<UString::Rep> value, HasOtherOwnerType)
- : JSCell(globalData->stringStructureID.get())
+ : JSCell(globalData->stringStructure.get())
, m_value(value)
{
}
@@ -90,7 +90,7 @@ namespace JSC {
bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
JSString* getIndex(JSGlobalData*, unsigned);
- static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
private:
enum VPtrStealingHackType { VPtrStealingHack };
@@ -99,8 +99,8 @@ namespace JSC {
{
}
- virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+ virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual JSObject* toObject(ExecState*) const;
@@ -117,9 +117,9 @@ namespace JSC {
UString m_value;
};
- JSString* asString(JSValue*);
+ JSString* asString(JSValuePtr);
- inline JSString* asString(JSValue* value)
+ inline JSString* asString(JSValuePtr value)
{
ASSERT(asCell(value)->isString());
return static_cast<JSString*>(asCell(value));
@@ -204,7 +204,7 @@ namespace JSC {
// --- JSValue inlines ----------------------------
- inline JSString* JSValue::toThisJSString(ExecState* exec)
+ inline JSString* JSValuePtr::toThisJSString(ExecState* exec)
{
return JSImmediate::isImmediate(asValue()) ? jsString(exec, JSImmediate::toString(asValue())) : asCell()->toThisJSString(exec);
}
diff --git a/JavaScriptCore/runtime/JSType.h b/JavaScriptCore/runtime/JSType.h
index f0fa28f..68f2890 100644
--- a/JavaScriptCore/runtime/JSType.h
+++ b/JavaScriptCore/runtime/JSType.h
@@ -1,6 +1,5 @@
/*
- * This file is part of the KDE libraries
- * Copyright (C) 2006 Apple Computer, Inc
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -19,8 +18,8 @@
*
*/
-#ifndef KJS_JSTYPE_H
-#define KJS_JSTYPE_H
+#ifndef JSType_h
+#define JSType_h
namespace JSC {
diff --git a/JavaScriptCore/runtime/JSValue.cpp b/JavaScriptCore/runtime/JSValue.cpp
index 73580b0..f549bff 100644
--- a/JavaScriptCore/runtime/JSValue.cpp
+++ b/JavaScriptCore/runtime/JSValue.cpp
@@ -31,20 +31,18 @@ namespace JSC {
static const double D32 = 4294967296.0;
// ECMA 9.4
-double JSValue::toInteger(ExecState* exec) const
+double JSValuePtr::toInteger(ExecState* exec) const
{
- int32_t i;
- if (getTruncatedInt32(i))
- return i;
+ if (isInt32Fast())
+ return getInt32Fast();
double d = toNumber(exec);
return isnan(d) ? 0.0 : trunc(d);
}
-double JSValue::toIntegerPreserveNaN(ExecState* exec) const
+double JSValuePtr::toIntegerPreserveNaN(ExecState* exec) const
{
- int32_t i;
- if (getTruncatedInt32(i))
- return i;
+ if (isInt32Fast())
+ return getInt32Fast();
return trunc(toNumber(exec));
}
@@ -68,11 +66,6 @@ int32_t toInt32SlowCase(double d, bool& ok)
return static_cast<int32_t>(d32);
}
-int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
-{
- return JSC::toInt32SlowCase(toNumber(exec), ok);
-}
-
uint32_t toUInt32SlowCase(double d, bool& ok)
{
ok = true;
@@ -91,14 +84,4 @@ uint32_t toUInt32SlowCase(double d, bool& ok)
return static_cast<uint32_t>(d32);
}
-uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
-{
- return JSC::toUInt32SlowCase(toNumber(exec), ok);
-}
-
-float JSValue::toFloat(ExecState* exec) const
-{
- return static_cast<float>(toNumber(exec));
-}
-
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h
index 059a5e6..1172a1b 100644
--- a/JavaScriptCore/runtime/JSValue.h
+++ b/JavaScriptCore/runtime/JSValue.h
@@ -20,37 +20,87 @@
*
*/
+#include <stddef.h> // for size_t
+#include <stdint.h>
+
#ifndef JSValue_h
#define JSValue_h
#include "CallData.h"
#include "ConstructData.h"
-#include "JSImmediate.h"
-#include "ustring.h"
-#include <stddef.h> // for size_t
-
-// The magic number 0x4000 is not important here, it is being subtracted back out (avoiding using zero since this
-// can have unexpected effects in this type of macro, particularly where multiple-inheritance is involved).
-#define OBJECT_OFFSET(class, member) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->member)) - 0x4000)
namespace JSC {
class Identifier;
+ class JSCell;
+ class JSObject;
class JSString;
class PropertySlot;
class PutPropertySlot;
+ class UString;
struct ClassInfo;
struct Instruction;
enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
- class JSValue : Noncopyable {
- protected:
- JSValue() { }
- virtual ~JSValue() { }
+ class JSImmediate;
+ class JSValueEncodedAsPointer;
+
+ class JSValuePtr {
+ friend class JSImmediate;
+ static JSValuePtr makeImmediate(intptr_t value)
+ {
+ return JSValuePtr(reinterpret_cast<JSCell*>(value));
+ }
+
+ intptr_t immediateValue()
+ {
+ return reinterpret_cast<intptr_t>(m_ptr);
+ }
+
public:
+ JSValuePtr()
+ : m_ptr(0)
+ {
+ }
+
+ JSValuePtr(JSCell* ptr)
+ : m_ptr(ptr)
+ {
+ }
+
+ JSValuePtr(const JSCell* ptr)
+ : m_ptr(const_cast<JSCell*>(ptr))
+ {
+ }
+
+ operator bool() const
+ {
+ return m_ptr;
+ }
+
+ bool operator==(const JSValuePtr other) const
+ {
+ return m_ptr == other.m_ptr;
+ }
+
+ bool operator!=(const JSValuePtr other) const
+ {
+ return m_ptr != other.m_ptr;
+ }
+
+ static JSValueEncodedAsPointer* encode(JSValuePtr value)
+ {
+ return reinterpret_cast<JSValueEncodedAsPointer*>(value.m_ptr);
+ }
+
+ static JSValuePtr decode(JSValueEncodedAsPointer* ptr)
+ {
+ return JSValuePtr(reinterpret_cast<JSCell*>(ptr));
+ }
+
// Querying the type.
bool isUndefined() const;
bool isNull() const;
@@ -65,7 +115,7 @@ namespace JSC {
// Extracting the value.
bool getBoolean(bool&) const;
bool getBoolean() const; // false if not a boolean
- double getNumber() const; // NaN if not a number
+ bool getNumber(double&) const;
double uncheckedGetNumber() const;
bool getString(UString&) const;
UString getString() const; // null string if not a string
@@ -80,163 +130,92 @@ namespace JSC {
bool getTruncatedUInt32(uint32_t&) const;
// Basic conversions.
- JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
- bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
+ JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
+ bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&);
bool toBoolean(ExecState*) const;
// toNumber conversion is expected to be side effect free if an exception has
// been set in the ExecState already.
double toNumber(ExecState*) const;
- JSValue* toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
-
+ JSValuePtr toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
UString toString(ExecState*) const;
JSObject* toObject(ExecState*) const;
// Integer conversions.
+ // 'x.numberToInt32(output)' is equivalent to 'x.isNumber() && x.toInt32(output)'
double toInteger(ExecState*) const;
double toIntegerPreserveNaN(ExecState*) const;
int32_t toInt32(ExecState*) const;
int32_t toInt32(ExecState*, bool& ok) const;
+ bool numberToInt32(int32_t& arg);
uint32_t toUInt32(ExecState*) const;
uint32_t toUInt32(ExecState*, bool& ok) const;
-
- // Floating point conversions.
- float toFloat(ExecState*) const;
+ bool numberToUInt32(uint32_t& arg);
+
+ // Fast integer operations; these values return results where the value is trivially available
+ // in a convenient form, for use in optimizations. No assumptions should be made based on the
+ // results of these operations, for example !isInt32Fast() does not necessarily indicate the
+ // result of getNumber will not be 0.
+ bool isInt32Fast() const;
+ int32_t getInt32Fast() const;
+ bool isUInt32Fast() const;
+ uint32_t getUInt32Fast() const;
+ static JSValuePtr makeInt32Fast(int32_t);
+ static bool areBothInt32Fast(JSValuePtr, JSValuePtr);
+
+ // Floating point conversions (this is a convenience method for webcore;
+ // signle precision float is not a representation used in JS or JSC).
+ float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }
// Garbage collection.
void mark();
bool marked() const;
// Object operations, with the toObject operation included.
- JSValue* get(ExecState*, const Identifier& propertyName) const;
- JSValue* get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
- JSValue* get(ExecState*, unsigned propertyName) const;
- JSValue* get(ExecState*, unsigned propertyName, PropertySlot&) const;
- void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
- void put(ExecState*, unsigned propertyName, JSValue*);
- bool deleteProperty(ExecState*, const Identifier& propertyName);
- bool deleteProperty(ExecState*, unsigned propertyName);
+ JSValuePtr get(ExecState*, const Identifier& propertyName) const;
+ JSValuePtr get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
+ JSValuePtr get(ExecState*, unsigned propertyName) const;
+ JSValuePtr get(ExecState*, unsigned propertyName, PropertySlot&) const;
+ void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+ void put(ExecState*, unsigned propertyName, JSValuePtr);
bool needsThisConversion() const;
JSObject* toThisObject(ExecState*) const;
UString toThisString(ExecState*) const;
JSString* toThisJSString(ExecState*);
- JSValue* getJSNumber(); // 0 if this is not a JSNumber or number object
+ static bool equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2);
+ static bool equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2);
+ static bool equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2);
+ static bool strictEqual(JSValuePtr v1, JSValuePtr v2);
+ static bool strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2);
+ static bool strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2);
- JSValue* asValue() const;
+ JSValuePtr getJSNumber(); // noValue() if this is not a JSNumber or number object
+ bool isCell() const;
JSCell* asCell() const;
private:
- bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
- bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- int32_t toInt32SlowCase(ExecState*, bool& ok) const;
- uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;
- };
-
- // These are identical logic to the JSValue functions above, and faster than jsNumber(number)->toInt32().
- int32_t toInt32(double);
- uint32_t toUInt32(double);
- int32_t toInt32SlowCase(double, bool& ok);
- uint32_t toUInt32SlowCase(double, bool& ok);
-
- inline JSValue* JSValue::asValue() const
- {
- return const_cast<JSValue*>(this);
- }
-
- inline bool JSValue::isUndefined() const
- {
- return asValue() == jsUndefined();
- }
-
- inline bool JSValue::isNull() const
- {
- return asValue() == jsNull();
- }
-
- inline bool JSValue::isUndefinedOrNull() const
- {
- return JSImmediate::isUndefinedOrNull(asValue());
- }
-
- inline bool JSValue::isBoolean() const
- {
- return JSImmediate::isBoolean(asValue());
- }
-
- inline bool JSValue::getBoolean(bool& v) const
- {
- if (JSImmediate::isBoolean(asValue())) {
- v = JSImmediate::toBoolean(asValue());
- return true;
- }
-
- return false;
- }
-
- inline bool JSValue::getBoolean() const
- {
- return asValue() == jsBoolean(true);
- }
+ inline const JSValuePtr asValue() const { return *this; }
- ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
- {
- int32_t i;
- if (getTruncatedInt32(i))
- return i;
- bool ok;
- return toInt32SlowCase(exec, ok);
- }
+ bool isDoubleNumber() const;
+ double getDoubleNumber() const;
- inline uint32_t JSValue::toUInt32(ExecState* exec) const
- {
- uint32_t i;
- if (getTruncatedUInt32(i))
- return i;
- bool ok;
- return toUInt32SlowCase(exec, ok);
- }
-
- inline int32_t toInt32(double val)
- {
- if (!(val >= -2147483648.0 && val < 2147483648.0)) {
- bool ignored;
- return toInt32SlowCase(val, ignored);
- }
- return static_cast<int32_t>(val);
- }
+ JSCell* m_ptr;
+ };
- inline uint32_t toUInt32(double val)
+ inline JSValuePtr noValue()
{
- if (!(val >= 0.0 && val < 4294967296.0)) {
- bool ignored;
- return toUInt32SlowCase(val, ignored);
- }
- return static_cast<uint32_t>(val);
+ return JSValuePtr();
}
- inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
- {
- int32_t i;
- if (getTruncatedInt32(i)) {
- ok = true;
- return i;
- }
- return toInt32SlowCase(exec, ok);
- }
+ inline bool operator==(const JSValuePtr a, const JSCell* b) { return a == JSValuePtr(b); }
+ inline bool operator==(const JSCell* a, const JSValuePtr b) { return JSValuePtr(a) == b; }
- inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
- {
- uint32_t i;
- if (getTruncatedUInt32(i)) {
- ok = true;
- return i;
- }
- return toUInt32SlowCase(exec, ok);
- }
+ inline bool operator!=(const JSValuePtr a, const JSCell* b) { return a != JSValuePtr(b); }
+ inline bool operator!=(const JSCell* a, const JSValuePtr b) { return JSValuePtr(a) != b; }
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSVariableObject.h b/JavaScriptCore/runtime/JSVariableObject.h
index 1194517..9bf5c4f 100644
--- a/JavaScriptCore/runtime/JSVariableObject.h
+++ b/JavaScriptCore/runtime/JSVariableObject.h
@@ -41,10 +41,12 @@ namespace JSC {
class Register;
class JSVariableObject : public JSObject {
+ friend class JIT;
+
public:
SymbolTable& symbolTable() const { return *d->symbolTable; }
- virtual void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes) = 0;
+ virtual void putWithAttributes(ExecState*, const Identifier&, JSValuePtr, unsigned attributes) = 0;
virtual bool deleteProperty(ExecState*, const Identifier&);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
@@ -72,18 +74,13 @@ namespace JSC {
Register* registers; // "r" in the register file.
OwnArrayPtr<Register> registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
- static inline ptrdiff_t offsetOf_registers()
- {
- return OBJECT_OFFSET(JSVariableObjectData, registers);
- }
-
private:
JSVariableObjectData(const JSVariableObjectData&);
JSVariableObjectData& operator=(const JSVariableObjectData&);
};
- JSVariableObject(PassRefPtr<StructureID> structureID, JSVariableObjectData* data)
- : JSObject(structureID)
+ JSVariableObject(PassRefPtr<Structure> structure, JSVariableObjectData* data)
+ : JSObject(structure)
, d(data) // Subclass owns this pointer.
{
}
@@ -93,21 +90,10 @@ namespace JSC {
bool symbolTableGet(const Identifier&, PropertySlot&);
bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
- bool symbolTablePut(const Identifier&, JSValue*);
- bool symbolTablePutWithAttributes(const Identifier&, JSValue*, unsigned attributes);
+ bool symbolTablePut(const Identifier&, JSValuePtr);
+ bool symbolTablePutWithAttributes(const Identifier&, JSValuePtr, unsigned attributes);
JSVariableObjectData* d;
-
- public:
- static inline ptrdiff_t offsetOf_d()
- {
- return OBJECT_OFFSET(JSVariableObject, d);
- }
-
- static inline ptrdiff_t offsetOf_Data_registers()
- {
- return JSVariableObjectData::offsetOf_registers();
- }
};
inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
@@ -131,7 +117,7 @@ namespace JSC {
return false;
}
- inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value)
+ inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValuePtr value)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -144,7 +130,7 @@ namespace JSC {
return true;
}
- inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue* value, unsigned attributes)
+ inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValuePtr value, unsigned attributes)
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
diff --git a/JavaScriptCore/runtime/JSWrapperObject.cpp b/JavaScriptCore/runtime/JSWrapperObject.cpp
index c791d93..fb57018 100644
--- a/JavaScriptCore/runtime/JSWrapperObject.cpp
+++ b/JavaScriptCore/runtime/JSWrapperObject.cpp
@@ -29,8 +29,8 @@ ASSERT_CLASS_FITS_IN_CELL(JSWrapperObject);
void JSWrapperObject::mark()
{
JSObject::mark();
- if (m_internalValue && !m_internalValue->marked())
- m_internalValue->mark();
+ if (m_internalValue && !m_internalValue.marked())
+ m_internalValue.mark();
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSWrapperObject.h b/JavaScriptCore/runtime/JSWrapperObject.h
index 5e4ba17..7381128 100644
--- a/JavaScriptCore/runtime/JSWrapperObject.h
+++ b/JavaScriptCore/runtime/JSWrapperObject.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Maks Orlovich
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -19,8 +19,8 @@
*
*/
-#ifndef KJS_JSWrapperObject_h
-#define KJS_JSWrapperObject_h
+#ifndef JSWrapperObject_h
+#define JSWrapperObject_h
#include "JSObject.h"
@@ -30,31 +30,31 @@ namespace JSC {
// Number, Boolean and Date which are wrappers for primitive types.
class JSWrapperObject : public JSObject {
protected:
- explicit JSWrapperObject(PassRefPtr<StructureID>);
+ explicit JSWrapperObject(PassRefPtr<Structure>);
public:
- JSValue* internalValue() const { return m_internalValue; }
- void setInternalValue(JSValue*);
+ JSValuePtr internalValue() const { return m_internalValue; }
+ void setInternalValue(JSValuePtr);
virtual void mark();
private:
- JSValue* m_internalValue;
+ JSValuePtr m_internalValue;
};
- inline JSWrapperObject::JSWrapperObject(PassRefPtr<StructureID> structure)
+ inline JSWrapperObject::JSWrapperObject(PassRefPtr<Structure> structure)
: JSObject(structure)
, m_internalValue(noValue())
{
}
- inline void JSWrapperObject::setInternalValue(JSValue* value)
+ inline void JSWrapperObject::setInternalValue(JSValuePtr value)
{
ASSERT(value);
- ASSERT(!value->isObject());
+ ASSERT(!value.isObject());
m_internalValue = value;
}
} // namespace JSC
-#endif // KJS_JSWrapperObject_h
+#endif // JSWrapperObject_h
diff --git a/JavaScriptCore/kjs/lookup.cpp b/JavaScriptCore/runtime/Lookup.cpp
index 41ac725..98133a8 100644
--- a/JavaScriptCore/kjs/lookup.cpp
+++ b/JavaScriptCore/runtime/Lookup.cpp
@@ -18,7 +18,7 @@
*/
#include "config.h"
-#include "lookup.h"
+#include "Lookup.h"
#include "PrototypeFunction.h"
@@ -26,6 +26,7 @@ namespace JSC {
void HashTable::createTable(JSGlobalData* globalData) const
{
+#if ENABLE(PERFECT_HASH_SIZE)
ASSERT(!table);
HashEntry* entries = new HashEntry[hashSizeMask + 1];
for (int i = 0; i <= hashSizeMask; ++i)
@@ -37,12 +38,41 @@ void HashTable::createTable(JSGlobalData* globalData) const
entries[hashIndex].initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
}
table = entries;
+#else
+ ASSERT(!table);
+ int linkIndex = compactHashSizeMask + 1;
+ HashEntry* entries = new HashEntry[compactSize];
+ for (int i = 0; i < compactSize; ++i)
+ entries[i].setKey(0);
+ for (int i = 0; values[i].key; ++i) {
+ UString::Rep* identifier = Identifier::add(globalData, values[i].key).releaseRef();
+ int hashIndex = identifier->computedHash() & compactHashSizeMask;
+ HashEntry* entry = &entries[hashIndex];
+
+ if (entry->key()) {
+ while (entry->next()) {
+ entry = entry->next();
+ }
+ ASSERT(linkIndex < compactSize);
+ entry->setNext(&entries[linkIndex++]);
+ entry = entry->next();
+ }
+
+ entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
+ }
+ table = entries;
+#endif
}
void HashTable::deleteTable() const
{
if (table) {
- for (int i = 0; i != hashSizeMask + 1; ++i) {
+#if ENABLE(PERFECT_HASH_SIZE)
+ int max = hashSizeMask + 1;
+#else
+ int max = compactSize;
+#endif
+ for (int i = 0; i != max; ++i) {
if (UString::Rep* key = table[i].key())
key->deref();
}
@@ -54,7 +84,7 @@ void HashTable::deleteTable() const
void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot)
{
ASSERT(entry->attributes() & Function);
- JSValue** location = thisObj->getDirectLocation(propertyName);
+ JSValuePtr* location = thisObj->getDirectLocation(propertyName);
if (!location) {
PrototypeFunction* function = new (exec) PrototypeFunction(exec, entry->functionLength(), propertyName, entry->function());
diff --git a/JavaScriptCore/kjs/lookup.h b/JavaScriptCore/runtime/Lookup.h
index a547613..55c3221 100644
--- a/JavaScriptCore/kjs/lookup.h
+++ b/JavaScriptCore/runtime/Lookup.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,18 +18,22 @@
*
*/
-#ifndef KJS_lookup_h
-#define KJS_lookup_h
+#ifndef Lookup_h
+#define Lookup_h
-#include "ExecState.h"
+#include "CallFrame.h"
+#include "Identifier.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
#include "PropertySlot.h"
-#include "identifier.h"
#include <stdio.h>
#include <wtf/Assertions.h>
+// Set ENABLE_PERFECT_HASH_SIZE to 0 to save memory at the
+// cost of speed. Test your platform as results may vary.
+#define ENABLE_PERFECT_HASH_SIZE 1
+
namespace JSC {
// Hash table generated by the create_hash_table script.
@@ -41,9 +45,9 @@ namespace JSC {
};
// FIXME: There is no reason this get function can't be simpler.
- // ie. typedef JSValue* (*GetFunction)(ExecState*, JSObject* baseObject)
+ // ie. typedef JSValuePtr (*GetFunction)(ExecState*, JSObject* baseObject)
typedef PropertySlot::GetValueFunc GetFunction;
- typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValue* value);
+ typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValuePtr value);
class HashEntry {
public:
@@ -53,6 +57,9 @@ namespace JSC {
m_attributes = attributes;
m_u.store.value1 = v1;
m_u.store.value2 = v2;
+#if !ENABLE(PERFECT_HASH_SIZE)
+ m_next = 0;
+#endif
}
void setKey(UString::Rep* key) { m_key = key; }
@@ -68,6 +75,11 @@ namespace JSC {
intptr_t lexerValue() const { ASSERT(!m_attributes); return m_u.lexer.value; }
+#if !ENABLE(PERFECT_HASH_SIZE)
+ void setNext(HashEntry *next) { m_next = next; }
+ HashEntry* next() const { return m_next; }
+#endif
+
private:
UString::Rep* m_key;
unsigned char m_attributes; // JSObject attributes
@@ -90,10 +102,19 @@ namespace JSC {
intptr_t unused;
} lexer;
} m_u;
+
+#if !ENABLE(PERFECT_HASH_SIZE)
+ HashEntry* m_next;
+#endif
};
struct HashTable {
+#if ENABLE(PERFECT_HASH_SIZE)
int hashSizeMask; // Precomputed size for the hash table (minus 1).
+#else
+ int compactSize;
+ int compactHashSizeMask;
+#endif
const HashTableValue* values; // Fixed values generated by script.
mutable const HashEntry* table; // Table allocated at runtime.
@@ -127,11 +148,28 @@ namespace JSC {
private:
ALWAYS_INLINE const HashEntry* entry(const Identifier& identifier) const
{
+#if ENABLE(PERFECT_HASH_SIZE)
ASSERT(table);
const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & hashSizeMask];
if (entry->key() != identifier.ustring().rep())
return 0;
return entry;
+#else
+ ASSERT(table);
+
+ const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & compactHashSizeMask];
+
+ if (!entry->key())
+ return 0;
+
+ do {
+ if (entry->key() == identifier.ustring().rep())
+ return entry;
+ entry = entry->next();
+ } while (entry);
+
+ return 0;
+#endif
}
// Convert the hash table keys to identifiers.
@@ -205,7 +243,7 @@ namespace JSC {
* is found it sets the value and returns true, else it returns false.
*/
template <class ThisImp>
- inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValue* value, const HashTable* table, ThisImp* thisObj)
+ inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, const HashTable* table, ThisImp* thisObj)
{
const HashEntry* entry = table->entry(exec, propertyName);
@@ -227,7 +265,7 @@ namespace JSC {
* then it calls put() on the ParentImp class.
*/
template <class ThisImp, class ParentImp>
- inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue* value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot)
+ inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot)
{
if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj))
thisObj->ParentImp::put(exec, propertyName, value, slot); // not found: forward to parent
@@ -235,4 +273,4 @@ namespace JSC {
} // namespace JSC
-#endif // KJS_lookup_h
+#endif // Lookup_h
diff --git a/JavaScriptCore/runtime/MathObject.cpp b/JavaScriptCore/runtime/MathObject.cpp
index 8b972d3..f9b7653 100644
--- a/JavaScriptCore/runtime/MathObject.cpp
+++ b/JavaScriptCore/runtime/MathObject.cpp
@@ -22,33 +22,35 @@
#include "MathObject.h"
#include "ObjectPrototype.h"
-#include "operations.h"
+#include "Operations.h"
#include <time.h>
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
+#include <wtf/RandomNumber.h>
+#include <wtf/RandomNumberSeed.h>
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(MathObject);
-static JSValue* mathProtoFuncAbs(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncACos(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncASin(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncATan(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncATan2(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncCeil(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncCos(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncExp(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncFloor(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncLog(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncMax(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncMin(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncPow(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncRandom(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncRound(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncSin(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncSqrt(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* mathProtoFuncTan(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr mathProtoFuncAbs(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncACos(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncASin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncATan(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncATan2(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncCeil(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncCos(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncExp(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncFloor(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncLog(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncMax(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncMin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncPow(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncRandom(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncRound(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncSin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncSqrt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr mathProtoFuncTan(ExecState*, JSObject*, JSValuePtr, const ArgList&);
}
@@ -83,7 +85,7 @@ const ClassInfo MathObject::info = { "Math", 0, 0, ExecState::mathTable };
@end
*/
-MathObject::MathObject(ExecState* exec, PassRefPtr<StructureID> structure)
+MathObject::MathObject(ExecState* exec, PassRefPtr<Structure> structure)
: JSObject(structure)
{
putDirectWithoutTransition(Identifier(exec, "E"), jsNumber(exec, exp(1.0)), DontDelete | DontEnum | ReadOnly);
@@ -94,6 +96,7 @@ MathObject::MathObject(ExecState* exec, PassRefPtr<StructureID> structure)
putDirectWithoutTransition(Identifier(exec, "PI"), jsNumber(exec, piDouble), DontDelete | DontEnum | ReadOnly);
putDirectWithoutTransition(Identifier(exec, "SQRT1_2"), jsNumber(exec, sqrt(0.5)), DontDelete | DontEnum | ReadOnly);
putDirectWithoutTransition(Identifier(exec, "SQRT2"), jsNumber(exec, sqrt(2.0)), DontDelete | DontEnum | ReadOnly);
+ WTF::initializeWeakRandomNumberGenerator();
}
// ECMA 15.8
@@ -112,62 +115,62 @@ bool MathObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
// ------------------------------ Functions --------------------------------
-JSValue* mathProtoFuncAbs(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncAbs(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, fabs(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, fabs(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncACos(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncACos(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, acos(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, acos(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncASin(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncASin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, asin(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, asin(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncATan(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncATan(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, atan(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, atan(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncATan2(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncATan2(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, atan2(args.at(exec, 0)->toNumber(exec), args.at(exec, 1)->toNumber(exec)));
+ return jsNumber(exec, atan2(args.at(exec, 0).toNumber(exec), args.at(exec, 1).toNumber(exec)));
}
-JSValue* mathProtoFuncCeil(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncCeil(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, ceil(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, ceil(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncCos(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncCos(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, cos(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, cos(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncExp(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncExp(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, exp(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, exp(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncFloor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncFloor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, floor(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, floor(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncLog(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncLog(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, log(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, log(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncMax(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncMax(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
unsigned argsCount = args.size();
double result = -Inf;
for (unsigned k = 0; k < argsCount; ++k) {
- double val = args.at(exec, k)->toNumber(exec);
+ double val = args.at(exec, k).toNumber(exec);
if (isnan(val)) {
result = NaN;
break;
@@ -178,12 +181,12 @@ JSValue* mathProtoFuncMax(ExecState* exec, JSObject*, JSValue*, const ArgList& a
return jsNumber(exec, result);
}
-JSValue* mathProtoFuncMin(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncMin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
unsigned argsCount = args.size();
double result = +Inf;
for (unsigned k = 0; k < argsCount; ++k) {
- double val = args.at(exec, k)->toNumber(exec);
+ double val = args.at(exec, k).toNumber(exec);
if (isnan(val)) {
result = NaN;
break;
@@ -194,12 +197,12 @@ JSValue* mathProtoFuncMin(ExecState* exec, JSObject*, JSValue*, const ArgList& a
return jsNumber(exec, result);
}
-JSValue* mathProtoFuncPow(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncPow(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
// ECMA 15.8.2.1.13
- double arg = args.at(exec, 0)->toNumber(exec);
- double arg2 = args.at(exec, 1)->toNumber(exec);
+ double arg = args.at(exec, 0).toNumber(exec);
+ double arg2 = args.at(exec, 1).toNumber(exec);
if (isnan(arg2))
return jsNaN(exec);
@@ -208,40 +211,32 @@ JSValue* mathProtoFuncPow(ExecState* exec, JSObject*, JSValue*, const ArgList& a
return jsNumber(exec, pow(arg, arg2));
}
-JSValue* mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue*, const ArgList&)
+JSValuePtr mathProtoFuncRandom(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
{
-#if !ENABLE(JSC_MULTIPLE_THREADS)
- static bool didInitRandom;
- if (!didInitRandom) {
- wtf_random_init();
- didInitRandom = true;
- }
-#endif
-
- return jsNumber(exec, wtf_random());
+ return jsNumber(exec, WTF::weakRandomNumber());
}
-JSValue* mathProtoFuncRound(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncRound(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- double arg = args.at(exec, 0)->toNumber(exec);
+ double arg = args.at(exec, 0).toNumber(exec);
if (signbit(arg) && arg >= -0.5)
return jsNumber(exec, -0.0);
return jsNumber(exec, floor(arg + 0.5));
}
-JSValue* mathProtoFuncSin(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncSin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, sin(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, sin(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, sqrt(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, sqrt(args.at(exec, 0).toNumber(exec)));
}
-JSValue* mathProtoFuncTan(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+JSValuePtr mathProtoFuncTan(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, tan(args.at(exec, 0)->toNumber(exec)));
+ return jsNumber(exec, tan(args.at(exec, 0).toNumber(exec)));
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/MathObject.h b/JavaScriptCore/runtime/MathObject.h
index 704b10e..d6163fd 100644
--- a/JavaScriptCore/runtime/MathObject.h
+++ b/JavaScriptCore/runtime/MathObject.h
@@ -27,16 +27,16 @@ namespace JSC {
class MathObject : public JSObject {
public:
- MathObject(ExecState*, PassRefPtr<StructureID>);
+ MathObject(ExecState*, PassRefPtr<Structure>);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType));
}
};
diff --git a/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/JavaScriptCore/runtime/NativeErrorConstructor.cpp
index 05159f0..eee9890 100644
--- a/JavaScriptCore/runtime/NativeErrorConstructor.cpp
+++ b/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -23,6 +23,7 @@
#include "ErrorInstance.h"
#include "JSFunction.h"
+#include "JSString.h"
#include "NativeErrorPrototype.h"
namespace JSC {
@@ -31,9 +32,9 @@ ASSERT_CLASS_FITS_IN_CELL(NativeErrorConstructor);
const ClassInfo NativeErrorConstructor::info = { "Function", &InternalFunction::info, 0, 0 };
-NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, PassRefPtr<StructureID> structure, NativeErrorPrototype* nativeErrorPrototype)
- : InternalFunction(&exec->globalData(), structure, Identifier(exec, nativeErrorPrototype->getDirect(exec->propertyNames().name)->getString()))
- , m_errorStructure(ErrorInstance::createStructureID(nativeErrorPrototype))
+NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, PassRefPtr<Structure> structure, NativeErrorPrototype* nativeErrorPrototype)
+ : InternalFunction(&exec->globalData(), structure, Identifier(exec, nativeErrorPrototype->getDirect(exec->propertyNames().name).getString()))
+ , m_errorStructure(ErrorInstance::createStructure(nativeErrorPrototype))
{
putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
putDirect(exec->propertyNames().prototype, nativeErrorPrototype, DontDelete | ReadOnly | DontEnum);
@@ -42,8 +43,8 @@ NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, PassRefPtr<Struc
ErrorInstance* NativeErrorConstructor::construct(ExecState* exec, const ArgList& args)
{
ErrorInstance* object = new (exec) ErrorInstance(m_errorStructure);
- if (!args.at(exec, 0)->isUndefined())
- object->putDirect(exec->propertyNames().message, jsString(exec, args.at(exec, 0)->toString(exec)));
+ if (!args.at(exec, 0).isUndefined())
+ object->putDirect(exec->propertyNames().message, jsString(exec, args.at(exec, 0).toString(exec)));
return object;
}
@@ -58,7 +59,7 @@ ConstructType NativeErrorConstructor::getConstructData(ConstructData& constructD
return ConstructTypeHost;
}
-static JSValue* callNativeErrorConstructor(ExecState* exec, JSObject* constructor, JSValue*, const ArgList& args)
+static JSValuePtr callNativeErrorConstructor(ExecState* exec, JSObject* constructor, JSValuePtr, const ArgList& args)
{
return static_cast<NativeErrorConstructor*>(constructor)->construct(exec, args);
}
diff --git a/JavaScriptCore/runtime/NativeErrorConstructor.h b/JavaScriptCore/runtime/NativeErrorConstructor.h
index 85acbb9..118d1f4 100644
--- a/JavaScriptCore/runtime/NativeErrorConstructor.h
+++ b/JavaScriptCore/runtime/NativeErrorConstructor.h
@@ -31,7 +31,7 @@ namespace JSC {
class NativeErrorConstructor : public InternalFunction {
public:
- NativeErrorConstructor(ExecState*, PassRefPtr<StructureID>, NativeErrorPrototype*);
+ NativeErrorConstructor(ExecState*, PassRefPtr<Structure>, NativeErrorPrototype*);
static const ClassInfo info;
@@ -43,7 +43,7 @@ namespace JSC {
virtual const ClassInfo* classInfo() const { return &info; }
- RefPtr<StructureID> m_errorStructure;
+ RefPtr<Structure> m_errorStructure;
};
} // namespace JSC
diff --git a/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/JavaScriptCore/runtime/NativeErrorPrototype.cpp
index 9403aa9..84190a0 100644
--- a/JavaScriptCore/runtime/NativeErrorPrototype.cpp
+++ b/JavaScriptCore/runtime/NativeErrorPrototype.cpp
@@ -23,13 +23,13 @@
#include "ErrorPrototype.h"
#include "JSString.h"
-#include "ustring.h"
+#include "UString.h"
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype);
-NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, PassRefPtr<StructureID> structure, const UString& name, const UString& message)
+NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure, const UString& name, const UString& message)
: JSObject(structure)
{
putDirect(exec->propertyNames().name, jsString(exec, name), 0);
diff --git a/JavaScriptCore/runtime/NativeErrorPrototype.h b/JavaScriptCore/runtime/NativeErrorPrototype.h
index 719cb90..77bfe8a 100644
--- a/JavaScriptCore/runtime/NativeErrorPrototype.h
+++ b/JavaScriptCore/runtime/NativeErrorPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class NativeErrorPrototype : public JSObject {
public:
- NativeErrorPrototype(ExecState*, PassRefPtr<StructureID>, const UString& name, const UString& message);
+ NativeErrorPrototype(ExecState*, PassRefPtr<Structure>, const UString& name, const UString& message);
};
} // namespace JSC
diff --git a/JavaScriptCore/runtime/NumberConstructor.cpp b/JavaScriptCore/runtime/NumberConstructor.cpp
index 5b6ccf8..caa4a70 100644
--- a/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -29,11 +29,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 JSValuePtr numberConstructorNaNValue(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr numberConstructorNegInfinity(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr numberConstructorPosInfinity(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr numberConstructorMaxValue(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr numberConstructorMinValue(ExecState*, const Identifier&, const PropertySlot&);
} // namespace JSC
@@ -53,7 +53,7 @@ const ClassInfo NumberConstructor::info = { "Function", &InternalFunction::info,
@end
*/
-NumberConstructor::NumberConstructor(ExecState* exec, PassRefPtr<StructureID> structure, NumberPrototype* numberPrototype)
+NumberConstructor::NumberConstructor(ExecState* exec, PassRefPtr<Structure> structure, NumberPrototype* numberPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, numberPrototype->info.className))
{
// Number.Prototype
@@ -68,36 +68,36 @@ bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr
return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot);
}
-JSValue* numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
+JSValuePtr numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
{
return jsNaN(exec);
}
-JSValue* numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+JSValuePtr numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
{
- return jsNumberCell(exec, -Inf);
+ return jsNumber(exec, -Inf);
}
-JSValue* numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+JSValuePtr numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
{
- return jsNumberCell(exec, Inf);
+ return jsNumber(exec, Inf);
}
-JSValue* numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
+JSValuePtr numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
{
- return jsNumberCell(exec, 1.7976931348623157E+308);
+ return jsNumber(exec, 1.7976931348623157E+308);
}
-JSValue* numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
+JSValuePtr numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
{
- return jsNumberCell(exec, 5E-324);
+ return jsNumber(exec, 5E-324);
}
// ECMA 15.7.1
static JSObject* constructWithNumberConstructor(ExecState* exec, JSObject*, const ArgList& args)
{
NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
- double n = args.isEmpty() ? 0 : args.at(exec, 0)->toNumber(exec);
+ double n = args.isEmpty() ? 0 : args.at(exec, 0).toNumber(exec);
object->setInternalValue(jsNumber(exec, n));
return object;
}
@@ -109,9 +109,9 @@ ConstructType NumberConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.7.2
-static JSValue* callNumberConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr callNumberConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
- return jsNumber(exec, args.isEmpty() ? 0 : args.at(exec, 0)->toNumber(exec));
+ return jsNumber(exec, args.isEmpty() ? 0 : args.at(exec, 0).toNumber(exec));
}
CallType NumberConstructor::getCallData(CallData& callData)
diff --git a/JavaScriptCore/runtime/NumberConstructor.h b/JavaScriptCore/runtime/NumberConstructor.h
index 8da23c4..070be5f 100644
--- a/JavaScriptCore/runtime/NumberConstructor.h
+++ b/JavaScriptCore/runtime/NumberConstructor.h
@@ -29,16 +29,16 @@ namespace JSC {
class NumberConstructor : public InternalFunction {
public:
- NumberConstructor(ExecState*, PassRefPtr<StructureID>, NumberPrototype*);
+ NumberConstructor(ExecState*, PassRefPtr<Structure>, NumberPrototype*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
- JSValue* getValueProperty(ExecState*, int token) const;
+ JSValuePtr getValueProperty(ExecState*, int token) const;
static const ClassInfo info;
- static PassRefPtr<StructureID> createStructureID(JSValue* proto)
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto)
{
- return StructureID::create(proto, TypeInfo(ObjectType, ImplementsHasInstance));
+ return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance));
}
enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
diff --git a/JavaScriptCore/runtime/NumberObject.cpp b/JavaScriptCore/runtime/NumberObject.cpp
index 252671b..dc10d8f 100644
--- a/JavaScriptCore/runtime/NumberObject.cpp
+++ b/JavaScriptCore/runtime/NumberObject.cpp
@@ -31,28 +31,21 @@ ASSERT_CLASS_FITS_IN_CELL(NumberObject);
const ClassInfo NumberObject::info = { "Number", 0, 0, 0 };
-NumberObject::NumberObject(PassRefPtr<StructureID> structure)
+NumberObject::NumberObject(PassRefPtr<Structure> structure)
: JSWrapperObject(structure)
{
}
-JSValue* NumberObject::getJSNumber()
+JSValuePtr NumberObject::getJSNumber()
{
return internalValue();
}
-NumberObject* constructNumber(ExecState* exec, JSNumberCell* number)
+NumberObject* constructNumber(ExecState* exec, JSValuePtr number)
{
NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
object->setInternalValue(number);
return object;
}
-NumberObject* constructNumberFromImmediateNumber(ExecState* exec, JSValue* value)
-{
- NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
- object->setInternalValue(value);
- return object;
-}
-
} // namespace JSC
diff --git a/JavaScriptCore/runtime/NumberObject.h b/JavaScriptCore/runtime/NumberObject.h
index eddecd1..285421d 100644
--- a/JavaScriptCore/runtime/NumberObject.h
+++ b/JavaScriptCore/runtime/NumberObject.h
@@ -25,22 +25,19 @@
namespace JSC {
- class JSNumberCell;
-
class NumberObject : public JSWrapperObject {
public:
- explicit NumberObject(PassRefPtr<StructureID>);
+ explicit NumberObject(PassRefPtr<Structure>);
static const ClassInfo info;
private:
virtual const ClassInfo* classInfo() const { return &info; }
- virtual JSValue* getJSNumber();
+ virtual JSValuePtr getJSNumber();
};
- NumberObject* constructNumber(ExecState*, JSNumberCell*);
- NumberObject* constructNumberFromImmediateNumber(ExecState*, JSValue*);
+ NumberObject* constructNumber(ExecState*, JSValuePtr);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp
index d203e3f..3e5ac91 100644
--- a/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -26,7 +26,7 @@
#include "JSString.h"
#include "PrototypeFunction.h"
#include "dtoa.h"
-#include "operations.h"
+#include "Operations.h"
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
#include <wtf/Vector.h>
@@ -35,16 +35,16 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(NumberPrototype);
-static JSValue* numberProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* numberProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* numberProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* numberProtoFuncToFixed(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* numberProtoFuncToExponential(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* numberProtoFuncToPrecision(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr numberProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr numberProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr numberProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr numberProtoFuncToFixed(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr numberProtoFuncToExponential(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr numberProtoFuncToPrecision(ExecState*, JSObject*, JSValuePtr, const ArgList&);
// ECMA 15.7.4
-NumberPrototype::NumberPrototype(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure)
+NumberPrototype::NumberPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
: NumberObject(structure)
{
setInternalValue(jsNumber(exec, 0));
@@ -67,7 +67,7 @@ static UString integerPartNoExp(double d)
{
int decimalPoint;
int sign;
- char* result = dtoa(d, 0, &decimalPoint, &sign, NULL);
+ char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);
bool resultIsInfOrNan = (decimalPoint == 9999);
size_t length = strlen(result);
@@ -89,7 +89,7 @@ static UString integerPartNoExp(double d)
str.append(buf.data());
}
- freedtoa(result);
+ WTF::freedtoa(result);
return str;
}
@@ -133,15 +133,15 @@ static double intPow10(int e)
return static_cast<double>(result);
}
-JSValue* numberProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr numberProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSValue* v = thisValue->getJSNumber();
+ JSValuePtr v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
- double radixAsDouble = args.at(exec, 0)->toInteger(exec); // nan -> 0
- if (radixAsDouble == 10 || args.at(exec, 0)->isUndefined())
- return jsString(exec, v->toString(exec));
+ double radixAsDouble = args.at(exec, 0).toInteger(exec); // nan -> 0
+ if (radixAsDouble == 10 || args.at(exec, 0).isUndefined())
+ return jsString(exec, v.toString(exec));
if (radixAsDouble < 2 || radixAsDouble > 36)
return throwError(exec, RangeError, "toString() radix argument must be between 2 and 36");
@@ -153,7 +153,7 @@ JSValue* numberProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue,
// unless someone finds a precise rule.
char s[2048 + 3];
const char* lastCharInString = s + sizeof(s) - 1;
- double x = v->uncheckedGetNumber();
+ double x = v.uncheckedGetNumber();
if (isnan(x) || isinf(x))
return jsString(exec, UString::from(x));
@@ -197,39 +197,39 @@ JSValue* numberProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue,
return jsString(exec, startOfResultString);
}
-JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr numberProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
// FIXME: Not implemented yet.
- JSValue* v = thisValue->getJSNumber();
+ JSValuePtr v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
- return jsString(exec, v->toString(exec));
+ return jsString(exec, v.toString(exec));
}
-JSValue* numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- JSValue* v = thisValue->getJSNumber();
+ JSValuePtr v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
return v;
}
-JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSValue* v = thisValue->getJSNumber();
+ JSValuePtr v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
- JSValue* fractionDigits = args.at(exec, 0);
- double df = fractionDigits->toInteger(exec);
+ JSValuePtr fractionDigits = args.at(exec, 0);
+ double df = fractionDigits.toInteger(exec);
if (!(df >= 0 && df <= 20))
return throwError(exec, RangeError, "toFixed() digits argument must be between 0 and 20");
int f = static_cast<int>(df);
- double x = v->uncheckedGetNumber();
+ double x = v.uncheckedGetNumber();
if (isnan(x))
return jsNontrivialString(exec, "NaN");
@@ -302,23 +302,23 @@ static void exponentialPartToString(char* buf, int& i, int decimalPoint)
buf[i++] = static_cast<char>('0' + exponential % 10);
}
-JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSValue* v = thisValue->getJSNumber();
+ JSValuePtr v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
- double x = v->uncheckedGetNumber();
+ double x = v.uncheckedGetNumber();
if (isnan(x) || isinf(x))
return jsString(exec, UString::from(x));
- JSValue* fractionalDigitsValue = args.at(exec, 0);
- double df = fractionalDigitsValue->toInteger(exec);
+ JSValuePtr fractionalDigitsValue = args.at(exec, 0);
+ double df = fractionalDigitsValue.toInteger(exec);
if (!(df >= 0 && df <= 20))
return throwError(exec, RangeError, "toExponential() argument must between 0 and 20");
int fractionalDigits = static_cast<int>(df);
- bool includeAllDigits = fractionalDigitsValue->isUndefined();
+ bool includeAllDigits = fractionalDigitsValue.isUndefined();
int decimalAdjust = 0;
if (x && !includeAllDigits) {
@@ -344,7 +344,7 @@ JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValue* thisV
int decimalPoint;
int sign;
- char* result = dtoa(x, 0, &decimalPoint, &sign, NULL);
+ char* result = WTF::dtoa(x, 0, &decimalPoint, &sign, NULL);
size_t resultLength = strlen(result);
decimalPoint += decimalAdjust;
@@ -367,21 +367,21 @@ JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValue* thisV
}
ASSERT(i <= 80);
- freedtoa(result);
+ WTF::freedtoa(result);
return jsString(exec, buf);
}
-JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSValue* v = thisValue->getJSNumber();
+ JSValuePtr v = thisValue.getJSNumber();
if (!v)
return throwError(exec, TypeError);
- double doublePrecision = args.at(exec, 0)->toIntegerPreserveNaN(exec);
- double x = v->uncheckedGetNumber();
- if (args.at(exec, 0)->isUndefined() || isnan(x) || isinf(x))
- return jsString(exec, v->toString(exec));
+ double doublePrecision = args.at(exec, 0).toIntegerPreserveNaN(exec);
+ double x = v.uncheckedGetNumber();
+ if (args.at(exec, 0).isUndefined() || isnan(x) || isinf(x))
+ return jsString(exec, v.toString(exec));
UString s;
if (x < 0) {
diff --git a/JavaScriptCore/runtime/NumberPrototype.h b/JavaScriptCore/runtime/NumberPrototype.h
index d70f260..0a3a544 100644
--- a/JavaScriptCore/runtime/NumberPrototype.h
+++ b/JavaScriptCore/runtime/NumberPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class NumberPrototype : public NumberObject {
public:
- NumberPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
+ NumberPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
};
} // namespace JSC
diff --git a/JavaScriptCore/runtime/ObjectConstructor.cpp b/JavaScriptCore/runtime/ObjectConstructor.cpp
index 329816f..2d61127 100644
--- a/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -28,7 +28,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor);
-ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<StructureID> structure, ObjectPrototype* objectPrototype)
+ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> structure, ObjectPrototype* objectPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, "Object"))
{
// ECMA 15.2.3.1
@@ -41,10 +41,10 @@ ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<StructureID> st
// ECMA 15.2.2
static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args)
{
- JSValue* arg = args.at(exec, 0);
- if (arg->isUndefinedOrNull())
+ JSValuePtr arg = args.at(exec, 0);
+ if (arg.isUndefinedOrNull())
return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
- return arg->toObject(exec);
+ return arg.toObject(exec);
}
static JSObject* constructWithObjectConstructor(ExecState* exec, JSObject*, const ArgList& args)
@@ -58,7 +58,7 @@ ConstructType ObjectConstructor::getConstructData(ConstructData& constructData)
return ConstructTypeHost;
}
-static JSValue* callObjectConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr callObjectConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
return constructObject(exec, args);
}
diff --git a/JavaScriptCore/runtime/ObjectConstructor.h b/JavaScriptCore/runtime/ObjectConstructor.h
index c100424..f8c058a 100644
--- a/JavaScriptCore/runtime/ObjectConstructor.h
+++ b/JavaScriptCore/runtime/ObjectConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class ObjectConstructor : public InternalFunction {
public:
- ObjectConstructor(ExecState*, PassRefPtr<StructureID>, ObjectPrototype*);
+ ObjectConstructor(ExecState*, PassRefPtr<Structure>, ObjectPrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/JavaScriptCore/runtime/ObjectPrototype.cpp b/JavaScriptCore/runtime/ObjectPrototype.cpp
index 42a8063..4b776a7 100644
--- a/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -29,17 +29,17 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype);
-static JSValue* objectProtoFuncValueOf(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* objectProtoFuncHasOwnProperty(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* objectProtoFuncDefineGetter(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* objectProtoFuncDefineSetter(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* objectProtoFuncLookupGetter(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
-
-ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<StructureID> stucture, StructureID* prototypeFunctionStructure)
+static JSValuePtr objectProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr objectProtoFuncHasOwnProperty(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr objectProtoFuncDefineGetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr objectProtoFuncDefineSetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr objectProtoFuncLookupGetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+
+ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<Structure> stucture, Structure* prototypeFunctionStructure)
: JSObject(stucture)
{
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
@@ -60,75 +60,75 @@ ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<StructureID> stuctu
// ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7
-JSValue* objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- return thisValue->toThisObject(exec);
+ return thisValue.toThisObject(exec);
}
-JSValue* objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- return jsBoolean(thisValue->toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args.at(exec, 0)->toString(exec))));
+ return jsBoolean(thisValue.toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args.at(exec, 0).toString(exec))));
}
-JSValue* objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSObject* thisObj = thisValue->toThisObject(exec);
+ JSObject* thisObj = thisValue.toThisObject(exec);
- if (!args.at(exec, 0)->isObject())
+ if (!args.at(exec, 0).isObject())
return jsBoolean(false);
- JSValue* v = asObject(args.at(exec, 0))->prototype();
+ JSValuePtr v = asObject(args.at(exec, 0))->prototype();
while (true) {
- if (!v->isObject())
+ if (!v.isObject())
return jsBoolean(false);
- if (thisObj == v)
+ if (v == thisObj)
return jsBoolean(true);
v = asObject(v)->prototype();
}
}
-JSValue* objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
CallData callData;
- if (args.at(exec, 1)->getCallData(callData) == CallTypeNone)
+ if (args.at(exec, 1).getCallData(callData) == CallTypeNone)
return throwError(exec, SyntaxError, "invalid getter usage");
- thisValue->toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)), asObject(args.at(exec, 1)));
+ thisValue.toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)), asObject(args.at(exec, 1)));
return jsUndefined();
}
-JSValue* objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
CallData callData;
- if (args.at(exec, 1)->getCallData(callData) == CallTypeNone)
+ if (args.at(exec, 1).getCallData(callData) == CallTypeNone)
return throwError(exec, SyntaxError, "invalid setter usage");
- thisValue->toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)), asObject(args.at(exec, 1)));
+ thisValue.toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)), asObject(args.at(exec, 1)));
return jsUndefined();
}
-JSValue* objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- return thisValue->toThisObject(exec)->lookupGetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)));
+ return thisValue.toThisObject(exec)->lookupGetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)));
}
-JSValue* objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- return thisValue->toThisObject(exec)->lookupSetter(exec, Identifier(exec, args.at(exec, 0)->toString(exec)));
+ return thisValue.toThisObject(exec)->lookupSetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)));
}
-JSValue* objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- return jsBoolean(thisValue->toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args.at(exec, 0)->toString(exec))));
+ return jsBoolean(thisValue.toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args.at(exec, 0).toString(exec))));
}
-JSValue* objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- return thisValue->toThisJSString(exec);
+ return thisValue.toThisJSString(exec);
}
-JSValue* objectProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr objectProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- return jsNontrivialString(exec, "[object " + thisValue->toThisObject(exec)->className() + "]");
+ return jsNontrivialString(exec, "[object " + thisValue.toThisObject(exec)->className() + "]");
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/ObjectPrototype.h b/JavaScriptCore/runtime/ObjectPrototype.h
index aefdf95..1c432fe 100644
--- a/JavaScriptCore/runtime/ObjectPrototype.h
+++ b/JavaScriptCore/runtime/ObjectPrototype.h
@@ -27,10 +27,10 @@ namespace JSC {
class ObjectPrototype : public JSObject {
public:
- ObjectPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
+ ObjectPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
};
- JSValue* objectProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+ JSValuePtr objectProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
} // namespace JSC
diff --git a/JavaScriptCore/kjs/operations.cpp b/JavaScriptCore/runtime/Operations.cpp
index f2d8deb..550d3f6 100644
--- a/JavaScriptCore/kjs/operations.cpp
+++ b/JavaScriptCore/runtime/Operations.cpp
@@ -20,7 +20,7 @@
*/
#include "config.h"
-#include "operations.h"
+#include "Operations.h"
#include "Error.h"
#include "JSObject.h"
@@ -35,37 +35,17 @@
namespace JSC {
-// ECMA 11.9.3
-bool equal(ExecState* exec, JSValue* v1, JSValue* v2)
-{
- if (JSImmediate::areBothImmediateNumbers(v1, v2))
- return v1 == v2;
-
- return equalSlowCaseInline(exec, v1, v2);
-}
-
-bool equalSlowCase(ExecState* exec, JSValue* v1, JSValue* v2)
+bool JSValuePtr::equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
{
return equalSlowCaseInline(exec, v1, v2);
}
-bool strictEqual(JSValue* v1, JSValue* v2)
-{
- if (JSImmediate::areBothImmediate(v1, v2))
- return v1 == v2;
-
- if (JSImmediate::isEitherImmediate(v1, v2) & (v1 != JSImmediate::from(0)) & (v2 != JSImmediate::from(0)))
- return false;
-
- return strictEqualSlowCaseInline(v1, v2);
-}
-
-bool strictEqualSlowCase(JSValue* v1, JSValue* v2)
+bool JSValuePtr::strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2)
{
return strictEqualSlowCaseInline(v1, v2);
}
-NEVER_INLINE JSValue* throwOutOfMemoryError(ExecState* exec)
+NEVER_INLINE JSValuePtr throwOutOfMemoryError(ExecState* exec)
{
JSObject* error = Error::create(exec, GeneralError, "Out of memory");
exec->setException(error);
diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h
new file mode 100644
index 0000000..c6a7e7a
--- /dev/null
+++ b/JavaScriptCore/runtime/Operations.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 Operations_h
+#define Operations_h
+
+#include "JSImmediate.h"
+#include "JSNumberCell.h"
+#include "JSString.h"
+
+namespace JSC {
+
+ // ECMA 11.9.3
+ inline bool JSValuePtr::equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
+ {
+ if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+ return v1 == v2;
+
+ return equalSlowCase(exec, v1, v2);
+ }
+
+ ALWAYS_INLINE bool JSValuePtr::equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
+ {
+ ASSERT(!JSImmediate::areBothImmediateIntegerNumbers(v1, v2));
+
+ do {
+ if (v1.isNumber() && v2.isNumber())
+ return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
+
+ bool s1 = v1.isString();
+ bool s2 = v2.isString();
+ if (s1 && s2)
+ return asString(v1)->value() == asString(v2)->value();
+
+ if (v1.isUndefinedOrNull()) {
+ if (v2.isUndefinedOrNull())
+ return true;
+ if (JSImmediate::isImmediate(v2))
+ return false;
+ return v2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
+ }
+
+ if (v2.isUndefinedOrNull()) {
+ if (JSImmediate::isImmediate(v1))
+ return false;
+ return v1.asCell()->structure()->typeInfo().masqueradesAsUndefined();
+ }
+
+ if (v1.isObject()) {
+ if (v2.isObject())
+ return v1 == v2;
+ JSValuePtr p1 = v1.toPrimitive(exec);
+ if (exec->hadException())
+ return false;
+ v1 = p1;
+ if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+ return v1 == v2;
+ continue;
+ }
+
+ if (v2.isObject()) {
+ JSValuePtr p2 = v2.toPrimitive(exec);
+ if (exec->hadException())
+ return false;
+ v2 = p2;
+ if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+ return v1 == v2;
+ continue;
+ }
+
+ if (s1 || s2) {
+ double d1 = v1.toNumber(exec);
+ double d2 = v2.toNumber(exec);
+ return d1 == d2;
+ }
+
+ if (v1.isBoolean()) {
+ if (v2.isNumber())
+ return static_cast<double>(v1.getBoolean()) == v2.uncheckedGetNumber();
+ } else if (v2.isBoolean()) {
+ if (v1.isNumber())
+ return v1.uncheckedGetNumber() == static_cast<double>(v2.getBoolean());
+ }
+
+ return v1 == v2;
+ } while (true);
+ }
+
+ // ECMA 11.9.3
+ inline bool JSValuePtr::strictEqual(JSValuePtr v1, JSValuePtr v2)
+ {
+ if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+ return v1 == v2;
+
+ if (v1.isNumber() && v2.isNumber())
+ return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
+
+ if (JSImmediate::isEitherImmediate(v1, v2))
+ return v1 == v2;
+
+ return strictEqualSlowCase(v1, v2);
+ }
+
+ ALWAYS_INLINE bool JSValuePtr::strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2)
+ {
+ ASSERT(!JSImmediate::isEitherImmediate(v1, v2));
+
+ if (v1.asCell()->isString() && v2.asCell()->isString())
+ return asString(v1)->value() == asString(v2)->value();
+
+ return v1 == v2;
+ }
+
+ JSValuePtr throwOutOfMemoryError(ExecState*);
+
+}
+#endif
diff --git a/JavaScriptCore/runtime/PropertyMapHashTable.h b/JavaScriptCore/runtime/PropertyMapHashTable.h
index 98b0727..935df68 100644
--- a/JavaScriptCore/runtime/PropertyMapHashTable.h
+++ b/JavaScriptCore/runtime/PropertyMapHashTable.h
@@ -21,7 +21,8 @@
#ifndef PropertyMapHashTable_h
#define PropertyMapHashTable_h
-#include "ustring.h"
+#include "UString.h"
+#include <wtf/Vector.h>
namespace JSC {
@@ -31,13 +32,21 @@ namespace JSC {
unsigned attributes;
unsigned index;
- PropertyMapEntry(UString::Rep* k, int a)
- : key(k)
+ PropertyMapEntry(UString::Rep* key, unsigned attributes)
+ : key(key)
, offset(0)
- , attributes(a)
+ , attributes(attributes)
, index(0)
{
}
+
+ PropertyMapEntry(UString::Rep* key, unsigned offset, unsigned attributes, unsigned index)
+ : key(key)
+ , offset(offset)
+ , attributes(attributes)
+ , index(index)
+ {
+ }
};
// lastIndexUsed is an ever-increasing index used to identify the order items
@@ -50,6 +59,7 @@ namespace JSC {
unsigned keyCount;
unsigned deletedSentinelCount;
unsigned lastIndexUsed;
+ Vector<unsigned>* deletedOffsets;
unsigned entryIndices[1];
PropertyMapEntry* entries()
diff --git a/JavaScriptCore/runtime/PropertyNameArray.cpp b/JavaScriptCore/runtime/PropertyNameArray.cpp
index 47e9d84..0878e73 100644
--- a/JavaScriptCore/runtime/PropertyNameArray.cpp
+++ b/JavaScriptCore/runtime/PropertyNameArray.cpp
@@ -27,7 +27,7 @@ static const size_t setThreshold = 20;
void PropertyNameArray::add(UString::Rep* identifier)
{
- ASSERT(identifier == &UString::Rep::null || identifier == &UString::Rep::empty || identifier->identifierTable());
+ ASSERT(identifier == &UString::Rep::null() || identifier == &UString::Rep::empty() || identifier->identifierTable());
size_t size = m_data->propertyNameVector().size();
if (size < setThreshold) {
diff --git a/JavaScriptCore/runtime/PropertyNameArray.h b/JavaScriptCore/runtime/PropertyNameArray.h
index d19c2e5..7dc14fe 100644
--- a/JavaScriptCore/runtime/PropertyNameArray.h
+++ b/JavaScriptCore/runtime/PropertyNameArray.h
@@ -21,9 +21,9 @@
#ifndef PropertyNameArray_h
#define PropertyNameArray_h
-#include "ExecState.h"
-#include "StructureID.h"
-#include "identifier.h"
+#include "CallFrame.h"
+#include "Identifier.h"
+#include "Structure.h"
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
@@ -41,21 +41,21 @@ namespace JSC {
PropertyNameVector& propertyNameVector() { return m_propertyNameVector; }
- void setCachedStructureID(StructureID* structureID) { m_cachedStructureID = structureID; }
- StructureID* cachedStructureID() const { return m_cachedStructureID; }
+ void setCachedStructure(Structure* structure) { m_cachedStructure = structure; }
+ Structure* cachedStructure() const { return m_cachedStructure; }
- void setCachedPrototypeChain(PassRefPtr<StructureIDChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
- StructureIDChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
+ void setCachedPrototypeChain(PassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
+ StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
private:
PropertyNameArrayData()
- : m_cachedStructureID(0)
+ : m_cachedStructure(0)
{
}
PropertyNameVector m_propertyNameVector;
- StructureID* m_cachedStructureID;
- RefPtr<StructureIDChain> m_cachedPrototypeChain;
+ Structure* m_cachedStructure;
+ RefPtr<StructureChain> m_cachedPrototypeChain;
};
class PropertyNameArray {
diff --git a/JavaScriptCore/runtime/PropertySlot.cpp b/JavaScriptCore/runtime/PropertySlot.cpp
index 37df83a..175f271 100644
--- a/JavaScriptCore/runtime/PropertySlot.cpp
+++ b/JavaScriptCore/runtime/PropertySlot.cpp
@@ -27,7 +27,7 @@
namespace JSC {
-JSValue* PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
// Prevent getter functions from observing execution if an exception is pending.
if (exec->hadException())
diff --git a/JavaScriptCore/runtime/PropertySlot.h b/JavaScriptCore/runtime/PropertySlot.h
index 29c19d4..1dd1afa 100644
--- a/JavaScriptCore/runtime/PropertySlot.h
+++ b/JavaScriptCore/runtime/PropertySlot.h
@@ -21,9 +21,10 @@
#ifndef PropertySlot_h
#define PropertySlot_h
-#include "Register.h"
+#include "Identifier.h"
#include "JSValue.h"
-#include "identifier.h"
+#include "JSImmediate.h"
+#include "Register.h"
#include <wtf/Assertions.h>
#include <wtf/NotFound.h>
@@ -44,16 +45,16 @@ namespace JSC {
clearValue();
}
- explicit PropertySlot(const JSValue* base)
- : m_slotBase(const_cast<JSValue*>(base))
+ explicit PropertySlot(const JSValuePtr base)
+ : m_slotBase(base)
, m_offset(WTF::notFound)
{
clearValue();
}
- typedef JSValue* (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
+ typedef JSValuePtr (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
- JSValue* getValue(ExecState* exec, const Identifier& propertyName) const
+ JSValuePtr getValue(ExecState* exec, const Identifier& propertyName) const
{
if (m_getValue == JSC_VALUE_SLOT_MARKER)
return *m_data.valueSlot;
@@ -62,7 +63,7 @@ namespace JSC {
return m_getValue(exec, propertyName, *this);
}
- JSValue* getValue(ExecState* exec, unsigned propertyName) const
+ JSValuePtr getValue(ExecState* exec, unsigned propertyName) const
{
if (m_getValue == JSC_VALUE_SLOT_MARKER)
return *m_data.valueSlot;
@@ -78,17 +79,17 @@ namespace JSC {
return m_offset;
}
- void putValue(JSValue* value)
+ void putValue(JSValuePtr value)
{
if (m_getValue == JSC_VALUE_SLOT_MARKER) {
*m_data.valueSlot = value;
return;
}
ASSERT(m_getValue == JSC_REGISTER_SLOT_MARKER);
- *m_data.registerSlot = value;
+ *m_data.registerSlot = JSValuePtr(value);
}
- void setValueSlot(JSValue** valueSlot)
+ void setValueSlot(JSValuePtr* valueSlot)
{
ASSERT(valueSlot);
m_getValue = JSC_VALUE_SLOT_MARKER;
@@ -96,7 +97,7 @@ namespace JSC {
m_data.valueSlot = valueSlot;
}
- void setValueSlot(JSValue* slotBase, JSValue** valueSlot)
+ void setValueSlot(JSValuePtr slotBase, JSValuePtr* valueSlot)
{
ASSERT(valueSlot);
m_getValue = JSC_VALUE_SLOT_MARKER;
@@ -104,7 +105,7 @@ namespace JSC {
m_data.valueSlot = valueSlot;
}
- void setValueSlot(JSValue* slotBase, JSValue** valueSlot, size_t offset)
+ void setValueSlot(JSValuePtr slotBase, JSValuePtr* valueSlot, size_t offset)
{
ASSERT(valueSlot);
m_getValue = JSC_VALUE_SLOT_MARKER;
@@ -113,7 +114,7 @@ namespace JSC {
m_offset = offset;
}
- void setValue(JSValue* value)
+ void setValue(JSValuePtr value)
{
ASSERT(value);
m_getValue = JSC_VALUE_SLOT_MARKER;
@@ -130,7 +131,7 @@ namespace JSC {
m_data.registerSlot = registerSlot;
}
- void setCustom(JSValue* slotBase, GetValueFunc getValue)
+ void setCustom(JSValuePtr slotBase, GetValueFunc getValue)
{
ASSERT(slotBase);
ASSERT(getValue);
@@ -138,7 +139,7 @@ namespace JSC {
m_slotBase = slotBase;
}
- void setCustomIndex(JSValue* slotBase, unsigned index, GetValueFunc getValue)
+ void setCustomIndex(JSValuePtr slotBase, unsigned index, GetValueFunc getValue)
{
ASSERT(slotBase);
ASSERT(getValue);
@@ -160,13 +161,13 @@ namespace JSC {
setValue(jsUndefined());
}
- JSValue* slotBase() const
+ JSValuePtr slotBase() const
{
ASSERT(m_slotBase);
return m_slotBase;
}
- void setBase(JSValue* base)
+ void setBase(JSValuePtr base)
{
ASSERT(m_slotBase);
ASSERT(base);
@@ -190,19 +191,19 @@ namespace JSC {
unsigned index() const { return m_data.index; }
private:
- static JSValue* functionGetter(ExecState*, const Identifier&, const PropertySlot&);
+ static JSValuePtr functionGetter(ExecState*, const Identifier&, const PropertySlot&);
GetValueFunc m_getValue;
- JSValue* m_slotBase;
+ JSValuePtr m_slotBase;
union {
JSObject* getterFunc;
- JSValue** valueSlot;
+ JSValuePtr* valueSlot;
Register* registerSlot;
unsigned index;
} m_data;
- JSValue* m_value;
+ JSValuePtr m_value;
size_t m_offset;
};
diff --git a/JavaScriptCore/runtime/Protect.h b/JavaScriptCore/runtime/Protect.h
new file mode 100644
index 0000000..c7f6b2d
--- /dev/null
+++ b/JavaScriptCore/runtime/Protect.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2004, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 Protect_h
+#define Protect_h
+
+#include "JSCell.h"
+#include "Collector.h"
+
+namespace JSC {
+
+ inline void gcProtect(JSCell* val)
+ {
+ Heap::heap(val)->protect(val);
+ }
+
+ inline void gcUnprotect(JSCell* val)
+ {
+ Heap::heap(val)->unprotect(val);
+ }
+
+ inline void gcProtectNullTolerant(JSCell* val)
+ {
+ if (val)
+ gcProtect(val);
+ }
+
+ inline void gcUnprotectNullTolerant(JSCell* val)
+ {
+ if (val)
+ gcUnprotect(val);
+ }
+
+ inline void gcProtect(JSValuePtr value)
+ {
+ if (value && value.isCell())
+ gcProtect(asCell(value));
+ }
+
+ inline void gcUnprotect(JSValuePtr value)
+ {
+ if (value && value.isCell())
+ gcUnprotect(asCell(value));
+ }
+
+ // FIXME: Share more code with RefPtr template? The only differences are the ref/deref operation
+ // and the implicit conversion to raw pointer
+ template <class T> class ProtectedPtr {
+ public:
+ ProtectedPtr() : m_ptr(0) {}
+ ProtectedPtr(T* ptr);
+ ProtectedPtr(const ProtectedPtr&);
+ ~ProtectedPtr();
+
+ template <class U> ProtectedPtr(const ProtectedPtr<U>&);
+
+ T* get() const { return m_ptr; }
+ operator T*() const { return m_ptr; }
+ operator JSValuePtr() const { return JSValuePtr(m_ptr); }
+ T* operator->() const { return m_ptr; }
+
+ operator bool() const { return m_ptr; }
+ bool operator!() const { return !m_ptr; }
+
+ ProtectedPtr& operator=(const ProtectedPtr&);
+ ProtectedPtr& operator=(T*);
+
+ private:
+ T* m_ptr;
+ };
+
+ class ProtectedJSValuePtr {
+ public:
+ ProtectedJSValuePtr() {}
+ ProtectedJSValuePtr(JSValuePtr value);
+ ProtectedJSValuePtr(const ProtectedJSValuePtr&);
+ ~ProtectedJSValuePtr();
+
+ template <class U> ProtectedJSValuePtr(const ProtectedPtr<U>&);
+
+ JSValuePtr get() const { return m_value; }
+ operator JSValuePtr() const { return m_value; }
+ JSValuePtr operator->() const { return m_value; }
+
+ operator bool() const { return m_value; }
+ bool operator!() const { return !m_value; }
+
+ ProtectedJSValuePtr& operator=(const ProtectedJSValuePtr&);
+ ProtectedJSValuePtr& operator=(JSValuePtr);
+
+ private:
+ JSValuePtr m_value;
+ };
+
+ template <class T> inline ProtectedPtr<T>::ProtectedPtr(T* ptr)
+ : m_ptr(ptr)
+ {
+ gcProtectNullTolerant(m_ptr);
+ }
+
+ template <class T> inline ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr& o)
+ : m_ptr(o.get())
+ {
+ gcProtectNullTolerant(m_ptr);
+ }
+
+ template <class T> inline ProtectedPtr<T>::~ProtectedPtr()
+ {
+ gcUnprotectNullTolerant(m_ptr);
+ }
+
+ template <class T> template <class U> inline ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U>& o)
+ : m_ptr(o.get())
+ {
+ gcProtectNullTolerant(m_ptr);
+ }
+
+ template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(const ProtectedPtr<T>& o)
+ {
+ T* optr = o.m_ptr;
+ gcProtectNullTolerant(optr);
+ gcUnprotectNullTolerant(m_ptr);
+ m_ptr = optr;
+ return *this;
+ }
+
+ template <class T> inline ProtectedPtr<T>& ProtectedPtr<T>::operator=(T* optr)
+ {
+ gcProtectNullTolerant(optr);
+ gcUnprotectNullTolerant(m_ptr);
+ m_ptr = optr;
+ return *this;
+ }
+
+ inline ProtectedJSValuePtr::ProtectedJSValuePtr(JSValuePtr value)
+ : m_value(value)
+ {
+ gcProtect(m_value);
+ }
+
+ inline ProtectedJSValuePtr::ProtectedJSValuePtr(const ProtectedJSValuePtr& o)
+ : m_value(o.get())
+ {
+ gcProtect(m_value);
+ }
+
+ inline ProtectedJSValuePtr::~ProtectedJSValuePtr()
+ {
+ gcUnprotect(m_value);
+ }
+
+ template <class U> ProtectedJSValuePtr::ProtectedJSValuePtr(const ProtectedPtr<U>& o)
+ : m_value(o.get())
+ {
+ gcProtect(m_value);
+ }
+
+ inline ProtectedJSValuePtr& ProtectedJSValuePtr::operator=(const ProtectedJSValuePtr& o)
+ {
+ JSValuePtr ovalue = o.m_value;
+ gcProtect(ovalue);
+ gcUnprotect(m_value);
+ m_value = ovalue;
+ return *this;
+ }
+
+ inline ProtectedJSValuePtr& ProtectedJSValuePtr::operator=(JSValuePtr ovalue)
+ {
+ gcProtect(ovalue);
+ gcUnprotect(m_value);
+ m_value = ovalue;
+ return *this;
+ }
+
+ template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() == b.get(); }
+ template <class T> inline bool operator==(const ProtectedPtr<T>& a, const T* b) { return a.get() == b; }
+ template <class T> inline bool operator==(const T* a, const ProtectedPtr<T>& b) { return a == b.get(); }
+
+ template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedPtr<T>& b) { return a.get() != b.get(); }
+ template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const T* b) { return a.get() != b; }
+ template <class T> inline bool operator!=(const T* a, const ProtectedPtr<T>& b) { return a != b.get(); }
+
+ inline bool operator==(const ProtectedJSValuePtr& a, const ProtectedJSValuePtr& b) { return a.get() == b.get(); }
+ inline bool operator==(const ProtectedJSValuePtr& a, const JSValuePtr b) { return a.get() == b; }
+ template <class T> inline bool operator==(const ProtectedJSValuePtr& a, const ProtectedPtr<T>& b) { return a.get() == JSValuePtr(b.get()); }
+ inline bool operator==(const JSValuePtr a, const ProtectedJSValuePtr& b) { return a == b.get(); }
+ template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedJSValuePtr& b) { return JSValuePtr(a.get()) == b.get(); }
+
+ inline bool operator!=(const ProtectedJSValuePtr& a, const ProtectedJSValuePtr& b) { return a.get() != b.get(); }
+ inline bool operator!=(const ProtectedJSValuePtr& a, const JSValuePtr b) { return a.get() != b; }
+ template <class T> inline bool operator!=(const ProtectedJSValuePtr& a, const ProtectedPtr<T>& b) { return a.get() != JSValuePtr(b.get()); }
+ inline bool operator!=(const JSValuePtr a, const ProtectedJSValuePtr& b) { return a != b.get(); }
+ template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedJSValuePtr& b) { return JSValuePtr(a.get()) != b.get(); }
+
+} // namespace JSC
+
+#endif // Protect_h
diff --git a/JavaScriptCore/runtime/PrototypeFunction.cpp b/JavaScriptCore/runtime/PrototypeFunction.cpp
index 8afe6a4..8e3d107 100644
--- a/JavaScriptCore/runtime/PrototypeFunction.cpp
+++ b/JavaScriptCore/runtime/PrototypeFunction.cpp
@@ -40,7 +40,7 @@ PrototypeFunction::PrototypeFunction(ExecState* exec, int length, const Identifi
putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
}
-PrototypeFunction::PrototypeFunction(ExecState* exec, PassRefPtr<StructureID> prototypeFunctionStructure, int length, const Identifier& name, NativeFunction function)
+PrototypeFunction::PrototypeFunction(ExecState* exec, PassRefPtr<Structure> prototypeFunctionStructure, int length, const Identifier& name, NativeFunction function)
: InternalFunction(&exec->globalData(), prototypeFunctionStructure, name)
, m_function(function)
{
diff --git a/JavaScriptCore/runtime/PrototypeFunction.h b/JavaScriptCore/runtime/PrototypeFunction.h
index 1592995..99ab327 100644
--- a/JavaScriptCore/runtime/PrototypeFunction.h
+++ b/JavaScriptCore/runtime/PrototypeFunction.h
@@ -32,7 +32,7 @@ namespace JSC {
class PrototypeFunction : public InternalFunction {
public:
PrototypeFunction(ExecState*, int length, const Identifier&, NativeFunction);
- PrototypeFunction(ExecState*, PassRefPtr<StructureID>, int length, const Identifier&, NativeFunction);
+ PrototypeFunction(ExecState*, PassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
private:
virtual CallType getCallData(CallData&);
diff --git a/JavaScriptCore/kjs/regexp.cpp b/JavaScriptCore/runtime/RegExp.cpp
index 7397232..b8251d2 100644
--- a/JavaScriptCore/kjs/regexp.cpp
+++ b/JavaScriptCore/runtime/RegExp.cpp
@@ -19,20 +19,24 @@
*/
#include "config.h"
-#include "regexp.h"
+#include "RegExp.h"
-#include "CTI.h"
-#include "lexer.h"
+#include "JIT.h"
+#include "Lexer.h"
+#include "WRECGenerator.h"
#include <pcre/pcre.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <wrec/WREC.h>
#include <wtf/Assertions.h>
#include <wtf/OwnArrayPtr.h>
namespace JSC {
+#if ENABLE(WREC)
+using namespace WREC;
+#endif
+
inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
: m_pattern(pattern)
, m_flagBits(0)
@@ -41,8 +45,8 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
, m_numSubpatterns(0)
{
#if ENABLE(WREC)
- m_wrecFunction = CTI::compileRegExp(globalData->machine, pattern, &m_numSubpatterns, &m_constructionError);
- if (m_wrecFunction)
+ m_wrecFunction = Generator::compileRegExp(globalData, pattern, &m_numSubpatterns, &m_constructionError, m_executablePool);
+ if (m_wrecFunction || m_constructionError)
return;
// Fall through to non-WREC case.
#else
@@ -84,8 +88,8 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const US
}
#if ENABLE(WREC)
- m_wrecFunction = CTI::compileRegExp(globalData->machine, pattern, &m_numSubpatterns, &m_constructionError, (m_flagBits & IgnoreCase), (m_flagBits & Multiline));
- if (m_wrecFunction)
+ m_wrecFunction = Generator::compileRegExp(globalData, pattern, &m_numSubpatterns, &m_constructionError, m_executablePool, (m_flagBits & IgnoreCase), (m_flagBits & Multiline));
+ if (m_wrecFunction || m_constructionError)
return;
// Fall through to non-WREC case.
#else
@@ -103,20 +107,16 @@ PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patte
RegExp::~RegExp()
{
jsRegExpFree(m_regExp);
-#if ENABLE(WREC)
- if (m_wrecFunction)
- WTF::fastFreeExecutable(m_wrecFunction);
-#endif
}
-int RegExp::match(const UString& s, int i, OwnArrayPtr<int>* ovector)
+int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
{
- if (i < 0)
- i = 0;
+ if (startOffset < 0)
+ startOffset = 0;
if (ovector)
ovector->clear();
- if (i > s.size() || s.isNull())
+ if (startOffset > s.size() || s.isNull())
return -1;
#if ENABLE(WREC)
@@ -132,7 +132,7 @@ int RegExp::match(const UString& s, int i, OwnArrayPtr<int>* ovector)
else
ovector->set(offsetVector);
- int result = reinterpret_cast<WRECFunction>(m_wrecFunction)(s.data(), i, s.size(), offsetVector);
+ int result = m_wrecFunction(s.data(), startOffset, s.size(), offsetVector);
if (result < 0) {
#ifndef NDEBUG
@@ -161,7 +161,7 @@ int RegExp::match(const UString& s, int i, OwnArrayPtr<int>* ovector)
ovector->set(offsetVector);
}
- int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.data()), s.size(), i, offsetVector, offsetVectorSize);
+ int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.data()), s.size(), startOffset, offsetVector, offsetVectorSize);
if (numMatches < 0) {
#ifndef NDEBUG
diff --git a/JavaScriptCore/kjs/regexp.h b/JavaScriptCore/runtime/RegExp.h
index 1842d94..139c754 100644
--- a/JavaScriptCore/kjs/regexp.h
+++ b/JavaScriptCore/runtime/RegExp.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,10 +18,12 @@
*
*/
-#ifndef KJS_REGEXP_H
-#define KJS_REGEXP_H
+#ifndef RegExp_h
+#define RegExp_h
-#include "ustring.h"
+#include "UString.h"
+#include "WREC.h"
+#include "ExecutableAllocator.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
@@ -33,8 +35,8 @@ namespace JSC {
class RegExp : public RefCounted<RegExp> {
public:
- static PassRefPtr<RegExp> create(JSGlobalData*, const UString& pattern);
- static PassRefPtr<RegExp> create(JSGlobalData*, const UString& pattern, const UString& flags);
+ static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern);
+ static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, const UString& flags);
~RegExp();
bool global() const { return m_flagBits & Global; }
@@ -47,12 +49,12 @@ namespace JSC {
bool isValid() const { return !m_constructionError; }
const char* errorMessage() const { return m_constructionError; }
- int match(const UString&, int offset, OwnArrayPtr<int>* ovector = 0);
+ int match(const UString&, int startOffset, OwnArrayPtr<int>* ovector = 0);
unsigned numSubpatterns() const { return m_numSubpatterns; }
private:
- RegExp(JSGlobalData*, const UString& pattern);
- RegExp(JSGlobalData*, const UString& pattern, const UString& flags);
+ RegExp(JSGlobalData* globalData, const UString& pattern);
+ RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags);
void compile();
@@ -66,11 +68,11 @@ namespace JSC {
unsigned m_numSubpatterns;
#if ENABLE(WREC)
- // Called as a WRECFunction
- void* m_wrecFunction;
+ WREC::CompiledRegExp m_wrecFunction;
+ RefPtr<ExecutablePool> m_executablePool;
#endif
};
} // namespace JSC
-#endif // KJS_REGEXP_H
+#endif // RegExp_h
diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp
index 4c4db39..bff51e0 100644
--- a/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -29,28 +29,28 @@
#include "RegExpMatchesArray.h"
#include "RegExpObject.h"
#include "RegExpPrototype.h"
-#include "regexp.h"
+#include "RegExp.h"
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 void setRegExpConstructorInput(ExecState*, JSObject*, JSValue*);
-static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValue*);
+static JSValuePtr regExpConstructorInput(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorLastMatch(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorLastParen(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorLeftContext(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorRightContext(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorDollar1(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorDollar2(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorDollar3(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorDollar4(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorDollar5(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorDollar6(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorDollar7(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorDollar8(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpConstructorDollar9(ExecState*, const Identifier&, const PropertySlot&);
+
+static void setRegExpConstructorInput(ExecState*, JSObject*, JSValuePtr);
+static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValuePtr);
} // namespace JSC
@@ -103,7 +103,7 @@ struct RegExpConstructorPrivate {
bool multiline : 1;
};
-RegExpConstructor::RegExpConstructor(ExecState* exec, PassRefPtr<StructureID> structure, RegExpPrototype* regExpPrototype)
+RegExpConstructor::RegExpConstructor(ExecState* exec, PassRefPtr<Structure> structure, RegExpPrototype* regExpPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, "RegExp"))
, d(new RegExpConstructorPrivate)
{
@@ -185,7 +185,7 @@ JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
return new (exec) RegExpMatchesArray(exec, d.get());
}
-JSValue* RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
+JSValuePtr RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
{
if (d->lastOvector && i <= d->lastNumSubPatterns) {
int start = d->lastOvector[2 * i];
@@ -195,7 +195,7 @@ JSValue* RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
return jsEmptyString(exec);
}
-JSValue* RegExpConstructor::getLastParen(ExecState* exec) const
+JSValuePtr RegExpConstructor::getLastParen(ExecState* exec) const
{
unsigned i = d->lastNumSubPatterns;
if (i > 0) {
@@ -207,14 +207,14 @@ JSValue* RegExpConstructor::getLastParen(ExecState* exec) const
return jsEmptyString(exec);
}
-JSValue* RegExpConstructor::getLeftContext(ExecState* exec) const
+JSValuePtr RegExpConstructor::getLeftContext(ExecState* exec) const
{
if (d->lastOvector)
return jsSubstring(exec, d->lastInput, 0, d->lastOvector[0]);
return jsEmptyString(exec);
}
-JSValue* RegExpConstructor::getRightContext(ExecState* exec) const
+JSValuePtr RegExpConstructor::getRightContext(ExecState* exec) const
{
if (d->lastOvector)
return jsSubstring(exec, d->lastInput, d->lastOvector[1], d->lastInput.size() - d->lastOvector[1]);
@@ -226,110 +226,110 @@ bool RegExpConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr
return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, slot);
}
-JSValue* regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 1);
}
-JSValue* regExpConstructorDollar2(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorDollar2(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 2);
}
-JSValue* regExpConstructorDollar3(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorDollar3(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 3);
}
-JSValue* regExpConstructorDollar4(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorDollar4(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 4);
}
-JSValue* regExpConstructorDollar5(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorDollar5(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 5);
}
-JSValue* regExpConstructorDollar6(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorDollar6(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 6);
}
-JSValue* regExpConstructorDollar7(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorDollar7(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 7);
}
-JSValue* regExpConstructorDollar8(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorDollar8(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 8);
}
-JSValue* regExpConstructorDollar9(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorDollar9(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 9);
}
-JSValue* regExpConstructorInput(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorInput(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return jsString(exec, asRegExpConstructor(slot.slotBase())->input());
}
-JSValue* regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsBoolean(asRegExpConstructor(slot.slotBase())->multiline());
}
-JSValue* regExpConstructorLastMatch(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorLastMatch(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getBackref(exec, 0);
}
-JSValue* regExpConstructorLastParen(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorLastParen(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getLastParen(exec);
}
-JSValue* regExpConstructorLeftContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorLeftContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getLeftContext(exec);
}
-JSValue* regExpConstructorRightContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpConstructorRightContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return asRegExpConstructor(slot.slotBase())->getRightContext(exec);
}
-void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
lookupPut<RegExpConstructor, InternalFunction>(exec, propertyName, value, ExecState::regExpConstructorTable(exec), this, slot);
}
-void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValue* value)
+void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValuePtr value)
{
- asRegExpConstructor(baseObject)->setInput(value->toString(exec));
+ asRegExpConstructor(baseObject)->setInput(value.toString(exec));
}
-void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValue* value)
+void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValuePtr value)
{
- asRegExpConstructor(baseObject)->setMultiline(value->toBoolean(exec));
+ asRegExpConstructor(baseObject)->setMultiline(value.toBoolean(exec));
}
// ECMA 15.10.4
JSObject* constructRegExp(ExecState* exec, const ArgList& args)
{
- JSValue* arg0 = args.at(exec, 0);
- JSValue* arg1 = args.at(exec, 1);
+ JSValuePtr arg0 = args.at(exec, 0);
+ JSValuePtr arg1 = args.at(exec, 1);
- if (arg0->isObject(&RegExpObject::info)) {
- if (!arg1->isUndefined())
+ if (arg0.isObject(&RegExpObject::info)) {
+ if (!arg1.isUndefined())
return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another.");
return asObject(arg0);
}
- UString pattern = arg0->isUndefined() ? UString("") : arg0->toString(exec);
- UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec);
+ UString pattern = arg0.isUndefined() ? UString("") : arg0.toString(exec);
+ UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
RefPtr<RegExp> regExp = RegExp::create(&exec->globalData(), pattern, flags);
if (!regExp->isValid())
@@ -349,7 +349,7 @@ ConstructType RegExpConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.10.3
-static JSValue* callRegExpConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr callRegExpConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
return constructRegExp(exec, args);
}
diff --git a/JavaScriptCore/runtime/RegExpConstructor.h b/JavaScriptCore/runtime/RegExpConstructor.h
index c5a94a5..f8c4366 100644
--- a/JavaScriptCore/runtime/RegExpConstructor.h
+++ b/JavaScriptCore/runtime/RegExpConstructor.h
@@ -32,14 +32,14 @@ namespace JSC {
class RegExpConstructor : public InternalFunction {
public:
- RegExpConstructor(ExecState*, PassRefPtr<StructureID>, RegExpPrototype*);
+ RegExpConstructor(ExecState*, PassRefPtr<Structure>, RegExpPrototype*);
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
+ return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
}
- virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
static const ClassInfo info;
@@ -53,10 +53,10 @@ namespace JSC {
void setMultiline(bool);
bool multiline() const;
- JSValue* getBackref(ExecState*, unsigned) const;
- JSValue* getLastParen(ExecState*) const;
- JSValue* getLeftContext(ExecState*) const;
- JSValue* getRightContext(ExecState*) const;
+ JSValuePtr getBackref(ExecState*, unsigned) const;
+ JSValuePtr getLastParen(ExecState*) const;
+ JSValuePtr getLeftContext(ExecState*) const;
+ JSValuePtr getRightContext(ExecState*) const;
private:
virtual ConstructType getConstructData(ConstructData&);
@@ -67,11 +67,11 @@ namespace JSC {
OwnPtr<RegExpConstructorPrivate> d;
};
- RegExpConstructor* asRegExpConstructor(JSValue*);
+ RegExpConstructor* asRegExpConstructor(JSValuePtr);
JSObject* constructRegExp(ExecState*, const ArgList&);
- inline RegExpConstructor* asRegExpConstructor(JSValue* value)
+ inline RegExpConstructor* asRegExpConstructor(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&RegExpConstructor::info));
return static_cast<RegExpConstructor*>(asObject(value));
diff --git a/JavaScriptCore/runtime/RegExpMatchesArray.h b/JavaScriptCore/runtime/RegExpMatchesArray.h
index 6a4279e..3583941 100644
--- a/JavaScriptCore/runtime/RegExpMatchesArray.h
+++ b/JavaScriptCore/runtime/RegExpMatchesArray.h
@@ -44,14 +44,14 @@ namespace JSC {
return JSArray::getOwnPropertySlot(exec, propertyName, slot);
}
- virtual void put(ExecState* exec, const Identifier& propertyName, JSValue* v, PutPropertySlot& slot)
+ virtual void put(ExecState* exec, const Identifier& propertyName, JSValuePtr v, PutPropertySlot& slot)
{
if (lazyCreationData())
fillArrayInstance(exec);
JSArray::put(exec, propertyName, v, slot);
}
- virtual void put(ExecState* exec, unsigned propertyName, JSValue* v)
+ virtual void put(ExecState* exec, unsigned propertyName, JSValuePtr v)
{
if (lazyCreationData())
fillArrayInstance(exec);
diff --git a/JavaScriptCore/runtime/RegExpObject.cpp b/JavaScriptCore/runtime/RegExpObject.cpp
index 127a71e..f8e0522 100644
--- a/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/JavaScriptCore/runtime/RegExpObject.cpp
@@ -29,12 +29,12 @@
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 void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue*);
+static JSValuePtr regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpObjectSource(ExecState*, const Identifier&, const PropertySlot&);
+static JSValuePtr regExpObjectLastIndex(ExecState*, const Identifier&, const PropertySlot&);
+static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValuePtr);
} // namespace JSC
@@ -56,7 +56,7 @@ const ClassInfo RegExpObject::info = { "RegExp", 0, 0, ExecState::regExpTable };
@end
*/
-RegExpObject::RegExpObject(PassRefPtr<StructureID> structure, PassRefPtr<RegExp> regExp)
+RegExpObject::RegExpObject(PassRefPtr<Structure> structure, PassRefPtr<RegExp> regExp)
: JSObject(structure)
, d(new RegExpObjectData(regExp, 0))
{
@@ -71,91 +71,54 @@ bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propert
return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot);
}
-JSValue* regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->global());
}
-JSValue* regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->ignoreCase());
}
-JSValue* regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
{
return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->multiline());
}
-JSValue* regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return jsString(exec, asRegExpObject(slot.slotBase())->regExp()->pattern());
}
-JSValue* regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValuePtr regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return jsNumber(exec, asRegExpObject(slot.slotBase())->lastIndex());
}
-void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot);
}
-void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue* value)
+void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValuePtr value)
{
- asRegExpObject(baseObject)->setLastIndex(value->toInteger(exec));
+ asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec));
}
-bool RegExpObject::match(ExecState* exec, const ArgList& args)
-{
- RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
-
- UString input;
- if (!args.isEmpty())
- input = args.at(exec, 0)->toString(exec);
- else {
- input = regExpObj->input();
- if (input.isNull()) {
- throwError(exec, GeneralError, "No input.");
- return false;
- }
- }
-
- bool global = get(exec, exec->propertyNames().global)->toBoolean(exec);
- int lastIndex = 0;
- if (global) {
- if (d->lastIndex < 0 || d->lastIndex > input.size()) {
- d->lastIndex = 0;
- return false;
- }
- lastIndex = static_cast<int>(d->lastIndex);
- }
-
- int foundIndex;
- int foundLength;
- regExpObj->performMatch(d->regExp.get(), input, lastIndex, foundIndex, foundLength);
-
- if (global) {
- lastIndex = foundIndex < 0 ? 0 : foundIndex + foundLength;
- d->lastIndex = lastIndex;
- }
-
- return foundIndex >= 0;
-}
-
-JSValue* RegExpObject::test(ExecState* exec, const ArgList& args)
+JSValuePtr RegExpObject::test(ExecState* exec, const ArgList& args)
{
return jsBoolean(match(exec, args));
}
-JSValue* RegExpObject::exec(ExecState* exec, const ArgList& args)
+JSValuePtr RegExpObject::exec(ExecState* exec, const ArgList& args)
{
if (match(exec, args))
return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec);
return jsNull();
}
-static JSValue* callRegExpObject(ExecState* exec, JSObject* function, JSValue*, const ArgList& args)
+static JSValuePtr callRegExpObject(ExecState* exec, JSObject* function, JSValuePtr, const ArgList& args)
{
return asRegExpObject(function)->exec(exec, args);
}
@@ -166,4 +129,39 @@ CallType RegExpObject::getCallData(CallData& callData)
return CallTypeHost;
}
+// Shared implementation used by test and exec.
+bool RegExpObject::match(ExecState* exec, const ArgList& args)
+{
+ RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
+
+ UString input = args.isEmpty() ? regExpConstructor->input() : args.at(exec, 0).toString(exec);
+ if (input.isNull()) {
+ throwError(exec, GeneralError, "No input to " + toString(exec) + ".");
+ return false;
+ }
+
+ if (!regExp()->global()) {
+ int position;
+ int length;
+ regExpConstructor->performMatch(d->regExp.get(), input, 0, position, length);
+ return position >= 0;
+ }
+
+ if (d->lastIndex < 0 || d->lastIndex > input.size()) {
+ d->lastIndex = 0;
+ return false;
+ }
+
+ int position;
+ int length;
+ regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length);
+ if (position < 0) {
+ d->lastIndex = 0;
+ return false;
+ }
+
+ d->lastIndex = position + length;
+ return true;
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExpObject.h b/JavaScriptCore/runtime/RegExpObject.h
index d80b47c..4c99c30 100644
--- a/JavaScriptCore/runtime/RegExpObject.h
+++ b/JavaScriptCore/runtime/RegExpObject.h
@@ -22,13 +22,13 @@
#define RegExpObject_h
#include "JSObject.h"
-#include "regexp.h"
+#include "RegExp.h"
namespace JSC {
class RegExpObject : public JSObject {
public:
- RegExpObject(PassRefPtr<StructureID>, PassRefPtr<RegExp>);
+ RegExpObject(PassRefPtr<Structure>, PassRefPtr<RegExp>);
virtual ~RegExpObject();
void setRegExp(PassRefPtr<RegExp> r) { d->regExp = r; }
@@ -37,18 +37,18 @@ namespace JSC {
void setLastIndex(double lastIndex) { d->lastIndex = lastIndex; }
double lastIndex() const { return d->lastIndex; }
- JSValue* test(ExecState*, const ArgList&);
- JSValue* exec(ExecState*, const ArgList&);
+ JSValuePtr test(ExecState*, const ArgList&);
+ JSValuePtr exec(ExecState*, const ArgList&);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
- virtual void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+ virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType));
}
private:
@@ -70,9 +70,9 @@ namespace JSC {
OwnPtr<RegExpObjectData> d;
};
- RegExpObject* asRegExpObject(JSValue*);
+ RegExpObject* asRegExpObject(JSValuePtr);
- inline RegExpObject* asRegExpObject(JSValue* value)
+ inline RegExpObject* asRegExpObject(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&RegExpObject::info));
return static_cast<RegExpObject*>(asObject(value));
diff --git a/JavaScriptCore/runtime/RegExpPrototype.cpp b/JavaScriptCore/runtime/RegExpPrototype.cpp
index ceee32a..73787bc 100644
--- a/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -29,22 +29,22 @@
#include "ObjectPrototype.h"
#include "PrototypeFunction.h"
#include "RegExpObject.h"
-#include "regexp.h"
+#include "RegExp.h"
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(RegExpPrototype);
-static JSValue* regExpProtoFuncTest(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* regExpProtoFuncExec(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* regExpProtoFuncCompile(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* regExpProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr regExpProtoFuncTest(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr regExpProtoFuncExec(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr regExpProtoFuncCompile(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr regExpProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
// ECMA 15.10.5
const ClassInfo RegExpPrototype::info = { "RegExpPrototype", 0, 0, 0 };
-RegExpPrototype::RegExpPrototype(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure)
+RegExpPrototype::RegExpPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
: JSObject(structure)
{
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
@@ -55,36 +55,36 @@ RegExpPrototype::RegExpPrototype(ExecState* exec, PassRefPtr<StructureID> struct
// ------------------------------ Functions ---------------------------
-JSValue* regExpProtoFuncTest(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr regExpProtoFuncTest(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&RegExpObject::info))
+ if (!thisValue.isObject(&RegExpObject::info))
return throwError(exec, TypeError);
return asRegExpObject(thisValue)->test(exec, args);
}
-JSValue* regExpProtoFuncExec(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr regExpProtoFuncExec(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&RegExpObject::info))
+ if (!thisValue.isObject(&RegExpObject::info))
return throwError(exec, TypeError);
return asRegExpObject(thisValue)->exec(exec, args);
}
-JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- if (!thisValue->isObject(&RegExpObject::info))
+ if (!thisValue.isObject(&RegExpObject::info))
return throwError(exec, TypeError);
RefPtr<RegExp> regExp;
- JSValue* arg0 = args.at(exec, 0);
- JSValue* arg1 = args.at(exec, 1);
+ JSValuePtr arg0 = args.at(exec, 0);
+ JSValuePtr arg1 = args.at(exec, 1);
- if (arg0->isObject(&RegExpObject::info)) {
- if (!arg1->isUndefined())
+ if (arg0.isObject(&RegExpObject::info)) {
+ if (!arg1.isUndefined())
return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another.");
regExp = asRegExpObject(arg0)->regExp();
} else {
- UString pattern = args.isEmpty() ? UString("") : arg0->toString(exec);
- UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec);
+ UString pattern = args.isEmpty() ? UString("") : arg0.toString(exec);
+ UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
regExp = RegExp::create(&exec->globalData(), pattern, flags);
}
@@ -96,21 +96,21 @@ JSValue* regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue* thisValue,
return jsUndefined();
}
-JSValue* regExpProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr regExpProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (!thisValue->isObject(&RegExpObject::info)) {
- if (thisValue->isObject(&RegExpPrototype::info))
+ if (!thisValue.isObject(&RegExpObject::info)) {
+ if (thisValue.isObject(&RegExpPrototype::info))
return jsNontrivialString(exec, "//");
return throwError(exec, TypeError);
}
- UString result = "/" + asRegExpObject(thisValue)->get(exec, exec->propertyNames().source)->toString(exec);
+ UString result = "/" + asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
result.append('/');
- if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global)->toBoolean(exec))
+ if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec))
result.append('g');
- if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec))
+ if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
result.append('i');
- if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline)->toBoolean(exec))
+ if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec))
result.append('m');
return jsNontrivialString(exec, result);
}
diff --git a/JavaScriptCore/runtime/RegExpPrototype.h b/JavaScriptCore/runtime/RegExpPrototype.h
index 44a0f32..f5db720 100644
--- a/JavaScriptCore/runtime/RegExpPrototype.h
+++ b/JavaScriptCore/runtime/RegExpPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class RegExpPrototype : public JSObject {
public:
- RegExpPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
+ RegExpPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
diff --git a/JavaScriptCore/runtime/ScopeChain.cpp b/JavaScriptCore/runtime/ScopeChain.cpp
index e90b565..5c2edab 100644
--- a/JavaScriptCore/runtime/ScopeChain.cpp
+++ b/JavaScriptCore/runtime/ScopeChain.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "ScopeChain.h"
+#include "JSActivation.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
#include "PropertyNameArray.h"
@@ -50,4 +51,18 @@ void ScopeChainNode::print() const
#endif
+int ScopeChain::localDepth() const
+{
+ int scopeDepth = 0;
+ ScopeChainIterator iter = this->begin();
+ ScopeChainIterator end = this->end();
+ while (!(*iter)->isObject(&JSActivation::info)) {
+ ++iter;
+ if (iter == end)
+ break;
+ ++scopeDepth;
+ }
+ return scopeDepth;
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/ScopeChain.h b/JavaScriptCore/runtime/ScopeChain.h
index 834217c..32b5e92 100644
--- a/JavaScriptCore/runtime/ScopeChain.h
+++ b/JavaScriptCore/runtime/ScopeChain.h
@@ -48,8 +48,8 @@ namespace JSC {
JSObject* globalThis;
int refCount;
- void deref() { if (--refCount == 0) release(); }
- void ref() { ++refCount; }
+ void deref() { ASSERT(refCount); if (--refCount == 0) { release();} }
+ void ref() { ASSERT(refCount); ++refCount; }
void release();
// Before calling "push" on a bare ScopeChainNode, a client should
@@ -143,7 +143,7 @@ namespace JSC {
class NoScopeChain {};
class ScopeChain {
- friend class CTI;
+ friend class JIT;
public:
ScopeChain(NoScopeChain)
: m_node(0)
@@ -191,6 +191,13 @@ namespace JSC {
void mark() const;
+ // Caution: this should only be used if the codeblock this is being used
+ // with needs a full scope chain, otherwise this returns the depth of
+ // the preceeding call frame
+ //
+ // Returns the depth of the current call frame's scope chain
+ int localDepth() const;
+
#ifndef NDEBUG
void print() const { m_node->print(); }
#endif
diff --git a/JavaScriptCore/runtime/SmallStrings.cpp b/JavaScriptCore/runtime/SmallStrings.cpp
index 06811b9..6c73df2 100644
--- a/JavaScriptCore/runtime/SmallStrings.cpp
+++ b/JavaScriptCore/runtime/SmallStrings.cpp
@@ -29,48 +29,60 @@
#include "JSGlobalObject.h"
#include "JSString.h"
+#include <wtf/Noncopyable.h>
+
namespace JSC {
+static const unsigned numCharactersToStore = 0x100;
-class SmallStringsStorage {
+class SmallStringsStorage : Noncopyable {
public:
SmallStringsStorage();
- ~SmallStringsStorage();
- UString::Rep* rep(unsigned char character) { return &reps[character]; }
+ UString::Rep* rep(unsigned char character) { return &m_reps[character]; }
private:
- UChar characters[0x100];
- UString::Rep* reps;
+ UChar m_characters[numCharactersToStore];
+ UString::BaseString m_base;
+ UString::Rep m_reps[numCharactersToStore];
};
SmallStringsStorage::SmallStringsStorage()
- : reps(static_cast<UString::Rep*>(fastZeroedMalloc(sizeof(UString::Rep) * 0x100)))
{
- for (unsigned i = 0; i < 0x100; ++i) {
- characters[i] = i;
- reps[i].offset = i;
- reps[i].len = 1;
- reps[i].rc = 1;
- reps[i].baseString = &reps[0];
- }
- reps[0].rc = 0x101;
- reps[0].buf = characters;
+ for (unsigned i = 0; i < numCharactersToStore; ++i)
+ m_characters[i] = i;
+
+ m_base.rc = numCharactersToStore + 1;
+ m_base.buf = m_characters;
+ m_base.len = numCharactersToStore;
+ m_base.offset = 0;
+ m_base._hash = 0;
+ m_base.m_baseString = 0;
+ m_base.preCapacity = 0;
+ m_base.usedPreCapacity = 0;
+ m_base.reportedCost = 0;
// make sure UString doesn't try to reuse the buffer by pretending we have one more character in it
- reps[0].usedCapacity = 0x101;
- reps[0].capacity = 0x101;
-}
+ m_base.usedCapacity = numCharactersToStore + 1;
+ m_base.capacity = numCharactersToStore + 1;
+ m_base.checkConsistency();
-SmallStringsStorage::~SmallStringsStorage()
-{
- fastFree(reps);
+ memset(&m_reps, 0, sizeof(m_reps));
+ for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ m_reps[i].offset = i;
+ m_reps[i].len = 1;
+ m_reps[i].rc = 1;
+ m_reps[i].setBaseString(&m_base);
+ m_reps[i].checkConsistency();
+ }
}
SmallStrings::SmallStrings()
: m_emptyString(0)
, m_storage(0)
{
- for (unsigned i = 0; i < 0x100; ++i)
+ COMPILE_ASSERT(numCharactersToStore == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
+
+ for (unsigned i = 0; i < numCharactersToStore; ++i)
m_singleCharacterStrings[i] = 0;
}
@@ -82,12 +94,24 @@ void SmallStrings::mark()
{
if (m_emptyString && !m_emptyString->marked())
m_emptyString->mark();
- for (unsigned i = 0; i < 0x100; ++i) {
+ for (unsigned i = 0; i < numCharactersToStore; ++i) {
if (m_singleCharacterStrings[i] && !m_singleCharacterStrings[i]->marked())
m_singleCharacterStrings[i]->mark();
}
}
-
+
+unsigned SmallStrings::count() const
+{
+ unsigned count = 0;
+ if (m_emptyString)
+ ++count;
+ for (unsigned i = 0; i < numCharactersToStore; ++i) {
+ if (m_singleCharacterStrings[i])
+ ++count;
+ }
+ return count;
+}
+
void SmallStrings::createEmptyString(JSGlobalData* globalData)
{
ASSERT(!m_emptyString);
@@ -109,4 +133,4 @@ UString::Rep* SmallStrings::singleCharacterStringRep(unsigned char character)
return m_storage->rep(character);
}
-}
+} // namespace JSC
diff --git a/JavaScriptCore/runtime/SmallStrings.h b/JavaScriptCore/runtime/SmallStrings.h
index 7c71208..e7f1170 100644
--- a/JavaScriptCore/runtime/SmallStrings.h
+++ b/JavaScriptCore/runtime/SmallStrings.h
@@ -26,7 +26,7 @@
#ifndef SmallStrings_h
#define SmallStrings_h
-#include "ustring.h"
+#include "UString.h"
#include <wtf/OwnPtr.h>
namespace JSC {
@@ -55,9 +55,11 @@ namespace JSC {
}
UString::Rep* singleCharacterStringRep(unsigned char character);
-
+
void mark();
-
+
+ unsigned count() const;
+
private:
void createEmptyString(JSGlobalData*);
void createSingleCharacterString(JSGlobalData*, unsigned char);
@@ -66,7 +68,7 @@ namespace JSC {
JSString* m_singleCharacterStrings[0x100];
OwnPtr<SmallStringsStorage> m_storage;
};
-
-}
-#endif
+} // namespace JSC
+
+#endif // SmallStrings_h
diff --git a/JavaScriptCore/runtime/StringConstructor.cpp b/JavaScriptCore/runtime/StringConstructor.cpp
index 850310e..dc1d60f 100644
--- a/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/JavaScriptCore/runtime/StringConstructor.cpp
@@ -27,26 +27,26 @@
namespace JSC {
-static NEVER_INLINE JSValue* stringFromCharCodeSlowCase(ExecState* exec, const ArgList& args)
+static NEVER_INLINE JSValuePtr stringFromCharCodeSlowCase(ExecState* exec, const ArgList& args)
{
UChar* buf = static_cast<UChar*>(fastMalloc(args.size() * sizeof(UChar)));
UChar* p = buf;
ArgList::const_iterator end = args.end();
for (ArgList::const_iterator it = args.begin(); it != end; ++it)
- *p++ = static_cast<UChar>((*it).jsValue(exec)->toUInt32(exec));
+ *p++ = static_cast<UChar>((*it).jsValue(exec).toUInt32(exec));
return jsString(exec, UString(buf, p - buf, false));
}
-static JSValue* stringFromCharCode(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr stringFromCharCode(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
if (LIKELY(args.size() == 1))
- return jsSingleCharacterString(exec, args.at(exec, 0)->toUInt32(exec));
+ return jsSingleCharacterString(exec, args.at(exec, 0).toUInt32(exec));
return stringFromCharCodeSlowCase(exec, args);
}
ASSERT_CLASS_FITS_IN_CELL(StringConstructor);
-StringConstructor::StringConstructor(ExecState* exec, PassRefPtr<StructureID> structure, StructureID* prototypeFunctionStructure, StringPrototype* stringPrototype)
+StringConstructor::StringConstructor(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, StringPrototype* stringPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, stringPrototype->classInfo()->className))
{
// ECMA 15.5.3.1 String.prototype
@@ -64,7 +64,7 @@ static JSObject* constructWithStringConstructor(ExecState* exec, JSObject*, cons
{
if (args.isEmpty())
return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure());
- return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure(), args.at(exec, 0)->toString(exec));
+ return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure(), args.at(exec, 0).toString(exec));
}
ConstructType StringConstructor::getConstructData(ConstructData& constructData)
@@ -74,11 +74,11 @@ ConstructType StringConstructor::getConstructData(ConstructData& constructData)
}
// ECMA 15.5.1
-static JSValue* callStringConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
+static JSValuePtr callStringConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
{
if (args.isEmpty())
return jsEmptyString(exec);
- return jsString(exec, args.at(exec, 0)->toString(exec));
+ return jsString(exec, args.at(exec, 0).toString(exec));
}
CallType StringConstructor::getCallData(CallData& callData)
diff --git a/JavaScriptCore/runtime/StringConstructor.h b/JavaScriptCore/runtime/StringConstructor.h
index 3376134..7d52c69 100644
--- a/JavaScriptCore/runtime/StringConstructor.h
+++ b/JavaScriptCore/runtime/StringConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class StringConstructor : public InternalFunction {
public:
- StringConstructor(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure, StringPrototype*);
+ StringConstructor(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure, StringPrototype*);
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
diff --git a/JavaScriptCore/runtime/StringObject.cpp b/JavaScriptCore/runtime/StringObject.cpp
index 5959395..093f5de 100644
--- a/JavaScriptCore/runtime/StringObject.cpp
+++ b/JavaScriptCore/runtime/StringObject.cpp
@@ -29,19 +29,19 @@ ASSERT_CLASS_FITS_IN_CELL(StringObject);
const ClassInfo StringObject::info = { "String", 0, 0, 0 };
-StringObject::StringObject(ExecState* exec, PassRefPtr<StructureID> structure)
+StringObject::StringObject(ExecState* exec, PassRefPtr<Structure> structure)
: JSWrapperObject(structure)
{
setInternalValue(jsEmptyString(exec));
}
-StringObject::StringObject(PassRefPtr<StructureID> structure, JSString* string)
+StringObject::StringObject(PassRefPtr<Structure> structure, JSString* string)
: JSWrapperObject(structure)
{
setInternalValue(string);
}
-StringObject::StringObject(ExecState* exec, PassRefPtr<StructureID> structure, const UString& string)
+StringObject::StringObject(ExecState* exec, PassRefPtr<Structure> structure, const UString& string)
: JSWrapperObject(structure)
{
setInternalValue(jsString(exec, string));
@@ -61,7 +61,7 @@ bool StringObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Pr
return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
}
-void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
+void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
{
if (propertyName == exec->propertyNames().length)
return;
diff --git a/JavaScriptCore/runtime/StringObject.h b/JavaScriptCore/runtime/StringObject.h
index 9297fd7..540c576 100644
--- a/JavaScriptCore/runtime/StringObject.h
+++ b/JavaScriptCore/runtime/StringObject.h
@@ -28,15 +28,15 @@ namespace JSC {
class StringObject : public JSWrapperObject {
public:
- StringObject(ExecState*, PassRefPtr<StructureID>);
- StringObject(ExecState*, PassRefPtr<StructureID>, const UString&);
+ StringObject(ExecState*, PassRefPtr<Structure>);
+ StringObject(ExecState*, PassRefPtr<Structure>, const UString&);
static StringObject* create(ExecState*, JSString*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
- virtual void put(ExecState* exec, const Identifier& propertyName, JSValue*, PutPropertySlot&);
+ virtual void put(ExecState* exec, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
@@ -45,13 +45,13 @@ namespace JSC {
JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
- static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
+ static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
{
- return StructureID::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType));
}
protected:
- StringObject(PassRefPtr<StructureID>, JSString*);
+ StringObject(PassRefPtr<Structure>, JSString*);
private:
virtual UString toString(ExecState*) const;
@@ -59,9 +59,9 @@ namespace JSC {
virtual JSString* toThisJSString(ExecState*);
};
- StringObject* asStringObject(JSValue*);
+ StringObject* asStringObject(JSValuePtr);
- inline StringObject* asStringObject(JSValue* value)
+ inline StringObject* asStringObject(JSValuePtr value)
{
ASSERT(asObject(value)->inherits(&StringObject::info));
return static_cast<StringObject*>(asObject(value));
diff --git a/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
index d703228..72c0f47 100644
--- a/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
+++ b/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
@@ -23,7 +23,7 @@
#include "JSGlobalObject.h"
#include "StringObject.h"
-#include "ustring.h"
+#include "UString.h"
namespace JSC {
@@ -33,18 +33,18 @@ namespace JSC {
static StringObjectThatMasqueradesAsUndefined* create(ExecState* exec, const UString& string)
{
return new (exec) StringObjectThatMasqueradesAsUndefined(exec,
- createStructureID(exec->lexicalGlobalObject()->stringPrototype()), string);
+ createStructure(exec->lexicalGlobalObject()->stringPrototype()), string);
}
private:
- StringObjectThatMasqueradesAsUndefined(ExecState* exec, PassRefPtr<StructureID> structure, const UString& string)
+ StringObjectThatMasqueradesAsUndefined(ExecState* exec, PassRefPtr<Structure> structure, const UString& string)
: StringObject(exec, structure, string)
{
}
- static PassRefPtr<StructureID> createStructureID(JSValue* proto)
+ static PassRefPtr<Structure> createStructure(JSValuePtr proto)
{
- return StructureID::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined));
+ return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined));
}
virtual bool toBoolean(ExecState*) const { return false; }
diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp
index 0b11c24..9c58f85 100644
--- a/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/JavaScriptCore/runtime/StringPrototype.cpp
@@ -37,36 +37,36 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(StringPrototype);
-static JSValue* stringProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncCharAt(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncCharCodeAt(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncConcat(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncMatch(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncReplace(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncSearch(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncSlice(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncSplit(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncSubstr(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncSubstring(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncToLowerCase(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncToUpperCase(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncLocaleCompare(ExecState*, JSObject*, JSValue*, const ArgList&);
-
-static JSValue* stringProtoFuncBig(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncSmall(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncBlink(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncBold(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncFixed(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncItalics(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncStrike(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncSub(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncSup(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncFontcolor(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncFontsize(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncAnchor(ExecState*, JSObject*, JSValue*, const ArgList&);
-static JSValue* stringProtoFuncLink(ExecState*, JSObject*, JSValue*, const ArgList&);
+static JSValuePtr stringProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncCharAt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncCharCodeAt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncConcat(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncLastIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncMatch(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncReplace(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncSearch(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncSlice(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncSplit(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncSubstr(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncSubstring(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncToLowerCase(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncToUpperCase(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncLocaleCompare(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+
+static JSValuePtr stringProtoFuncBig(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncSmall(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncBlink(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncBold(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncFixed(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncItalics(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncStrike(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncSub(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncSup(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncFontcolor(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncFontsize(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncAnchor(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValuePtr stringProtoFuncLink(ExecState*, JSObject*, JSValuePtr, const ArgList&);
}
@@ -117,7 +117,7 @@ const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, Exec
*/
// ECMA 15.5.4
-StringPrototype::StringPrototype(ExecState* exec, PassRefPtr<StructureID> structure)
+StringPrototype::StringPrototype(ExecState* exec, PassRefPtr<Structure> structure)
: StringObject(exec, structure)
{
// The constructor will be added later, after StringConstructor has been built
@@ -140,13 +140,12 @@ static inline UString substituteBackreferences(const UString& replacement, const
if (i + 1 == replacement.size())
break;
- unsigned short ref = replacement[i + 1];
+ UChar ref = replacement[i + 1];
if (ref == '$') {
// "$$" -> "$"
++i;
substitutedReplacement.append(replacement.data() + offset, i - offset);
offset = i + 1;
- substitutedReplacement.append('$');
continue;
}
@@ -162,7 +161,7 @@ static inline UString substituteBackreferences(const UString& replacement, const
} else if (ref == '\'') {
backrefStart = ovector[1];
backrefLength = source.size() - backrefStart;
- } else if (ref >= '0' && ref <= '9') {
+ } else if (reg && ref >= '0' && ref <= '9') {
// 1- and 2-digit back references are allowed
unsigned backrefIndex = ref - '0';
if (backrefIndex > reg->numSubpatterns())
@@ -177,6 +176,8 @@ static inline UString substituteBackreferences(const UString& replacement, const
advance = 1;
}
}
+ if (!backrefIndex)
+ continue;
backrefStart = ovector[2 * backrefIndex];
backrefLength = ovector[2 * backrefIndex + 1] - backrefStart;
} else
@@ -203,25 +204,25 @@ static inline int localeCompare(const UString& a, const UString& b)
return Collator::userDefault()->collate(reinterpret_cast<const ::UChar*>(a.data()), a.size(), reinterpret_cast<const ::UChar*>(b.data()), b.size());
}
-JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncReplace(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- JSString* sourceVal = thisValue->toThisJSString(exec);
+ JSString* sourceVal = thisValue.toThisJSString(exec);
const UString& source = sourceVal->value();
- JSValue* pattern = args.at(exec, 0);
+ JSValuePtr pattern = args.at(exec, 0);
- JSValue* replacement = args.at(exec, 1);
+ JSValuePtr replacement = args.at(exec, 1);
UString replacementString;
CallData callData;
- CallType callType = replacement->getCallData(callData);
+ CallType callType = replacement.getCallData(callData);
if (callType == CallTypeNone)
- replacementString = replacement->toString(exec);
+ replacementString = replacement.toString(exec);
- if (pattern->isObject(&RegExpObject::info)) {
+ if (pattern.isObject(&RegExpObject::info)) {
RegExp* reg = asRegExpObject(pattern)->regExp();
bool global = reg->global();
- RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
+ RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int lastIndex = 0;
int startPosition = 0;
@@ -234,7 +235,7 @@ JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue,
int matchIndex;
int matchLen;
int* ovector;
- regExpObj->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
+ regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
if (matchIndex < 0)
break;
@@ -257,7 +258,7 @@ JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue,
args.append(jsNumber(exec, completeMatchStart));
args.append(sourceVal);
- replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args)->toString(exec));
+ replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec));
if (exec->hadException())
break;
} else
@@ -286,7 +287,7 @@ JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue,
}
// First arg is a string
- UString patternString = pattern->toString(exec);
+ UString patternString = pattern.toString(exec);
int matchPos = source.find(patternString);
int matchLen = patternString.size();
// Do the replacement
@@ -299,95 +300,107 @@ JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue,
args.append(jsNumber(exec, matchPos));
args.append(sourceVal);
- replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args)->toString(exec);
+ replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec);
}
- return jsString(exec, source.substr(0, matchPos) + replacementString + source.substr(matchPos + matchLen));
+ int ovector[2] = { matchPos, matchPos + matchLen };
+ return jsString(exec, source.substr(0, matchPos)
+ + substituteBackreferences(replacementString, source, ovector, 0)
+ + source.substr(matchPos + matchLen));
}
-JSValue* stringProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
// Also used for valueOf.
- if (thisValue->isString())
+ if (thisValue.isString())
return thisValue;
- if (thisValue->isObject(&StringObject::info))
+ if (thisValue.isObject(&StringObject::info))
return asStringObject(thisValue)->internalValue();
return throwError(exec, TypeError);
}
-JSValue* stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
unsigned len = s.size();
- JSValue* a0 = args.at(exec, 0);
- if (JSImmediate::isNumber(a0)) {
- uint32_t i;
- if (JSImmediate::getUInt32(a0, i) && i < len)
+ JSValuePtr a0 = args.at(exec, 0);
+ if (a0.isUInt32Fast()) {
+ uint32_t i = a0.getUInt32Fast();
+ if (i < len)
return jsSingleCharacterSubstring(exec, s, i);
return jsEmptyString(exec);
}
- double dpos = a0->toInteger(exec);
+ double dpos = a0.toInteger(exec);
if (dpos >= 0 && dpos < len)
return jsSingleCharacterSubstring(exec, s, static_cast<unsigned>(dpos));
return jsEmptyString(exec);
}
-JSValue* stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
unsigned len = s.size();
- JSValue* a0 = args.at(exec, 0);
- if (JSImmediate::isNumber(a0)) {
- uint32_t i;
- if (JSImmediate::getUInt32(a0, i) && i < len)
+ JSValuePtr a0 = args.at(exec, 0);
+ if (a0.isUInt32Fast()) {
+ uint32_t i = a0.getUInt32Fast();
+ if (i < len)
return jsNumber(exec, s.data()[i]);
return jsNaN(exec);
}
- double dpos = a0->toInteger(exec);
+ double dpos = a0.toInteger(exec);
if (dpos >= 0 && dpos < len)
return jsNumber(exec, s[static_cast<int>(dpos)]);
return jsNaN(exec);
}
-JSValue* stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
ArgList::const_iterator end = args.end();
for (ArgList::const_iterator it = args.begin(); it != end; ++it)
- s += (*it).jsValue(exec)->toString(exec);
+ s += (*it).jsValue(exec).toString(exec);
return jsString(exec, s);
}
-JSValue* stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
int len = s.size();
- JSValue* a0 = args.at(exec, 0);
- JSValue* a1 = args.at(exec, 1);
- UString u2 = a0->toString(exec);
- double dpos = a1->toInteger(exec);
- if (dpos < 0)
- dpos = 0;
- else if (dpos > len)
- dpos = len;
- return jsNumber(exec, s.find(u2, static_cast<int>(dpos)));
+ JSValuePtr a0 = args.at(exec, 0);
+ JSValuePtr a1 = args.at(exec, 1);
+ UString u2 = a0.toString(exec);
+ int pos;
+ if (a1.isUndefined())
+ pos = 0;
+ else if (a1.isUInt32Fast())
+ pos = min<uint32_t>(a1.getUInt32Fast(), len);
+ else {
+ double dpos = a1.toInteger(exec);
+ if (dpos < 0)
+ dpos = 0;
+ else if (dpos > len)
+ dpos = len;
+ pos = static_cast<int>(dpos);
+ }
+
+ return jsNumber(exec, s.find(u2, pos));
}
-JSValue* stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
int len = s.size();
- JSValue* a0 = args.at(exec, 0);
- JSValue* a1 = args.at(exec, 1);
+ JSValuePtr a0 = args.at(exec, 0);
+ JSValuePtr a1 = args.at(exec, 1);
- UString u2 = a0->toString(exec);
- double dpos = a1->toIntegerPreserveNaN(exec);
+ UString u2 = a0.toString(exec);
+ double dpos = a1.toIntegerPreserveNaN(exec);
if (dpos < 0)
dpos = 0;
else if (!(dpos <= len)) // true for NaN
@@ -395,16 +408,16 @@ JSValue* stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue* thisVal
return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
}
-JSValue* stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncMatch(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
- JSValue* a0 = args.at(exec, 0);
+ JSValuePtr a0 = args.at(exec, 0);
UString u = s;
RefPtr<RegExp> reg;
RegExpObject* imp = 0;
- if (a0->isObject(&RegExpObject::info))
+ if (a0.isObject(&RegExpObject::info))
reg = asRegExpObject(a0)->regExp();
else {
/*
@@ -412,17 +425,17 @@ JSValue* stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue* thisValue, co
* If regexp is not an object whose [[Class]] property is "RegExp", it is
* replaced with the result of the expression new RegExp(regexp).
*/
- reg = RegExp::create(&exec->globalData(), a0->toString(exec));
+ reg = RegExp::create(&exec->globalData(), a0.toString(exec));
}
- RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
+ RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
int matchLength;
- regExpObj->performMatch(reg.get(), u, 0, pos, matchLength);
+ regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
if (!(reg->global())) {
// case without 'g' flag is handled like RegExp.prototype.exec
if (pos < 0)
return jsNull();
- return regExpObj->arrayOfMatches(exec);
+ return regExpConstructor->arrayOfMatches(exec);
}
// return array of matches
@@ -432,7 +445,7 @@ JSValue* stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue* thisValue, co
list.append(jsSubstring(exec, u, pos, matchLength));
lastIndex = pos;
pos += matchLength == 0 ? 1 : matchLength;
- regExpObj->performMatch(reg.get(), u, pos, pos, matchLength);
+ regExpConstructor->performMatch(reg.get(), u, pos, pos, matchLength);
}
if (imp)
imp->setLastIndex(lastIndex);
@@ -446,15 +459,15 @@ JSValue* stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue* thisValue, co
return constructArray(exec, list);
}
-JSValue* stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncSearch(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
- JSValue* a0 = args.at(exec, 0);
+ JSValuePtr a0 = args.at(exec, 0);
UString u = s;
RefPtr<RegExp> reg;
- if (a0->isObject(&RegExpObject::info))
+ if (a0.isObject(&RegExpObject::info))
reg = asRegExpObject(a0)->regExp();
else {
/*
@@ -462,26 +475,26 @@ JSValue* stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue* thisValue, c
* If regexp is not an object whose [[Class]] property is "RegExp", it is
* replaced with the result of the expression new RegExp(regexp).
*/
- reg = RegExp::create(&exec->globalData(), a0->toString(exec));
+ reg = RegExp::create(&exec->globalData(), a0.toString(exec));
}
- RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
+ RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
int matchLength;
- regExpObj->performMatch(reg.get(), u, 0, pos, matchLength);
+ regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
return jsNumber(exec, pos);
}
-JSValue* stringProtoFuncSlice(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
int len = s.size();
- JSValue* a0 = args.at(exec, 0);
- JSValue* a1 = args.at(exec, 1);
+ JSValuePtr a0 = args.at(exec, 0);
+ JSValuePtr a1 = args.at(exec, 1);
// The arg processing is very much like ArrayProtoFunc::Slice
- double start = a0->toInteger(exec);
- double end = a1->isUndefined() ? len : a1->toInteger(exec);
+ double start = a0.toInteger(exec);
+ double end = a1.isUndefined() ? len : a1.toInteger(exec);
double from = start < 0 ? len + start : start;
double to = end < 0 ? len + end : end;
if (to > from && to > 0 && from < len) {
@@ -495,18 +508,18 @@ JSValue* stringProtoFuncSlice(ExecState* exec, JSObject*, JSValue* thisValue, co
return jsEmptyString(exec);
}
-JSValue* stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncSplit(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
- JSValue* a0 = args.at(exec, 0);
- JSValue* a1 = args.at(exec, 1);
+ JSValuePtr a0 = args.at(exec, 0);
+ JSValuePtr a1 = args.at(exec, 1);
JSArray* result = constructEmptyArray(exec);
unsigned i = 0;
int p0 = 0;
- unsigned limit = a1->isUndefined() ? 0xFFFFFFFFU : a1->toUInt32(exec);
- if (a0->isObject(&RegExpObject::info)) {
+ unsigned limit = a1.isUndefined() ? 0xFFFFFFFFU : a1.toUInt32(exec);
+ if (a0.isObject(&RegExpObject::info)) {
RegExp* reg = asRegExpObject(a0)->regExp();
if (s.isEmpty() && reg->match(s, 0) >= 0) {
// empty string matched by regexp -> empty array
@@ -533,7 +546,7 @@ JSValue* stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue* thisValue, co
}
}
} else {
- UString u2 = a0->toString(exec);
+ UString u2 = a0.toString(exec);
if (u2.isEmpty()) {
if (s.isEmpty()) {
// empty separator matches empty string -> empty array
@@ -557,16 +570,16 @@ JSValue* stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue* thisValue, co
return result;
}
-JSValue* stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
int len = s.size();
- JSValue* a0 = args.at(exec, 0);
- JSValue* a1 = args.at(exec, 1);
+ JSValuePtr a0 = args.at(exec, 0);
+ JSValuePtr a1 = args.at(exec, 1);
- double start = a0->toInteger(exec);
- double length = a1->isUndefined() ? len : a1->toInteger(exec);
+ double start = a0.toInteger(exec);
+ double length = a1.isUndefined() ? len : a1.toInteger(exec);
if (start >= len || length <= 0)
return jsEmptyString(exec);
if (start < 0) {
@@ -579,16 +592,16 @@ JSValue* stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValue* thisValue, c
return jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(length));
}
-JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
int len = s.size();
- JSValue* a0 = args.at(exec, 0);
- JSValue* a1 = args.at(exec, 1);
+ JSValuePtr a0 = args.at(exec, 0);
+ JSValuePtr a1 = args.at(exec, 1);
- double start = a0->toNumber(exec);
- double end = a1->toNumber(exec);
+ double start = a0.toNumber(exec);
+ double end = a1.toNumber(exec);
if (isnan(start))
start = 0;
if (isnan(end))
@@ -601,7 +614,7 @@ JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValue* thisValue
start = len;
if (end > len)
end = len;
- if (a1->isUndefined())
+ if (a1.isUndefined())
end = len;
if (start > end) {
double temp = end;
@@ -611,9 +624,9 @@ JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValue* thisValue
return jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(end) - static_cast<unsigned>(start));
}
-JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- JSString* sVal = thisValue->toThisJSString(exec);
+ JSString* sVal = thisValue.toThisJSString(exec);
const UString& s = sVal->value();
int sSize = s.size();
@@ -645,9 +658,9 @@ JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValue* thisVal
return jsString(exec, UString(buffer.releaseBuffer(), length, false));
}
-JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- JSString* sVal = thisValue->toThisJSString(exec);
+ JSString* sVal = thisValue.toThisJSString(exec);
const UString& s = sVal->value();
int sSize = s.size();
@@ -679,96 +692,155 @@ JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValue* thisVal
return jsString(exec, UString(buffer.releaseBuffer(), length, false));
}
-JSValue* stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
if (args.size() < 1)
return jsNumber(exec, 0);
- UString s = thisValue->toThisString(exec);
- JSValue* a0 = args.at(exec, 0);
- return jsNumber(exec, localeCompare(s, a0->toString(exec)));
+ UString s = thisValue.toThisString(exec);
+ JSValuePtr a0 = args.at(exec, 0);
+ return jsNumber(exec, localeCompare(s, a0.toString(exec)));
}
-JSValue* stringProtoFuncBig(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncBig(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<big>" + s + "</big>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<big>" + s + "</big>");
}
-JSValue* stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncSmall(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<small>" + s + "</small>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<small>" + s + "</small>");
}
-JSValue* stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncBlink(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<blink>" + s + "</blink>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<blink>" + s + "</blink>");
}
-JSValue* stringProtoFuncBold(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncBold(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<b>" + s + "</b>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<b>" + s + "</b>");
}
-JSValue* stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncFixed(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
+ UString s = thisValue.toThisString(exec);
return jsString(exec, "<tt>" + s + "</tt>");
}
-JSValue* stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncItalics(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<i>" + s + "</i>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<i>" + s + "</i>");
}
-JSValue* stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncStrike(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<strike>" + s + "</strike>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<strike>" + s + "</strike>");
}
-JSValue* stringProtoFuncSub(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncSub(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<sub>" + s + "</sub>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<sub>" + s + "</sub>");
}
-JSValue* stringProtoFuncSup(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
+JSValuePtr stringProtoFuncSup(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- UString s = thisValue->toThisString(exec);
- return jsString(exec, "<sup>" + s + "</sup>");
+ UString s = thisValue.toThisString(exec);
+ return jsNontrivialString(exec, "<sup>" + s + "</sup>");
}
-JSValue* stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
- JSValue* a0 = args.at(exec, 0);
- return jsString(exec, "<font color=\"" + a0->toString(exec) + "\">" + s + "</font>");
+ UString s = thisValue.toThisString(exec);
+ JSValuePtr a0 = args.at(exec, 0);
+ return jsNontrivialString(exec, "<font color=\"" + a0.toString(exec) + "\">" + s + "</font>");
}
-JSValue* stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
+JSValuePtr stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- UString s = thisValue->toThisString(exec);
- JSValue* a0 = args.at(exec, 0);
- return jsString(exec, "<font size=\"" + a0->toString(exec) + "\">" + s + "</font>");
-}
+ UString s = thisValue.toThisString(exec);
+ JSValuePtr a0 = args.at(exec, 0);
-JSValue* stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
-{
- UString s = thisValue->toThisString(exec);
- JSValue* a0 = args.at(exec, 0);
- return jsString(exec, "<a name=\"" + a0->toString(exec) + "\">" + s + "</a>");
-}
+ uint32_t smallInteger;
+ if (a0.getUInt32(smallInteger) && smallInteger <= 9) {
+ unsigned stringSize = s.size();
+ unsigned bufferSize = 22 + stringSize;
+ UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar)));
+ if (!buffer)
+ return jsUndefined();
+ buffer[0] = '<';
+ buffer[1] = 'f';
+ buffer[2] = 'o';
+ buffer[3] = 'n';
+ buffer[4] = 't';
+ buffer[5] = ' ';
+ buffer[6] = 's';
+ buffer[7] = 'i';
+ buffer[8] = 'z';
+ buffer[9] = 'e';
+ buffer[10] = '=';
+ buffer[11] = '"';
+ buffer[12] = '0' + smallInteger;
+ buffer[13] = '"';
+ buffer[14] = '>';
+ memcpy(&buffer[15], s.data(), stringSize * sizeof(UChar));
+ buffer[15 + stringSize] = '<';
+ buffer[16 + stringSize] = '/';
+ buffer[17 + stringSize] = 'f';
+ buffer[18 + stringSize] = 'o';
+ buffer[19 + stringSize] = 'n';
+ buffer[20 + stringSize] = 't';
+ buffer[21 + stringSize] = '>';
+ return jsNontrivialString(exec, UString(buffer, bufferSize, false));
+ }
-JSValue* stringProtoFuncLink(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
-{
- UString s = thisValue->toThisString(exec);
- JSValue* a0 = args.at(exec, 0);
- return jsString(exec, "<a href=\"" + a0->toString(exec) + "\">" + s + "</a>");
+ return jsNontrivialString(exec, "<font size=\"" + a0.toString(exec) + "\">" + s + "</font>");
+}
+
+JSValuePtr stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ JSValuePtr a0 = args.at(exec, 0);
+ return jsNontrivialString(exec, "<a name=\"" + a0.toString(exec) + "\">" + s + "</a>");
+}
+
+JSValuePtr stringProtoFuncLink(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+{
+ UString s = thisValue.toThisString(exec);
+ JSValuePtr a0 = args.at(exec, 0);
+ UString linkText = a0.toString(exec);
+
+ unsigned linkTextSize = linkText.size();
+ unsigned stringSize = s.size();
+ unsigned bufferSize = 15 + linkTextSize + stringSize;
+ UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar)));
+ if (!buffer)
+ return jsUndefined();
+ buffer[0] = '<';
+ buffer[1] = 'a';
+ buffer[2] = ' ';
+ buffer[3] = 'h';
+ buffer[4] = 'r';
+ buffer[5] = 'e';
+ buffer[6] = 'f';
+ buffer[7] = '=';
+ buffer[8] = '"';
+ memcpy(&buffer[9], linkText.data(), linkTextSize * sizeof(UChar));
+ buffer[9 + linkTextSize] = '"';
+ buffer[10 + linkTextSize] = '>';
+ memcpy(&buffer[11 + linkTextSize], s.data(), stringSize * sizeof(UChar));
+ buffer[11 + linkTextSize + stringSize] = '<';
+ buffer[12 + linkTextSize + stringSize] = '/';
+ buffer[13 + linkTextSize + stringSize] = 'a';
+ buffer[14 + linkTextSize + stringSize] = '>';
+ return jsNontrivialString(exec, UString(buffer, bufferSize, false));
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/StringPrototype.h b/JavaScriptCore/runtime/StringPrototype.h
index b127885..6f5344e 100644
--- a/JavaScriptCore/runtime/StringPrototype.h
+++ b/JavaScriptCore/runtime/StringPrototype.h
@@ -29,7 +29,7 @@ namespace JSC {
class StringPrototype : public StringObject {
public:
- StringPrototype(ExecState*, PassRefPtr<StructureID>);
+ StringPrototype(ExecState*, PassRefPtr<Structure>);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
diff --git a/JavaScriptCore/runtime/StructureID.cpp b/JavaScriptCore/runtime/Structure.cpp
index 8333595..86ee76c 100644
--- a/JavaScriptCore/runtime/StructureID.cpp
+++ b/JavaScriptCore/runtime/Structure.cpp
@@ -24,13 +24,13 @@
*/
#include "config.h"
-#include "StructureID.h"
+#include "Structure.h"
+#include "Identifier.h"
#include "JSObject.h"
#include "PropertyNameArray.h"
-#include "StructureIDChain.h"
-#include "identifier.h"
-#include "lookup.h"
+#include "StructureChain.h"
+#include "Lookup.h"
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/RefPtr.h>
@@ -47,7 +47,7 @@
#endif
using namespace std;
-using WTF::doubleHash;
+using namespace WTF;
namespace JSC {
@@ -59,76 +59,84 @@ static const int smallMapThreshold = 1024;
// becomes small compared to the inefficiency of insertion sort.
static const unsigned tinyMapThreshold = 20;
+static const unsigned newTableSize = 16;
+
#ifndef NDEBUG
-static WTF::RefCountedLeakCounter structureIDCounter("StructureID");
+static WTF::RefCountedLeakCounter structureCounter("Structure");
#if ENABLE(JSC_MULTIPLE_THREADS)
static Mutex ignoreSetMutex;
#endif
static bool shouldIgnoreLeaks;
-static HashSet<StructureID*> ignoreSet;
+static HashSet<Structure*> ignoreSet;
#endif
#if DUMP_STRUCTURE_ID_STATISTICS
-static HashSet<StructureID*> liveStructureIDSet;
+static HashSet<Structure*> liveStructureSet;
#endif
-void StructureID::dumpStatistics()
+void Structure::dumpStatistics()
{
#if DUMP_STRUCTURE_ID_STATISTICS
unsigned numberLeaf = 0;
unsigned numberUsingSingleSlot = 0;
unsigned numberSingletons = 0;
+ unsigned numberWithPropertyMaps = 0;
unsigned totalPropertyMapsSize = 0;
- HashSet<StructureID*>::const_iterator end = liveStructureIDSet.end();
- for (HashSet<StructureID*>::const_iterator it = liveStructureIDSet.begin(); it != end; ++it) {
- StructureID* structureID = *it;
- if (structureID->m_usingSingleTransitionSlot) {
- if (!structureID->m_transitions.singleTransition)
+ HashSet<Structure*>::const_iterator end = liveStructureSet.end();
+ for (HashSet<Structure*>::const_iterator it = liveStructureSet.begin(); it != end; ++it) {
+ Structure* structure = *it;
+ if (structure->m_usingSingleTransitionSlot) {
+ if (!structure->m_transitions.singleTransition)
++numberLeaf;
else
++numberUsingSingleSlot;
- if (!structureID->m_previous && !structureID->m_transitions.singleTransition)
+ if (!structure->m_previous && !structure->m_transitions.singleTransition)
++numberSingletons;
}
- if (structureID->m_propertyTable)
- totalPropertyMapsSize += PropertyMapHashTable::allocationSize(structureID->m_propertyTable->size);
+ if (structure->m_propertyTable) {
+ ++numberWithPropertyMaps;
+ totalPropertyMapsSize += PropertyMapHashTable::allocationSize(structure->m_propertyTable->size);
+ if (structure->m_propertyTable->deletedOffsets)
+ totalPropertyMapsSize += (structure->m_propertyTable->deletedOffsets->capacity() * sizeof(unsigned));
+ }
}
- printf("Number of live StructureIDs: %d\n", liveStructureIDSet.size());
- printf("Number of StructureIDs using the single item optimization for transition map: %d\n", numberUsingSingleSlot);
- printf("Number of StructureIDs that are leaf nodes: %d\n", numberLeaf);
- printf("Number of StructureIDs that singletons: %d\n", numberSingletons);
+ printf("Number of live Structures: %d\n", liveStructureSet.size());
+ printf("Number of Structures using the single item optimization for transition map: %d\n", numberUsingSingleSlot);
+ printf("Number of Structures that are leaf nodes: %d\n", numberLeaf);
+ printf("Number of Structures that singletons: %d\n", numberSingletons);
+ printf("Number of Structures with PropertyMaps: %d\n", numberWithPropertyMaps);
- printf("Size of a single StructureIDs: %d\n", static_cast<unsigned>(sizeof(StructureID)));
+ printf("Size of a single Structures: %d\n", static_cast<unsigned>(sizeof(Structure)));
printf("Size of sum of all property maps: %d\n", totalPropertyMapsSize);
- printf("Size of average of all property maps: %f\n", static_cast<double>(totalPropertyMapsSize) / static_cast<double>(liveStructureIDSet.size()));
+ printf("Size of average of all property maps: %f\n", static_cast<double>(totalPropertyMapsSize) / static_cast<double>(liveStructureSet.size()));
#else
- printf("Dumping StructureID statistics is not enabled.\n");
+ printf("Dumping Structure statistics is not enabled.\n");
#endif
}
-StructureID::StructureID(JSValue* prototype, const TypeInfo& typeInfo)
+Structure::Structure(JSValuePtr prototype, const TypeInfo& typeInfo)
: m_typeInfo(typeInfo)
, m_prototype(prototype)
, m_cachedPrototypeChain(0)
, m_previous(0)
, m_nameInPrevious(0)
- , m_transitionCount(0)
, m_propertyTable(0)
, m_propertyStorageCapacity(JSObject::inlineStorageCapacity)
- , m_cachedTransistionOffset(WTF::notFound)
+ , m_offset(noOffset)
, m_isDictionary(false)
+ , m_isPinnedPropertyTable(false)
, m_hasGetterSetterProperties(false)
, m_usingSingleTransitionSlot(true)
, m_attributesInPrevious(0)
{
ASSERT(m_prototype);
- ASSERT(m_prototype->isObject() || m_prototype->isNull());
+ ASSERT(m_prototype.isObject() || m_prototype.isNull());
m_transitions.singleTransition = 0;
@@ -139,27 +147,27 @@ StructureID::StructureID(JSValue* prototype, const TypeInfo& typeInfo)
if (shouldIgnoreLeaks)
ignoreSet.add(this);
else
- structureIDCounter.increment();
+ structureCounter.increment();
#endif
#if DUMP_STRUCTURE_ID_STATISTICS
- liveStructureIDSet.add(this);
+ liveStructureSet.add(this);
#endif
}
-StructureID::~StructureID()
+Structure::~Structure()
{
if (m_previous) {
if (m_previous->m_usingSingleTransitionSlot) {
m_previous->m_transitions.singleTransition = 0;
} else {
- ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious, m_attributesInPrevious)));
- m_previous->m_transitions.table->remove(make_pair(m_nameInPrevious, m_attributesInPrevious));
+ ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious.get(), m_attributesInPrevious)));
+ m_previous->m_transitions.table->remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious));
}
}
if (m_cachedPropertyNameArrayData)
- m_cachedPropertyNameArrayData->setCachedStructureID(0);
+ m_cachedPropertyNameArrayData->setCachedStructure(0);
if (!m_usingSingleTransitionSlot)
delete m_transitions.table;
@@ -170,6 +178,8 @@ StructureID::~StructureID()
if (UString::Rep* key = m_propertyTable->entries()[i].key)
key->deref();
}
+
+ delete m_propertyTable->deletedOffsets;
fastFree(m_propertyTable);
}
@@ -177,39 +187,113 @@ StructureID::~StructureID()
#if ENABLE(JSC_MULTIPLE_THREADS)
MutexLocker protect(ignoreSetMutex);
#endif
- HashSet<StructureID*>::iterator it = ignoreSet.find(this);
+ HashSet<Structure*>::iterator it = ignoreSet.find(this);
if (it != ignoreSet.end())
ignoreSet.remove(it);
else
- structureIDCounter.decrement();
+ structureCounter.decrement();
#endif
#if DUMP_STRUCTURE_ID_STATISTICS
- liveStructureIDSet.remove(this);
+ liveStructureSet.remove(this);
#endif
}
-void StructureID::startIgnoringLeaks()
+void Structure::startIgnoringLeaks()
{
#ifndef NDEBUG
shouldIgnoreLeaks = true;
#endif
}
-void StructureID::stopIgnoringLeaks()
+void Structure::stopIgnoringLeaks()
{
#ifndef NDEBUG
shouldIgnoreLeaks = false;
#endif
}
-void StructureID::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
+static bool isPowerOf2(unsigned v)
+{
+ // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
+
+ return !(v & (v - 1)) && v;
+}
+
+static unsigned nextPowerOf2(unsigned v)
+{
+ // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html
+ // Devised by Sean Anderson, Sepember 14, 2001
+
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v++;
+
+ return v;
+}
+
+static unsigned sizeForKeyCount(size_t keyCount)
+{
+ if (keyCount == notFound)
+ return newTableSize;
+
+ if (keyCount < 8)
+ return newTableSize;
+
+ if (isPowerOf2(keyCount))
+ return keyCount * 4;
+
+ return nextPowerOf2(keyCount) * 2;
+}
+
+void Structure::materializePropertyMap()
+{
+ ASSERT(!m_propertyTable);
+
+ Vector<Structure*, 8> structures;
+ structures.append(this);
+
+ Structure* structure = this;
+
+ // Search for the last Structure with a property table.
+ while ((structure = structure->previousID())) {
+ if (structure->m_isPinnedPropertyTable) {
+ ASSERT(structure->m_propertyTable);
+ ASSERT(!structure->m_previous);
+
+ m_propertyTable = structure->copyPropertyTable();
+ break;
+ }
+
+ structures.append(structure);
+ }
+
+ if (!m_propertyTable)
+ createPropertyMapHashTable(sizeForKeyCount(m_offset + 1));
+ else {
+ if (sizeForKeyCount(m_offset + 1) > m_propertyTable->size)
+ rehashPropertyMapHashTable(sizeForKeyCount(m_offset + 1)); // This could be made more efficient by combining with the copy above.
+ }
+
+ for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) {
+ structure = structures[i];
+ structure->m_nameInPrevious->ref();
+ PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, ++m_propertyTable->lastIndexUsed);
+ insertIntoPropertyMapHashTable(entry);
+ }
+}
+
+void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
{
bool shouldCache = propertyNames.cacheable() && !(propertyNames.size() || m_isDictionary);
if (shouldCache) {
if (m_cachedPropertyNameArrayData) {
- if (structureIDChainsAreEqual(m_cachedPropertyNameArrayData->cachedPrototypeChain(), cachedPrototypeChain())) {
+ if (structureChainsAreEqual(m_cachedPropertyNameArrayData->cachedPrototypeChain(), cachedPrototypeChain())) {
propertyNames.setData(m_cachedPropertyNameArrayData);
return;
}
@@ -226,7 +310,11 @@ void StructureID::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray&
continue;
table->initializeIfNeeded(exec);
ASSERT(table->table);
+#if ENABLE(PERFECT_HASH_SIZE)
int hashSizeMask = table->hashSizeMask;
+#else
+ int hashSizeMask = table->compactSize - 1;
+#endif
const HashEntry* entry = table->table;
for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
if (entry->key() && !(entry->attributes() & DontEnum))
@@ -234,31 +322,31 @@ void StructureID::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray&
}
}
- if (m_prototype->isObject())
+ if (m_prototype.isObject())
asObject(m_prototype)->getPropertyNames(exec, propertyNames);
if (shouldCache) {
if (m_cachedPropertyNameArrayData)
- m_cachedPropertyNameArrayData->setCachedStructureID(0);
+ m_cachedPropertyNameArrayData->setCachedStructure(0);
m_cachedPropertyNameArrayData = propertyNames.data();
- StructureIDChain* chain = cachedPrototypeChain();
+ StructureChain* chain = cachedPrototypeChain();
if (!chain)
chain = createCachedPrototypeChain();
m_cachedPropertyNameArrayData->setCachedPrototypeChain(chain);
- m_cachedPropertyNameArrayData->setCachedStructureID(this);
+ m_cachedPropertyNameArrayData->setCachedStructure(this);
}
}
-void StructureID::clearEnumerationCache()
+void Structure::clearEnumerationCache()
{
if (m_cachedPropertyNameArrayData)
- m_cachedPropertyNameArrayData->setCachedStructureID(0);
+ m_cachedPropertyNameArrayData->setCachedStructure(0);
m_cachedPropertyNameArrayData.clear();
}
-void StructureID::growPropertyStorageCapacity()
+void Structure::growPropertyStorageCapacity()
{
if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity)
m_propertyStorageCapacity = JSObject::nonInlineBaseStorageCapacity;
@@ -266,131 +354,168 @@ void StructureID::growPropertyStorageCapacity()
m_propertyStorageCapacity *= 2;
}
-PassRefPtr<StructureID> StructureID::addPropertyTransition(StructureID* structureID, const Identifier& propertyName, unsigned attributes, size_t& offset)
+PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset)
{
- ASSERT(!structureID->m_isDictionary);
- ASSERT(structureID->typeInfo().type() == ObjectType);
-
- if (structureID->m_usingSingleTransitionSlot) {
- StructureID* existingTransition = structureID->m_transitions.singleTransition;
- if (existingTransition && existingTransition->m_nameInPrevious == propertyName.ustring().rep() && existingTransition->m_attributesInPrevious == attributes) {
- offset = structureID->m_transitions.singleTransition->cachedTransistionOffset();
- ASSERT(offset != WTF::notFound);
+ ASSERT(!structure->m_isDictionary);
+ ASSERT(structure->typeInfo().type() == ObjectType);
+
+ if (structure->m_usingSingleTransitionSlot) {
+ Structure* existingTransition = structure->m_transitions.singleTransition;
+ if (existingTransition && existingTransition->m_nameInPrevious.get() == propertyName.ustring().rep() && existingTransition->m_attributesInPrevious == attributes) {
+ ASSERT(structure->m_transitions.singleTransition->m_offset != noOffset);
+ offset = structure->m_transitions.singleTransition->m_offset;
return existingTransition;
}
} else {
- if (StructureID* existingTransition = structureID->m_transitions.table->get(make_pair(propertyName.ustring().rep(), attributes))) {
- offset = existingTransition->cachedTransistionOffset();
- ASSERT(offset != WTF::notFound);
+ if (Structure* existingTransition = structure->m_transitions.table->get(make_pair(propertyName.ustring().rep(), attributes))) {
+ ASSERT(existingTransition->m_offset != noOffset);
+ offset = existingTransition->m_offset;
return existingTransition;
- }
+ }
}
- if (structureID->m_transitionCount > s_maxTransitionLength) {
- RefPtr<StructureID> transition = toDictionaryTransition(structureID);
+ return 0;
+}
+
+PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset)
+{
+ ASSERT(!structure->m_isDictionary);
+ ASSERT(structure->typeInfo().type() == ObjectType);
+ ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, offset));
+
+ if (structure->transitionCount() > s_maxTransitionLength) {
+ RefPtr<Structure> transition = toDictionaryTransition(structure);
offset = transition->put(propertyName, attributes);
if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
transition->growPropertyStorageCapacity();
return transition.release();
}
- RefPtr<StructureID> transition = create(structureID->m_prototype, structureID->typeInfo());
- transition->m_cachedPrototypeChain = structureID->m_cachedPrototypeChain;
- transition->m_previous = structureID;
+ RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
+ transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain;
+ transition->m_previous = structure;
transition->m_nameInPrevious = propertyName.ustring().rep();
transition->m_attributesInPrevious = attributes;
- transition->m_transitionCount = structureID->m_transitionCount + 1;
- transition->m_propertyTable = structureID->copyPropertyTable();
- transition->m_deletedOffsets = structureID->m_deletedOffsets;
- transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
- transition->m_hasGetterSetterProperties = structureID->m_hasGetterSetterProperties;
+ transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
+ transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+
+ if (structure->m_propertyTable) {
+ if (structure->m_isPinnedPropertyTable)
+ transition->m_propertyTable = structure->copyPropertyTable();
+ else {
+ transition->m_propertyTable = structure->m_propertyTable;
+ structure->m_propertyTable = 0;
+ }
+ } else {
+ if (structure->m_previous)
+ transition->materializePropertyMap();
+ else
+ transition->createPropertyMapHashTable();
+ }
offset = transition->put(propertyName, attributes);
if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
transition->growPropertyStorageCapacity();
- transition->setCachedTransistionOffset(offset);
+ transition->m_offset = offset;
- if (structureID->m_usingSingleTransitionSlot) {
- if (!structureID->m_transitions.singleTransition) {
- structureID->m_transitions.singleTransition = transition.get();
+ if (structure->m_usingSingleTransitionSlot) {
+ if (!structure->m_transitions.singleTransition) {
+ structure->m_transitions.singleTransition = transition.get();
return transition.release();
}
- StructureID* existingTransition = structureID->m_transitions.singleTransition;
- structureID->m_usingSingleTransitionSlot = false;
- StructureIDTransitionTable* transitionTable = new StructureIDTransitionTable;
- structureID->m_transitions.table = transitionTable;
- transitionTable->add(make_pair(existingTransition->m_nameInPrevious, existingTransition->m_attributesInPrevious), existingTransition);
+ Structure* existingTransition = structure->m_transitions.singleTransition;
+ structure->m_usingSingleTransitionSlot = false;
+ StructureTransitionTable* transitionTable = new StructureTransitionTable;
+ structure->m_transitions.table = transitionTable;
+ transitionTable->add(make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition);
}
- structureID->m_transitions.table->add(make_pair(propertyName.ustring().rep(), attributes), transition.get());
+ structure->m_transitions.table->add(make_pair(propertyName.ustring().rep(), attributes), transition.get());
return transition.release();
}
-PassRefPtr<StructureID> StructureID::removePropertyTransition(StructureID* structureID, const Identifier& propertyName, size_t& offset)
+PassRefPtr<Structure> Structure::removePropertyTransition(Structure* structure, const Identifier& propertyName, size_t& offset)
{
- ASSERT(!structureID->m_isDictionary);
+ ASSERT(!structure->m_isDictionary);
- RefPtr<StructureID> transition = create(structureID->m_prototype, structureID->typeInfo());
- transition->m_isDictionary = true;
- transition->m_propertyTable = structureID->copyPropertyTable();
- transition->m_deletedOffsets = structureID->m_deletedOffsets;
- transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
- transition->m_hasGetterSetterProperties = structureID->m_hasGetterSetterProperties;
+ RefPtr<Structure> transition = toDictionaryTransition(structure);
offset = transition->remove(propertyName);
return transition.release();
}
-PassRefPtr<StructureID> StructureID::toDictionaryTransition(StructureID* structureID)
+PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, JSValuePtr prototype)
{
- ASSERT(!structureID->m_isDictionary);
+ RefPtr<Structure> transition = create(prototype, structure->typeInfo());
+
+ transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
+ transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+
+ // Don't set m_offset, as one can not transition to this.
+
+ structure->materializePropertyMapIfNecessary();
+ transition->m_propertyTable = structure->copyPropertyTable();
+ transition->m_isPinnedPropertyTable = true;
- RefPtr<StructureID> transition = create(structureID->m_prototype, structureID->typeInfo());
- transition->m_isDictionary = true;
- transition->m_propertyTable = structureID->copyPropertyTable();
- transition->m_deletedOffsets = structureID->m_deletedOffsets;
- transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
- transition->m_hasGetterSetterProperties = structureID->m_hasGetterSetterProperties;
return transition.release();
}
-PassRefPtr<StructureID> StructureID::fromDictionaryTransition(StructureID* structureID)
+PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
{
- ASSERT(structureID->m_isDictionary);
+ RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
+ transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
+ transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties;
- // Since dictionary StructureIDs are not shared, and no opcodes specialize
- // for them, we don't need to allocate a new StructureID when transitioning
- // to non-dictionary status.
- structureID->m_isDictionary = false;
- return structureID;
+ // Don't set m_offset, as one can not transition to this.
+
+ structure->materializePropertyMapIfNecessary();
+ transition->m_propertyTable = structure->copyPropertyTable();
+ transition->m_isPinnedPropertyTable = true;
+
+ return transition.release();
}
-PassRefPtr<StructureID> StructureID::changePrototypeTransition(StructureID* structureID, JSValue* prototype)
+PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure)
{
- RefPtr<StructureID> transition = create(prototype, structureID->typeInfo());
- transition->m_transitionCount = structureID->m_transitionCount + 1;
- transition->m_propertyTable = structureID->copyPropertyTable();
- transition->m_deletedOffsets = structureID->m_deletedOffsets;
- transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
- transition->m_hasGetterSetterProperties = structureID->m_hasGetterSetterProperties;
+ ASSERT(!structure->m_isDictionary);
+
+ RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
+ transition->m_isDictionary = true;
+ transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
+ transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+
+ structure->materializePropertyMapIfNecessary();
+ transition->m_propertyTable = structure->copyPropertyTable();
+ transition->m_isPinnedPropertyTable = true;
+
return transition.release();
}
-PassRefPtr<StructureID> StructureID::getterSetterTransition(StructureID* structureID)
+PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure)
{
- RefPtr<StructureID> transition = create(structureID->storedPrototype(), structureID->typeInfo());
- transition->m_transitionCount = structureID->m_transitionCount + 1;
- transition->m_propertyTable = structureID->copyPropertyTable();
- transition->m_deletedOffsets = structureID->m_deletedOffsets;
- transition->m_propertyStorageCapacity = structureID->m_propertyStorageCapacity;
- transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties;
- return transition.release();
+ ASSERT(structure->m_isDictionary);
+
+ // Since dictionary Structures are not shared, and no opcodes specialize
+ // for them, we don't need to allocate a new Structure when transitioning
+ // to non-dictionary status.
+
+ // FIMXE: We can make this more efficient by canonicalizing the Structure (draining the
+ // deleted offsets vector) before transitioning from dictionary.
+ if (!structure->m_propertyTable || !structure->m_propertyTable->deletedOffsets || structure->m_propertyTable->deletedOffsets->isEmpty())
+ structure->m_isDictionary = false;
+
+ return structure;
}
-size_t StructureID::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes)
+size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes)
{
+ ASSERT(!m_transitions.singleTransition);
+
+ materializePropertyMapIfNecessary();
+
+ m_isPinnedPropertyTable = true;
size_t offset = put(propertyName, attributes);
if (propertyStorageSize() > propertyStorageCapacity())
growPropertyStorageCapacity();
@@ -398,23 +523,29 @@ size_t StructureID::addPropertyWithoutTransition(const Identifier& propertyName,
return offset;
}
-size_t StructureID::removePropertyWithoutTransition(const Identifier& propertyName)
+size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName)
{
+ ASSERT(!m_transitions.singleTransition);
+ ASSERT(m_isDictionary);
+
+ materializePropertyMapIfNecessary();
+
+ m_isPinnedPropertyTable = true;
size_t offset = remove(propertyName);
clearEnumerationCache();
return offset;
}
-StructureIDChain* StructureID::createCachedPrototypeChain()
+StructureChain* Structure::createCachedPrototypeChain()
{
ASSERT(typeInfo().type() == ObjectType);
ASSERT(!m_cachedPrototypeChain);
- JSValue* prototype = storedPrototype();
- if (JSImmediate::isImmediate(prototype))
+ JSValuePtr prototype = storedPrototype();
+ if (!prototype.isCell())
return 0;
- RefPtr<StructureIDChain> chain = StructureIDChain::create(asObject(prototype)->structureID());
+ RefPtr<StructureChain> chain = StructureChain::create(asObject(prototype)->structure());
setCachedPrototypeChain(chain.release());
return cachedPrototypeChain();
}
@@ -447,13 +578,13 @@ static const unsigned deletedSentinelIndex = 1;
#if !DO_PROPERTYMAP_CONSTENCY_CHECK
-inline void StructureID::checkConsistency()
+inline void Structure::checkConsistency()
{
-}
+}
#endif
-PropertyMapHashTable* StructureID::copyPropertyTable()
+PropertyMapHashTable* Structure::copyPropertyTable()
{
if (!m_propertyTable)
return 0;
@@ -468,15 +599,20 @@ PropertyMapHashTable* StructureID::copyPropertyTable()
key->ref();
}
+ // Copy the deletedOffsets vector.
+ if (m_propertyTable->deletedOffsets)
+ newTable->deletedOffsets = new Vector<unsigned>(*m_propertyTable->deletedOffsets);
+
return newTable;
}
-size_t StructureID::get(const Identifier& propertyName, unsigned& attributes) const
+size_t Structure::get(const Identifier& propertyName, unsigned& attributes)
{
ASSERT(!propertyName.isNull());
+ materializePropertyMapIfNecessary();
if (!m_propertyTable)
- return WTF::notFound;
+ return notFound;
UString::Rep* rep = propertyName._ustring.rep();
@@ -488,7 +624,7 @@ size_t StructureID::get(const Identifier& propertyName, unsigned& attributes) co
unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
if (entryIndex == emptyEntryIndex)
- return WTF::notFound;
+ return notFound;
if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
attributes = m_propertyTable->entries()[entryIndex - 1].attributes;
@@ -510,7 +646,7 @@ size_t StructureID::get(const Identifier& propertyName, unsigned& attributes) co
entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
if (entryIndex == emptyEntryIndex)
- return WTF::notFound;
+ return notFound;
if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
attributes = m_propertyTable->entries()[entryIndex - 1].attributes;
@@ -519,10 +655,10 @@ size_t StructureID::get(const Identifier& propertyName, unsigned& attributes) co
}
}
-size_t StructureID::put(const Identifier& propertyName, unsigned attributes)
+size_t Structure::put(const Identifier& propertyName, unsigned attributes)
{
ASSERT(!propertyName.isNull());
- ASSERT(get(propertyName) == WTF::notFound);
+ ASSERT(get(propertyName) == notFound);
checkConsistency();
@@ -592,9 +728,9 @@ size_t StructureID::put(const Identifier& propertyName, unsigned attributes)
m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed;
unsigned newOffset;
- if (!m_deletedOffsets.isEmpty()) {
- newOffset = m_deletedOffsets.last();
- m_deletedOffsets.removeLast();
+ if (m_propertyTable->deletedOffsets && !m_propertyTable->deletedOffsets->isEmpty()) {
+ newOffset = m_propertyTable->deletedOffsets->last();
+ m_propertyTable->deletedOffsets->removeLast();
} else
newOffset = m_propertyTable->keyCount;
m_propertyTable->entries()[entryIndex - 1].offset = newOffset;
@@ -608,7 +744,7 @@ size_t StructureID::put(const Identifier& propertyName, unsigned attributes)
return newOffset;
}
-size_t StructureID::remove(const Identifier& propertyName)
+size_t Structure::remove(const Identifier& propertyName)
{
ASSERT(!propertyName.isNull());
@@ -617,7 +753,7 @@ size_t StructureID::remove(const Identifier& propertyName)
UString::Rep* rep = propertyName._ustring.rep();
if (!m_propertyTable)
- return WTF::notFound;
+ return notFound;
#if DUMP_PROPERTYMAP_STATS
++numProbes;
@@ -632,7 +768,7 @@ size_t StructureID::remove(const Identifier& propertyName)
while (1) {
entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
if (entryIndex == emptyEntryIndex)
- return WTF::notFound;
+ return notFound;
key = m_propertyTable->entries()[entryIndex - 1].key;
if (rep == key)
@@ -662,7 +798,10 @@ size_t StructureID::remove(const Identifier& propertyName)
m_propertyTable->entries()[entryIndex - 1].key = 0;
m_propertyTable->entries()[entryIndex - 1].attributes = 0;
m_propertyTable->entries()[entryIndex - 1].offset = 0;
- m_deletedOffsets.append(offset);
+
+ if (!m_propertyTable->deletedOffsets)
+ m_propertyTable->deletedOffsets = new Vector<unsigned>;
+ m_propertyTable->deletedOffsets->append(offset);
ASSERT(m_propertyTable->keyCount >= 1);
--m_propertyTable->keyCount;
@@ -675,7 +814,7 @@ size_t StructureID::remove(const Identifier& propertyName)
return offset;
}
-void StructureID::insertIntoPropertyMapHashTable(const PropertyMapEntry& entry)
+void Structure::insertIntoPropertyMapHashTable(const PropertyMapEntry& entry)
{
ASSERT(m_propertyTable);
@@ -712,17 +851,16 @@ void StructureID::insertIntoPropertyMapHashTable(const PropertyMapEntry& entry)
++m_propertyTable->keyCount;
}
-void StructureID::expandPropertyMapHashTable()
+void Structure::createPropertyMapHashTable()
{
- ASSERT(m_propertyTable);
- rehashPropertyMapHashTable(m_propertyTable->size * 2);
+ ASSERT(sizeForKeyCount(7) == newTableSize);
+ createPropertyMapHashTable(newTableSize);
}
-void StructureID::createPropertyMapHashTable()
+void Structure::createPropertyMapHashTable(unsigned newTableSize)
{
- const unsigned newTableSize = 16;
-
ASSERT(!m_propertyTable);
+ ASSERT(isPowerOf2(newTableSize));
checkConsistency();
@@ -733,16 +871,23 @@ void StructureID::createPropertyMapHashTable()
checkConsistency();
}
-void StructureID::rehashPropertyMapHashTable()
+void Structure::expandPropertyMapHashTable()
+{
+ ASSERT(m_propertyTable);
+ rehashPropertyMapHashTable(m_propertyTable->size * 2);
+}
+
+void Structure::rehashPropertyMapHashTable()
{
ASSERT(m_propertyTable);
ASSERT(m_propertyTable->size);
rehashPropertyMapHashTable(m_propertyTable->size);
}
-void StructureID::rehashPropertyMapHashTable(unsigned newTableSize)
+void Structure::rehashPropertyMapHashTable(unsigned newTableSize)
{
ASSERT(m_propertyTable);
+ ASSERT(isPowerOf2(newTableSize));
checkConsistency();
@@ -761,6 +906,7 @@ void StructureID::rehashPropertyMapHashTable(unsigned newTableSize)
}
}
m_propertyTable->lastIndexUsed = lastIndexUsed;
+ m_propertyTable->deletedOffsets = oldTable->deletedOffsets;
fastFree(oldTable);
@@ -778,8 +924,9 @@ static int comparePropertyMapEntryIndices(const void* a, const void* b)
return 0;
}
-void StructureID::getEnumerablePropertyNamesInternal(PropertyNameArray& propertyNames) const
+void Structure::getEnumerablePropertyNamesInternal(PropertyNameArray& propertyNames)
{
+ materializePropertyMapIfNecessary();
if (!m_propertyTable)
return;
@@ -836,12 +983,12 @@ void StructureID::getEnumerablePropertyNamesInternal(PropertyNameArray& property
#if DO_PROPERTYMAP_CONSTENCY_CHECK
-void StructureID::checkConsistency()
+void Structure::checkConsistency()
{
if (!m_propertyTable)
return;
- ASSERT(m_propertyTable->size >= 16);
+ ASSERT(m_propertyTable->size >= newTableSize);
ASSERT(m_propertyTable->sizeMask);
ASSERT(m_propertyTable->size == m_propertyTable->sizeMask + 1);
ASSERT(!(m_propertyTable->size & m_propertyTable->sizeMask));
diff --git a/JavaScriptCore/runtime/StructureID.h b/JavaScriptCore/runtime/Structure.h
index 4f45dac..569738b 100644
--- a/JavaScriptCore/runtime/StructureID.h
+++ b/JavaScriptCore/runtime/Structure.h
@@ -23,20 +23,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StructureID_h
-#define StructureID_h
+#ifndef Structure_h
+#define Structure_h
+#include "Identifier.h"
#include "JSType.h"
#include "JSValue.h"
#include "PropertyMapHashTable.h"
-#include "StructureIDChain.h"
-#include "StructureIDTransitionTable.h"
+#include "StructureChain.h"
+#include "StructureTransitionTable.h"
#include "TypeInfo.h"
-#include "identifier.h"
-#include "ustring.h"
-#include <wtf/HashFunctions.h>
-#include <wtf/HashTraits.h>
-#include <wtf/OwnArrayPtr.h>
+#include "UString.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -51,12 +48,12 @@ namespace JSC {
class PropertyNameArray;
class PropertyNameArrayData;
- class StructureID : public RefCounted<StructureID> {
+ class Structure : public RefCounted<Structure> {
public:
- friend class CTI;
- static PassRefPtr<StructureID> create(JSValue* prototype, const TypeInfo& typeInfo)
+ friend class JIT;
+ static PassRefPtr<Structure> create(JSValuePtr prototype, const TypeInfo& typeInfo)
{
- return adoptRef(new StructureID(prototype, typeInfo));
+ return adoptRef(new Structure(prototype, typeInfo));
}
static void startIgnoringLeaks();
@@ -64,113 +61,128 @@ namespace JSC {
static void dumpStatistics();
- static PassRefPtr<StructureID> changePrototypeTransition(StructureID*, JSValue* prototype);
- static PassRefPtr<StructureID> addPropertyTransition(StructureID*, const Identifier& propertyName, unsigned attributes, size_t& offset);
- static PassRefPtr<StructureID> removePropertyTransition(StructureID*, const Identifier& propertyName, size_t& offset);
- static PassRefPtr<StructureID> getterSetterTransition(StructureID*);
- static PassRefPtr<StructureID> toDictionaryTransition(StructureID*);
- static PassRefPtr<StructureID> fromDictionaryTransition(StructureID*);
+ static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, size_t& offset);
+ static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, size_t& offset);
+ static PassRefPtr<Structure> removePropertyTransition(Structure*, const Identifier& propertyName, size_t& offset);
+ static PassRefPtr<Structure> changePrototypeTransition(Structure*, JSValuePtr prototype);
+ static PassRefPtr<Structure> getterSetterTransition(Structure*);
+ static PassRefPtr<Structure> toDictionaryTransition(Structure*);
+ static PassRefPtr<Structure> fromDictionaryTransition(Structure*);
- ~StructureID();
+ ~Structure();
void mark()
{
- if (!m_prototype->marked())
- m_prototype->mark();
+ if (!m_prototype.marked())
+ m_prototype.mark();
}
// These should be used with caution.
size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes);
size_t removePropertyWithoutTransition(const Identifier& propertyName);
- void setPrototypeWithoutTransition(JSValue* prototype) { m_prototype = prototype; }
+ void setPrototypeWithoutTransition(JSValuePtr prototype) { m_prototype = prototype; }
bool isDictionary() const { return m_isDictionary; }
const TypeInfo& typeInfo() const { return m_typeInfo; }
- // For use when first creating a new structure.
- TypeInfo& mutableTypeInfo() { return m_typeInfo; }
+ JSValuePtr storedPrototype() const { return m_prototype; }
+ JSValuePtr prototypeForLookup(ExecState*);
- JSValue* storedPrototype() const { return m_prototype; }
- JSValue* prototypeForLookup(ExecState*);
+ Structure* previousID() const { return m_previous.get(); }
- StructureID* previousID() const { return m_previous.get(); }
-
- StructureIDChain* createCachedPrototypeChain();
- void setCachedPrototypeChain(PassRefPtr<StructureIDChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
- StructureIDChain* cachedPrototypeChain() const { return m_cachedPrototypeChain.get(); }
-
- void setCachedTransistionOffset(size_t offset) { m_cachedTransistionOffset = offset; }
- size_t cachedTransistionOffset() const { return m_cachedTransistionOffset; }
+ StructureChain* createCachedPrototypeChain();
+ void setCachedPrototypeChain(PassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
+ StructureChain* cachedPrototypeChain() const { return m_cachedPrototypeChain.get(); }
void growPropertyStorageCapacity();
size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; }
- size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_deletedOffsets.size() : 0; }
+ size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; }
- size_t get(const Identifier& propertyName) const;
- size_t get(const Identifier& propertyName, unsigned& attributes) const;
+ size_t get(const Identifier& propertyName);
+ size_t get(const Identifier& propertyName, unsigned& attributes);
void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; }
- bool isEmpty() const { return !m_propertyTable; }
+ bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; }
private:
- StructureID(JSValue* prototype, const TypeInfo&);
+ Structure(JSValuePtr prototype, const TypeInfo&);
size_t put(const Identifier& propertyName, unsigned attributes);
size_t remove(const Identifier& propertyName);
- void getEnumerablePropertyNamesInternal(PropertyNameArray&) const;
+ void getEnumerablePropertyNamesInternal(PropertyNameArray&);
void expandPropertyMapHashTable();
void rehashPropertyMapHashTable();
void rehashPropertyMapHashTable(unsigned newTableSize);
void createPropertyMapHashTable();
+ void createPropertyMapHashTable(unsigned newTableSize);
void insertIntoPropertyMapHashTable(const PropertyMapEntry&);
void checkConsistency();
PropertyMapHashTable* copyPropertyTable();
+ void materializePropertyMap();
+ void materializePropertyMapIfNecessary()
+ {
+ if (m_propertyTable || !m_previous)
+ return;
+ materializePropertyMap();
+ }
void clearEnumerationCache();
+ void* addressOfCount()
+ {
+ return &m_refCount;
+ }
+
+ signed char transitionCount() const
+ {
+ // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
+ return m_offset == noOffset ? 0 : m_offset + 1;
+ }
+
static const unsigned emptyEntryIndex = 0;
- static const size_t s_maxTransitionLength = 64;
+ static const signed char s_maxTransitionLength = 64;
+
+ static const signed char noOffset = -1;
TypeInfo m_typeInfo;
- JSValue* m_prototype;
- RefPtr<StructureIDChain> m_cachedPrototypeChain;
+ JSValuePtr m_prototype;
+ RefPtr<StructureChain> m_cachedPrototypeChain;
- RefPtr<StructureID> m_previous;
- UString::Rep* m_nameInPrevious;
+ RefPtr<Structure> m_previous;
+ RefPtr<UString::Rep> m_nameInPrevious;
- size_t m_transitionCount;
union {
- StructureID* singleTransition;
- StructureIDTransitionTable* table;
+ Structure* singleTransition;
+ StructureTransitionTable* table;
} m_transitions;
RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
PropertyMapHashTable* m_propertyTable;
- Vector<unsigned> m_deletedOffsets;
size_t m_propertyStorageCapacity;
-
- size_t m_cachedTransistionOffset;
+ signed char m_offset;
bool m_isDictionary : 1;
+ bool m_isPinnedPropertyTable : 1;
bool m_hasGetterSetterProperties : 1;
bool m_usingSingleTransitionSlot : 1;
unsigned m_attributesInPrevious : 5;
};
- inline size_t StructureID::get(const Identifier& propertyName) const
+ inline size_t Structure::get(const Identifier& propertyName)
{
ASSERT(!propertyName.isNull());
+ materializePropertyMapIfNecessary();
if (!m_propertyTable)
return WTF::notFound;
@@ -213,4 +225,4 @@ namespace JSC {
} // namespace JSC
-#endif // StructureID_h
+#endif // Structure_h
diff --git a/JavaScriptCore/runtime/StructureIDChain.cpp b/JavaScriptCore/runtime/StructureChain.cpp
index 83d9254..4d00263 100644
--- a/JavaScriptCore/runtime/StructureIDChain.cpp
+++ b/JavaScriptCore/runtime/StructureChain.cpp
@@ -24,42 +24,42 @@
*/
#include "config.h"
-#include "StructureIDChain.h"
+#include "StructureChain.h"
#include "JSObject.h"
-#include "StructureID.h"
+#include "Structure.h"
#include <wtf/RefPtr.h>
namespace JSC {
-StructureIDChain::StructureIDChain(StructureID* structureID)
+StructureChain::StructureChain(Structure* structure)
{
size_t size = 1;
- StructureID* tmp = structureID;
- while (!tmp->storedPrototype()->isNull()) {
+ Structure* tmp = structure;
+ while (!tmp->storedPrototype().isNull()) {
++size;
- tmp = asCell(tmp->storedPrototype())->structureID();
+ tmp = asCell(tmp->storedPrototype())->structure();
}
- m_vector.set(new RefPtr<StructureID>[size + 1]);
+ m_vector.set(new RefPtr<Structure>[size + 1]);
size_t i;
for (i = 0; i < size - 1; ++i) {
- m_vector[i] = structureID;
- structureID = asObject(structureID->storedPrototype())->structureID();
+ m_vector[i] = structure;
+ structure = asObject(structure->storedPrototype())->structure();
}
- m_vector[i] = structureID;
+ m_vector[i] = structure;
m_vector[i + 1] = 0;
}
-bool structureIDChainsAreEqual(StructureIDChain* chainA, StructureIDChain* chainB)
+bool structureChainsAreEqual(StructureChain* chainA, StructureChain* chainB)
{
if (!chainA || !chainB)
return false;
- RefPtr<StructureID>* a = chainA->head();
- RefPtr<StructureID>* b = chainB->head();
+ RefPtr<Structure>* a = chainA->head();
+ RefPtr<Structure>* b = chainB->head();
while (1) {
if (*a != *b)
return false;
diff --git a/JavaScriptCore/runtime/StructureIDChain.h b/JavaScriptCore/runtime/StructureChain.h
index 2d554a7..a3a1be2 100644
--- a/JavaScriptCore/runtime/StructureIDChain.h
+++ b/JavaScriptCore/runtime/StructureChain.h
@@ -23,8 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StructureIDChain_h
-#define StructureIDChain_h
+#ifndef StructureChain_h
+#define StructureChain_h
#include <wtf/OwnArrayPtr.h>
#include <wtf/PassRefPtr.h>
@@ -33,22 +33,22 @@
namespace JSC {
- class StructureID;
+ class Structure;
- class StructureIDChain : public RefCounted<StructureIDChain> {
+ class StructureChain : public RefCounted<StructureChain> {
public:
- static PassRefPtr<StructureIDChain> create(StructureID* structureID) { return adoptRef(new StructureIDChain(structureID)); }
+ static PassRefPtr<StructureChain> create(Structure* structure) { return adoptRef(new StructureChain(structure)); }
- RefPtr<StructureID>* head() { return m_vector.get(); }
+ RefPtr<Structure>* head() { return m_vector.get(); }
private:
- StructureIDChain(StructureID* structureID);
+ StructureChain(Structure* structure);
- OwnArrayPtr<RefPtr<StructureID> > m_vector;
+ OwnArrayPtr<RefPtr<Structure> > m_vector;
};
- bool structureIDChainsAreEqual(StructureIDChain*, StructureIDChain*);
+ bool structureChainsAreEqual(StructureChain*, StructureChain*);
} // namespace JSC
-#endif // StructureIDChain_h
+#endif // StructureChain_h
diff --git a/JavaScriptCore/runtime/StructureIDTransitionTable.h b/JavaScriptCore/runtime/StructureTransitionTable.h
index dd65971..1543049 100644
--- a/JavaScriptCore/runtime/StructureIDTransitionTable.h
+++ b/JavaScriptCore/runtime/StructureTransitionTable.h
@@ -23,10 +23,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StructureIDTransitionTable_h
-#define StructureIDTransitionTable_h
+#ifndef StructureTransitionTable_h
+#define StructureTransitionTable_h
-#include "ustring.h"
+#include "UString.h"
#include <wtf/HashFunctions.h>
#include <wtf/HashMap.h>
#include <wtf/HashTraits.h>
@@ -34,9 +34,9 @@
namespace JSC {
- class StructureID;
+ class Structure;
- struct StructureIDTransitionTableHash {
+ struct StructureTransitionTableHash {
typedef std::pair<RefPtr<UString::Rep>, unsigned> Key;
static unsigned hash(const Key& p)
{
@@ -51,7 +51,7 @@ namespace JSC {
static const bool safeToCompareToEmptyOrDeleted = true;
};
- struct StructureIDTransitionTableHashTraits {
+ struct StructureTransitionTableHashTraits {
typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits;
typedef WTF::GenericHashTraits<unsigned> SecondTraits;
typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType> TraitType;
@@ -65,8 +65,8 @@ namespace JSC {
static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
};
- typedef HashMap<StructureIDTransitionTableHash::Key, StructureID*, StructureIDTransitionTableHash, StructureIDTransitionTableHashTraits> StructureIDTransitionTable;
+ typedef HashMap<StructureTransitionTableHash::Key, Structure*, StructureTransitionTableHash, StructureTransitionTableHashTraits> StructureTransitionTable;
} // namespace JSC
-#endif // StructureIDTransitionTable_h
+#endif // StructureTransitionTable_h
diff --git a/JavaScriptCore/runtime/SymbolTable.h b/JavaScriptCore/runtime/SymbolTable.h
index d730d58..c00f95a 100644
--- a/JavaScriptCore/runtime/SymbolTable.h
+++ b/JavaScriptCore/runtime/SymbolTable.h
@@ -30,7 +30,7 @@
#define SymbolTable_h
#include "JSObject.h"
-#include "ustring.h"
+#include "UString.h"
#include <wtf/AlwaysInline.h>
namespace JSC {
diff --git a/JavaScriptCore/kjs/TypeInfo.h b/JavaScriptCore/runtime/TypeInfo.h
index 4f0b16c..52da347 100644
--- a/JavaScriptCore/kjs/TypeInfo.h
+++ b/JavaScriptCore/runtime/TypeInfo.h
@@ -39,7 +39,7 @@ namespace JSC {
static const unsigned HasStandardGetOwnPropertySlot = 1 << 4;
class TypeInfo {
- friend class CTI;
+ friend class JIT;
public:
TypeInfo(JSType type, unsigned flags = 0) : m_type(type), m_flags(flags) { }
diff --git a/JavaScriptCore/kjs/ustring.cpp b/JavaScriptCore/runtime/UString.cpp
index 3a85b1d..8cb12cf 100644
--- a/JavaScriptCore/kjs/ustring.cpp
+++ b/JavaScriptCore/runtime/UString.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
+ * 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
@@ -21,13 +22,13 @@
*/
#include "config.h"
-#include "ustring.h"
+#include "UString.h"
#include "JSGlobalObjectFunctions.h"
-#include "collector.h"
+#include "Collector.h"
#include "dtoa.h"
-#include "identifier.h"
-#include "operations.h"
+#include "Identifier.h"
+#include "Operations.h"
#include <ctype.h>
#include <float.h>
#include <limits.h>
@@ -186,8 +187,37 @@ bool operator==(const CString& c1, const CString& c2)
// 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;
-UString::Rep UString::Rep::null = { 0, 0, INT_MAX / 2, 0, 1, &UString::Rep::null, 0, 0, 0, 0, 0, 0 };
-UString::Rep UString::Rep::empty = { 0, 0, INT_MAX / 2, 0, 1, &UString::Rep::empty, 0, &sharedEmptyChar, 0, 0, 0, 0 };
+UString::BaseString* UString::Rep::nullBaseString;
+UString::BaseString* UString::Rep::emptyBaseString;
+UString* UString::nullUString;
+
+static void initializeStaticBaseString(int len, UChar* buf, UString::BaseString& base)
+{
+ base.offset = 0;
+ base.len = len;
+ base.rc = INT_MAX / 2;
+ base._hash = 0;
+ base.m_identifierTableAndFlags.setFlag(UString::Rep::StaticFlag);
+ base.m_baseString = 0;
+ base.buf = buf;
+ base.preCapacity = 0;
+ base.usedPreCapacity = 0;
+ base.capacity = 0;
+ base.usedCapacity = 0;
+ base.reportedCost = 0;
+ base.checkConsistency();
+}
+
+void initializeUString()
+{
+ UString::Rep::nullBaseString = new UString::BaseString;
+ initializeStaticBaseString(0, 0, *UString::Rep::nullBaseString);
+
+ UString::Rep::emptyBaseString = new UString::BaseString;
+ initializeStaticBaseString(0, &sharedEmptyChar, *UString::Rep::emptyBaseString);
+
+ UString::nullUString = new UString;
+}
static char* statBuffer = 0; // Only used for debugging via UString::ascii().
@@ -200,13 +230,12 @@ PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar* d, int l)
PassRefPtr<UString::Rep> UString::Rep::create(UChar* d, int l)
{
- Rep* r = new Rep;
+ BaseString* r = new BaseString;
r->offset = 0;
r->len = l;
r->rc = 1;
r->_hash = 0;
- r->m_identifierTable = 0;
- r->baseString = r;
+ r->m_baseString = 0;
r->reportedCost = 0;
r->buf = d;
r->usedCapacity = l;
@@ -220,31 +249,24 @@ PassRefPtr<UString::Rep> UString::Rep::create(UChar* d, int l)
return adoptRef(r);
}
-PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset, int length)
+PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> rep, int offset, int length)
{
- ASSERT(base);
- base->checkConsistency();
+ ASSERT(rep);
+ rep->checkConsistency();
- int baseOffset = base->offset;
+ int repOffset = rep->offset;
- base = base->baseString;
+ PassRefPtr<BaseString> base = rep->baseString();
- ASSERT(-(offset + baseOffset) <= base->usedPreCapacity);
- ASSERT(offset + baseOffset + length <= base->usedCapacity);
+ ASSERT(-(offset + repOffset) <= base->usedPreCapacity);
+ ASSERT(offset + repOffset + length <= base->usedCapacity);
Rep* r = new Rep;
- r->offset = baseOffset + offset;
+ r->offset = repOffset + offset;
r->len = length;
r->rc = 1;
r->_hash = 0;
- r->m_identifierTable = 0;
- r->baseString = base.releaseRef();
- r->reportedCost = 0;
- r->buf = 0;
- r->usedCapacity = 0;
- r->capacity = 0;
- r->usedPreCapacity = 0;
- r->preCapacity = 0;
+ r->setBaseString(base);
r->checkConsistency();
@@ -255,13 +277,13 @@ PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset,
PassRefPtr<UString::Rep> UString::Rep::createFromUTF8(const char* string)
{
if (!string)
- return &UString::Rep::null;
+ return &UString::Rep::null();
size_t length = strlen(string);
Vector<UChar, 1024> buffer(length);
UChar* p = buffer.data();
if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length))
- return &UString::Rep::null;
+ return &UString::Rep::null();
return UString::Rep::createCopying(buffer.data(), p - buffer.data());
}
@@ -275,10 +297,11 @@ void UString::Rep::destroy()
if (!isStatic()) {
if (identifierTable())
Identifier::remove(this);
- if (baseString == this)
- fastFree(buf);
+ UString::BaseString* base = baseString();
+ if (base == this)
+ fastFree(base->buf);
else
- baseString->deref();
+ base->deref();
delete this;
}
@@ -380,17 +403,10 @@ unsigned UString::Rep::computeHash(const char* s, int l)
#ifndef NDEBUG
void UString::Rep::checkConsistency() const
{
- // Only base strings have non-zero shared data.
- if (this != baseString) {
- ASSERT(!buf);
- ASSERT(!usedCapacity);
- ASSERT(!capacity);
- ASSERT(!usedPreCapacity);
- ASSERT(!preCapacity);
- }
+ const UString::BaseString* base = baseString();
// There is no recursion for base strings.
- ASSERT(baseString == baseString->baseString);
+ ASSERT(base == base->baseString());
if (isStatic()) {
// There are only two static strings: null and empty.
@@ -401,10 +417,10 @@ void UString::Rep::checkConsistency() const
}
// The string fits in buffer.
- ASSERT(baseString->usedPreCapacity <= baseString->preCapacity);
- ASSERT(baseString->usedCapacity <= baseString->capacity);
- ASSERT(-offset <= baseString->usedPreCapacity);
- ASSERT(offset + len <= baseString->usedCapacity);
+ ASSERT(base->usedPreCapacity <= base->preCapacity);
+ ASSERT(base->usedCapacity <= base->capacity);
+ ASSERT(-offset <= base->usedPreCapacity);
+ ASSERT(offset + len <= base->usedCapacity);
}
#endif
@@ -424,35 +440,24 @@ static inline size_t expandedSize(size_t size, size_t otherSize)
return expandedSize + otherSize;
}
-inline int UString::usedCapacity() const
-{
- return m_rep->baseString->usedCapacity;
-}
-
-inline int UString::usedPreCapacity() const
-{
- return m_rep->baseString->usedPreCapacity;
-}
-
-
static inline bool expandCapacity(UString::Rep* rep, int requiredLength)
{
rep->checkConsistency();
- UString::Rep* r = rep->baseString;
+ UString::BaseString* base = rep->baseString();
- if (requiredLength > r->capacity) {
- size_t newCapacity = expandedSize(requiredLength, r->preCapacity);
- UChar* oldBuf = r->buf;
- r->buf = reallocChars(r->buf, newCapacity);
- if (!r->buf) {
- r->buf = oldBuf;
+ if (requiredLength > base->capacity) {
+ size_t newCapacity = expandedSize(requiredLength, base->preCapacity);
+ UChar* oldBuf = base->buf;
+ base->buf = reallocChars(base->buf, newCapacity);
+ if (!base->buf) {
+ base->buf = oldBuf;
return false;
}
- r->capacity = newCapacity - r->preCapacity;
+ base->capacity = newCapacity - base->preCapacity;
}
- if (requiredLength > r->usedCapacity)
- r->usedCapacity = requiredLength;
+ if (requiredLength > base->usedCapacity)
+ base->usedCapacity = requiredLength;
rep->checkConsistency();
return true;
@@ -468,41 +473,41 @@ void UString::expandPreCapacity(int requiredPreCap)
{
m_rep->checkConsistency();
- Rep* r = m_rep->baseString;
+ BaseString* base = m_rep->baseString();
- if (requiredPreCap > r->preCapacity) {
- size_t newCapacity = expandedSize(requiredPreCap, r->capacity);
- int delta = newCapacity - r->capacity - r->preCapacity;
+ if (requiredPreCap > base->preCapacity) {
+ size_t newCapacity = expandedSize(requiredPreCap, base->capacity);
+ int delta = newCapacity - base->capacity - base->preCapacity;
UChar* newBuf = allocChars(newCapacity);
if (!newBuf) {
makeNull();
return;
}
- copyChars(newBuf + delta, r->buf, r->capacity + r->preCapacity);
- fastFree(r->buf);
- r->buf = newBuf;
+ copyChars(newBuf + delta, base->buf, base->capacity + base->preCapacity);
+ fastFree(base->buf);
+ base->buf = newBuf;
- r->preCapacity = newCapacity - r->capacity;
+ base->preCapacity = newCapacity - base->capacity;
}
- if (requiredPreCap > r->usedPreCapacity)
- r->usedPreCapacity = requiredPreCap;
+ if (requiredPreCap > base->usedPreCapacity)
+ base->usedPreCapacity = requiredPreCap;
m_rep->checkConsistency();
}
-PassRefPtr<UString::Rep> createRep(const char* c)
+static PassRefPtr<UString::Rep> createRep(const char* c)
{
if (!c)
- return &UString::Rep::null;
+ return &UString::Rep::null();
if (!c[0])
- return &UString::Rep::empty;
+ return &UString::Rep::empty();
size_t length = strlen(c);
UChar* d = allocChars(length);
if (!d)
- return &UString::Rep::null;
+ return &UString::Rep::null();
else {
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
@@ -519,7 +524,7 @@ UString::UString(const char* c)
UString::UString(const UChar* c, int length)
{
if (length == 0)
- m_rep = &Rep::empty;
+ m_rep = &Rep::empty();
else
m_rep = Rep::createCopying(c, length);
}
@@ -527,7 +532,7 @@ UString::UString(const UChar* c, int length)
UString::UString(UChar* c, int length, bool copy)
{
if (length == 0)
- m_rep = &Rep::empty;
+ m_rep = &Rep::empty();
else if (copy)
m_rep = Rep::createCopying(c, length);
else
@@ -537,7 +542,7 @@ UString::UString(UChar* c, int length, bool copy)
UString::UString(const Vector<UChar>& buffer)
{
if (!buffer.size())
- m_rep = &Rep::empty;
+ m_rep = &Rep::empty();
else
m_rep = Rep::createCopying(buffer.data(), buffer.size());
}
@@ -551,6 +556,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
int thisSize = rep->size();
int thisOffset = rep->offset;
int length = thisSize + tSize;
+ UString::BaseString* base = rep->baseString();
// possible cases:
if (tSize == 0) {
@@ -558,19 +564,19 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
} else if (thisSize == 0) {
// this is empty
rep = UString::Rep::createCopying(tData, tSize);
- } else if (rep->baseIsSelf() && rep->rc == 1) {
+ } else if (rep == base && rep->rc == 1) {
// this is direct and has refcount of 1 (so we can just alter it directly)
if (!expandCapacity(rep.get(), thisOffset + length))
- rep = &UString::Rep::null;
+ rep = &UString::Rep::null();
if (rep->data()) {
copyChars(rep->data() + thisSize, tData, tSize);
rep->len = length;
rep->_hash = 0;
}
- } else if (thisOffset + thisSize == rep->baseString->usedCapacity && thisSize >= minShareSize) {
+ } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
// this reaches the end of the buffer - extend it if it's long enough to append to
if (!expandCapacity(rep.get(), thisOffset + length))
- rep = &UString::Rep::null;
+ rep = &UString::Rep::null();
if (rep->data()) {
copyChars(rep->data() + thisSize, tData, tSize);
rep = UString::Rep::create(rep, 0, length);
@@ -580,12 +586,12 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
size_t newCapacity = expandedSize(length, 0);
UChar* d = allocChars(newCapacity);
if (!d)
- rep = &UString::Rep::null;
+ rep = &UString::Rep::null();
else {
copyChars(d, rep->data(), thisSize);
copyChars(d + thisSize, tData, tSize);
rep = UString::Rep::create(d, length);
- rep->capacity = newCapacity;
+ rep->baseString()->capacity = newCapacity;
}
}
@@ -604,6 +610,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
int thisOffset = rep->offset;
int tSize = static_cast<int>(strlen(t));
int length = thisSize + tSize;
+ UString::BaseString* base = rep->baseString();
// possible cases:
if (thisSize == 0) {
@@ -611,7 +618,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
rep = createRep(t);
} else if (tSize == 0) {
// t is empty, we'll just return *this below.
- } else if (rep->baseIsSelf() && rep->rc == 1) {
+ } else if (rep == base && rep->rc == 1) {
// this is direct and has refcount of 1 (so we can just alter it directly)
expandCapacity(rep.get(), thisOffset + length);
UChar* d = rep->data();
@@ -621,7 +628,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
rep->len = length;
rep->_hash = 0;
}
- } else if (thisOffset + thisSize == rep->baseString->usedCapacity && thisSize >= minShareSize) {
+ } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
// this string reaches the end of the buffer - extend it
expandCapacity(rep.get(), thisOffset + length);
UChar* d = rep->data();
@@ -635,13 +642,13 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
size_t newCapacity = expandedSize(length, 0);
UChar* d = allocChars(newCapacity);
if (!d)
- rep = &UString::Rep::null;
+ rep = &UString::Rep::null();
else {
copyChars(d, rep->data(), thisSize);
for (int i = 0; i < tSize; ++i)
d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend
rep = UString::Rep::create(d, length);
- rep->capacity = newCapacity;
+ rep->baseString()->capacity = newCapacity;
}
}
@@ -670,15 +677,17 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
if (bSize == 0)
return a;
- if (bSize == 1 && aOffset + aSize == a->baseString->usedCapacity && aOffset + length <= a->baseString->capacity) {
+ UString::BaseString* aBase = a->baseString();
+ if (bSize == 1 && aOffset + aSize == aBase->usedCapacity && aOffset + length <= aBase->capacity) {
// b is a single character (common fast case)
- a->baseString->usedCapacity = aOffset + length;
+ aBase->usedCapacity = aOffset + length;
a->data()[aSize] = b->data()[0];
return UString::Rep::create(a, 0, length);
}
- if (aOffset + aSize == a->baseString->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize &&
- (-bOffset != b->baseString->usedPreCapacity || aSize >= bSize)) {
+ UString::BaseString* bBase = b->baseString();
+ if (aOffset + aSize == aBase->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize
+ && (-bOffset != bBase->usedPreCapacity || aSize >= bSize)) {
// - a reaches the end of its buffer so it qualifies for shared append
// - also, it's at least a quarter the length of b - appending to a much shorter
// string does more harm than good
@@ -697,7 +706,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
return result;
}
- if (-bOffset == b->baseString->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize) {
+ if (-bOffset == bBase->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize) {
// - b reaches the beginning of its buffer so it qualifies for shared prepend
// - also, it's at least a quarter the length of a - prepending to a much shorter
// string does more harm than good
@@ -723,7 +732,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
copyChars(d, a->data(), aSize);
copyChars(d + aSize, b->data(), bSize);
PassRefPtr<UString::Rep> result = UString::Rep::create(d, length);
- result->capacity = newCapacity;
+ result->baseString()->capacity = newCapacity;
a->checkConsistency();
b->checkConsistency();
@@ -775,7 +784,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d)
int decimalPoint;
int sign;
- char* result = dtoa(d, 0, &decimalPoint, &sign, NULL);
+ char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);
int length = static_cast<int>(strlen(result));
int i = 0;
@@ -826,17 +835,11 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d)
buf[i++] = '\0';
}
- freedtoa(result);
+ WTF::freedtoa(result);
return concatenate(rep, buf);
}
-const UString& UString::null()
-{
- static UString* n = new UString; // Should be called from main thread at least once to be safely initialized.
- return *n;
-}
-
UString UString::from(int i)
{
UChar buf[1 + sizeof(i) * 3];
@@ -923,7 +926,7 @@ UString UString::from(double d)
int decimalPoint;
int sign;
- char* result = dtoa(d, 0, &decimalPoint, &sign, NULL);
+ char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);
int length = static_cast<int>(strlen(result));
int i = 0;
@@ -974,7 +977,7 @@ UString UString::from(double d)
buf[i++] = '\0';
}
- freedtoa(result);
+ WTF::freedtoa(result);
return UString(buf);
}
@@ -1030,6 +1033,7 @@ UString& UString::append(const UString &t)
int thisOffset = m_rep->offset;
int tSize = t.size();
int length = thisSize + tSize;
+ BaseString* base = m_rep->baseString();
// possible cases:
if (thisSize == 0) {
@@ -1037,7 +1041,7 @@ UString& UString::append(const UString &t)
*this = t;
} else if (tSize == 0) {
// t is empty
- } else if (m_rep->baseIsSelf() && m_rep->rc == 1) {
+ } else if (m_rep == base && m_rep->rc == 1) {
// this is direct and has refcount of 1 (so we can just alter it directly)
expandCapacity(thisOffset + length);
if (data()) {
@@ -1045,7 +1049,7 @@ UString& UString::append(const UString &t)
m_rep->len = length;
m_rep->_hash = 0;
}
- } else if (thisOffset + thisSize == usedCapacity() && thisSize >= minShareSize) {
+ } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
// this reaches the end of the buffer - extend it if it's long enough to append to
expandCapacity(thisOffset + length);
if (data()) {
@@ -1062,7 +1066,7 @@ UString& UString::append(const UString &t)
copyChars(d, data(), thisSize);
copyChars(d + thisSize, t.data(), tSize);
m_rep = Rep::create(d, length);
- m_rep->capacity = newCapacity;
+ m_rep->baseString()->capacity = newCapacity;
}
}
@@ -1090,6 +1094,7 @@ UString& UString::append(UChar c)
int thisOffset = m_rep->offset;
int length = size();
+ BaseString* base = m_rep->baseString();
// possible cases:
if (length == 0) {
@@ -1101,9 +1106,9 @@ UString& UString::append(UChar c)
else {
d[0] = c;
m_rep = Rep::create(d, 1);
- m_rep->capacity = newCapacity;
+ m_rep->baseString()->capacity = newCapacity;
}
- } else if (m_rep->baseIsSelf() && m_rep->rc == 1) {
+ } else if (m_rep == base && m_rep->rc == 1) {
// this is direct and has refcount of 1 (so we can just alter it directly)
expandCapacity(thisOffset + length + 1);
UChar* d = m_rep->data();
@@ -1112,7 +1117,7 @@ UString& UString::append(UChar c)
m_rep->len = length + 1;
m_rep->_hash = 0;
}
- } else if (thisOffset + length == usedCapacity() && length >= minShareSize) {
+ } else if (thisOffset + length == base->usedCapacity && length >= minShareSize) {
// this reaches the end of the string - extend it and share
expandCapacity(thisOffset + length + 1);
UChar* d = m_rep->data();
@@ -1130,7 +1135,7 @@ UString& UString::append(UChar c)
copyChars(d, data(), length);
d[length] = c;
m_rep = Rep::create(d, length + 1);
- m_rep->capacity = newCapacity;
+ m_rep->baseString()->capacity = newCapacity;
}
}
@@ -1185,19 +1190,20 @@ char* UString::ascii() const
UString& UString::operator=(const char* c)
{
if (!c) {
- m_rep = &Rep::null;
+ m_rep = &Rep::null();
return *this;
}
if (!c[0]) {
- m_rep = &Rep::empty;
+ m_rep = &Rep::empty();
return *this;
}
int l = static_cast<int>(strlen(c));
UChar* d;
- if (m_rep->rc == 1 && l <= m_rep->capacity && m_rep->baseIsSelf() && m_rep->offset == 0 && m_rep->preCapacity == 0) {
- d = m_rep->buf;
+ BaseString* base = m_rep->baseString();
+ if (m_rep->rc == 1 && l <= base->capacity && m_rep == base && m_rep->offset == 0 && base->preCapacity == 0) {
+ d = base->buf;
m_rep->_hash = 0;
m_rep->len = l;
} else {
@@ -1281,7 +1287,7 @@ double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) co
} else {
// regular number ?
char* end;
- d = strtod(c, &end);
+ d = WTF::strtod(c, &end);
if ((d != 0.0 || end != c) && d != Inf && d != -Inf) {
c = end;
} else {
@@ -1413,12 +1419,24 @@ uint32_t UString::toStrictUInt32(bool* ok) const
int UString::find(const UString& f, int pos) const
{
- int sz = size();
int fsz = f.size();
- if (sz < fsz)
- return -1;
+
if (pos < 0)
pos = 0;
+
+ if (fsz == 1) {
+ UChar ch = f[0];
+ const UChar* end = data() + size();
+ for (const UChar* c = data() + pos; c < end; c++) {
+ if (*c == ch)
+ return static_cast<int>(c - data());
+ }
+ return -1;
+ }
+
+ int sz = size();
+ if (sz < fsz)
+ return -1;
if (fsz == 0)
return pos;
const UChar* end = data() + sz - fsz;
@@ -1626,13 +1644,13 @@ CString UString::UTF8String(bool strict) const
// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
NEVER_INLINE void UString::makeNull()
{
- m_rep = &Rep::null;
+ m_rep = &Rep::null();
}
// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
NEVER_INLINE UString::Rep* UString::nullRep()
{
- return &Rep::null;
+ return &Rep::null();
}
} // namespace JSC
diff --git a/JavaScriptCore/kjs/ustring.h b/JavaScriptCore/runtime/UString.h
index f47b134..59a7665 100644
--- a/JavaScriptCore/kjs/ustring.h
+++ b/JavaScriptCore/runtime/UString.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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
@@ -19,15 +20,15 @@
*
*/
-#ifndef _KJS_USTRING_H_
-#define _KJS_USTRING_H_
+#ifndef UString_h
+#define UString_h
-#include "collector.h"
+#include "Collector.h"
#include <stdint.h>
#include <string.h>
#include <wtf/Assertions.h>
-#include <wtf/FastMalloc.h>
#include <wtf/PassRefPtr.h>
+#include <wtf/PtrAndFlags.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#include <wtf/unicode/Unicode.h>
@@ -71,11 +72,12 @@ namespace JSC {
typedef Vector<char, 32> CStringBuffer;
class UString {
- friend class CTI;
+ friend class JIT;
public:
- struct Rep {
- friend class CTI;
+ struct BaseString;
+ struct Rep : Noncopyable {
+ friend class JIT;
static PassRefPtr<Rep> create(UChar*, int);
static PassRefPtr<Rep> createCopying(const UChar*, int);
@@ -87,8 +89,8 @@ namespace JSC {
void destroy();
- bool baseIsSelf() const { return baseString == this; }
- UChar* data() const { return baseString->buf + baseString->preCapacity + offset; }
+ bool baseIsSelf() const { return m_identifierTableAndFlags.isFlagSet(BaseStringFlag); }
+ UChar* data() const;
int size() const { return len; }
unsigned hash() const { if (_hash == 0) _hash = computeHash(data(), len); return _hash; }
@@ -98,35 +100,55 @@ namespace JSC {
static unsigned computeHash(const char*, int length);
static unsigned computeHash(const char* s) { return computeHash(s, strlen(s)); }
- IdentifierTable* identifierTable() const { return reinterpret_cast<IdentifierTable*>(m_identifierTable & ~static_cast<uintptr_t>(1)); }
- void setIdentifierTable(IdentifierTable* table) { ASSERT(!isStatic()); m_identifierTable = reinterpret_cast<intptr_t>(table); }
+ IdentifierTable* identifierTable() const { return m_identifierTableAndFlags.get(); }
+ void setIdentifierTable(IdentifierTable* table) { ASSERT(!isStatic()); m_identifierTableAndFlags.set(table); }
- bool isStatic() const { return m_identifierTable & 1; }
- void setStatic(bool v) { ASSERT(!identifierTable()); m_identifierTable = v; }
+ bool isStatic() const { return m_identifierTableAndFlags.isFlagSet(StaticFlag); }
+ void setStatic(bool);
+ void setBaseString(PassRefPtr<BaseString>);
+ BaseString* baseString();
+ const BaseString* baseString() const;
Rep* ref() { ++rc; return this; }
ALWAYS_INLINE void deref() { if (--rc == 0) destroy(); }
void checkConsistency() const;
+ enum UStringFlags {
+ StaticFlag,
+ BaseStringFlag
+ };
// unshared data
int offset;
int len;
int rc; // For null and empty static strings, this field does not reflect a correct count, because ref/deref are not thread-safe. A special case in destroy() guarantees that these do not get deleted.
mutable unsigned _hash;
- intptr_t m_identifierTable; // A pointer to identifier table. The lowest bit is used to indicate whether the string is static (null or empty).
- UString::Rep* baseString;
- size_t reportedCost;
+ PtrAndFlags<IdentifierTable, UStringFlags> m_identifierTableAndFlags;
+ void* m_baseString; // If "this" is a BaseString instance, it is 0. BaseString* otherwise.
+
+ static BaseString& null() { return *nullBaseString; }
+ static BaseString& empty() { return *emptyBaseString; }
+
+ private:
+ friend void initializeUString();
+ static BaseString* nullBaseString;
+ static BaseString* emptyBaseString;
+ };
- // potentially shared data. 0 if backed up by a base string.
+ struct BaseString : public Rep {
+ BaseString()
+ {
+ m_identifierTableAndFlags.setFlag(BaseStringFlag);
+ }
+
+ // potentially shared data.
UChar* buf;
- int usedCapacity;
- int capacity;
- int usedPreCapacity;
int preCapacity;
+ int usedPreCapacity;
+ int capacity;
+ int usedCapacity;
- static Rep null;
- static Rep empty;
+ size_t reportedCost;
};
public:
@@ -204,7 +226,7 @@ namespace JSC {
const UChar* data() const { return m_rep->data(); }
- bool isNull() const { return (m_rep == &Rep::null); }
+ bool isNull() const { return (m_rep == &Rep::null()); }
bool isEmpty() const { return (!m_rep->len); }
bool is8Bit() const;
@@ -230,7 +252,7 @@ namespace JSC {
UString substr(int pos = 0, int len = -1) const;
- static const UString& null();
+ static const UString& null() { return *nullUString; }
Rep* rep() const { return m_rep.get(); }
static Rep* nullRep();
@@ -244,14 +266,14 @@ namespace JSC {
size_t cost() const;
private:
- int usedCapacity() const;
- int usedPreCapacity() const;
void expandCapacity(int requiredLength);
void expandPreCapacity(int requiredPreCap);
void makeNull();
RefPtr<Rep> m_rep;
+ static UString* nullUString;
+ friend void initializeUString();
friend bool operator==(const UString&, const UString&);
friend PassRefPtr<Rep> concatenate(Rep*, Rep*); // returns 0 if out of memory
};
@@ -298,6 +320,37 @@ namespace JSC {
bool equal(const UString::Rep*, const UString::Rep*);
+ inline UChar* UString::Rep::data() const
+ {
+ const BaseString* base = baseString();
+ return base->buf + base->preCapacity + offset;
+ }
+
+ inline void UString::Rep::setStatic(bool v)
+ {
+ ASSERT(!identifierTable());
+ if (v)
+ m_identifierTableAndFlags.setFlag(StaticFlag);
+ else
+ m_identifierTableAndFlags.clearFlag(StaticFlag);
+ }
+
+ inline void UString::Rep::setBaseString(PassRefPtr<BaseString> base)
+ {
+ ASSERT(base != this);
+ m_baseString = base.releaseRef();
+ }
+
+ inline UString::BaseString* UString::Rep::baseString()
+ {
+ return reinterpret_cast<BaseString*>(baseIsSelf() ? this : m_baseString);
+ }
+
+ inline const UString::BaseString* UString::Rep::baseString() const
+ {
+ return const_cast<const BaseString*>(const_cast<Rep*>(this)->baseString());
+ }
+
#ifdef NDEBUG
inline void UString::Rep::checkConsistency() const
{
@@ -305,7 +358,7 @@ namespace JSC {
#endif
inline UString::UString()
- : m_rep(&Rep::null)
+ : m_rep(&Rep::null())
{
}
@@ -328,8 +381,9 @@ namespace JSC {
inline size_t UString::cost() const
{
- size_t capacity = (m_rep->baseString->capacity + m_rep->baseString->preCapacity) * sizeof(UChar);
- size_t reportedCost = m_rep->baseString->reportedCost;
+ BaseString* base = m_rep->baseString();
+ size_t capacity = (base->capacity + base->preCapacity) * sizeof(UChar);
+ size_t reportedCost = base->reportedCost;
ASSERT(capacity >= reportedCost);
size_t capacityDelta = capacity - reportedCost;
@@ -337,7 +391,7 @@ namespace JSC {
if (capacityDelta < static_cast<size_t>(minShareSize))
return 0;
- m_rep->baseString->reportedCost = capacity;
+ base->reportedCost = capacity;
return capacityDelta;
}
@@ -347,6 +401,7 @@ namespace JSC {
static unsigned hash(JSC::UString::Rep* key) { return key->computedHash(); }
};
+ void initializeUString();
} // namespace JSC
namespace WTF {
diff --git a/JavaScriptCore/tests/mozilla/js1_5/Array/regress-157652.js b/JavaScriptCore/tests/mozilla/js1_5/Array/regress-157652.js
index 7c61686..226b871 100644
--- a/JavaScriptCore/tests/mozilla/js1_5/Array/regress-157652.js
+++ b/JavaScriptCore/tests/mozilla/js1_5/Array/regress-157652.js
@@ -116,7 +116,7 @@ var summary = "Testing that Array.sort() doesn't crash on very large arrays";
printBugNumber(bug);
printStatus(summary);
-// KJS doesn't run out of memory, so we don't expect an abnormal exit code
+// JSC doesn't run out of memory, so we don't expect an abnormal exit code
//expectExitCode(3);
var IN_RHINO = inRhino();
diff --git a/JavaScriptCore/wrec/CharacterClass.cpp b/JavaScriptCore/wrec/CharacterClass.cpp
new file mode 100644
index 0000000..e3f12f2
--- /dev/null
+++ b/JavaScriptCore/wrec/CharacterClass.cpp
@@ -0,0 +1,140 @@
+/*
+ * 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/CharacterClass.h b/JavaScriptCore/wrec/CharacterClass.h
new file mode 100644
index 0000000..8a9d2fc
--- /dev/null
+++ b/JavaScriptCore/wrec/CharacterClass.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CharacterClass_h
+#define CharacterClass_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(WREC)
+
+#include <wtf/unicode/Unicode.h>
+
+namespace JSC { namespace WREC {
+
+ struct CharacterRange {
+ UChar begin;
+ UChar end;
+ };
+
+ struct CharacterClass {
+ static const CharacterClass& newline();
+ static const CharacterClass& digits();
+ static const CharacterClass& spaces();
+ static const CharacterClass& wordchar();
+ static const CharacterClass& nondigits();
+ static const CharacterClass& nonspaces();
+ static const CharacterClass& nonwordchar();
+
+ const UChar* matches;
+ unsigned numMatches;
+
+ const CharacterRange* ranges;
+ unsigned numRanges;
+
+ const UChar* matchesUnicode;
+ unsigned numMatchesUnicode;
+
+ const CharacterRange* rangesUnicode;
+ unsigned numRangesUnicode;
+ };
+
+} } // namespace JSC::WREC
+
+#endif // ENABLE(WREC)
+
+#endif // CharacterClass_h
diff --git a/JavaScriptCore/wrec/CharacterClassConstructor.cpp b/JavaScriptCore/wrec/CharacterClassConstructor.cpp
index 85eccaa..06f4262 100644
--- a/JavaScriptCore/wrec/CharacterClassConstructor.cpp
+++ b/JavaScriptCore/wrec/CharacterClassConstructor.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,110 +33,7 @@
using namespace WTF;
-namespace JSC {
-
-static const UChar asciiNewlines[2] = { '\n', '\r' };
-static const UChar unicodeNewlines[2] = { 0x2028, 0x2029 };
-CharacterClass& getCharacterClassNewline() {
- static CharacterClass charClass = {
- asciiNewlines, 2,
- 0, 0,
- unicodeNewlines, 2,
- 0, 0,
- };
-
- return charClass;
-}
-
-static const CharacterClassRange asciiDigitsRange[1] = { { '0', '9' } };
-CharacterClass& getCharacterClassDigits() {
- static CharacterClass charClass = {
- 0, 0,
- asciiDigitsRange, 1,
- 0, 0,
- 0, 0,
- };
-
- return charClass;
-}
-
-static const UChar asciiSpaces[1] = { ' ' };
-static const CharacterClassRange asciiSpacesRange[1] = { { '\t', '\r' } };
-static const UChar unicodeSpaces[8] = { 0x00a0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000 };
-static const CharacterClassRange unicodeSpacesRange[1] = { { 0x2000, 0x200a } };
-CharacterClass& getCharacterClassSpaces() {
- static CharacterClass charClass = {
- asciiSpaces, 1,
- asciiSpacesRange, 1,
- unicodeSpaces, 8,
- unicodeSpacesRange, 1,
- };
-
- return charClass;
-}
-
-static const UChar asciiWordchar[1] = { '_' };
-static const CharacterClassRange asciiWordcharRange[3] = { { '0', '9' }, { 'A', 'Z' }, { 'a', 'z' } };
-CharacterClass& getCharacterClassWordchar() {
- static CharacterClass charClass = {
- asciiWordchar, 1,
- asciiWordcharRange, 3,
- 0, 0,
- 0, 0,
- };
-
- return charClass;
-}
-
-static const CharacterClassRange asciiNondigitsRange[2] = { { 0, '0' - 1 }, { '9' + 1, 0x7f } };
-static const CharacterClassRange unicodeNondigitsRange[1] = { { 0x0080, 0xffff } };
-CharacterClass& getCharacterClassNondigits() {
- static CharacterClass charClass = {
- 0, 0,
- asciiNondigitsRange, 2,
- 0, 0,
- unicodeNondigitsRange, 1,
- };
-
- return charClass;
-}
-
-static const CharacterClassRange asciiNonspacesRange[3] = { { 0, '\t' - 1 }, { '\r' + 1, ' ' - 1 }, { ' ' + 1, 0x7f } };
-static const CharacterClassRange unicodeNonspacesRange[9] = {
- { 0x0080, 0x009f },
- { 0x00a1, 0x167f },
- { 0x1681, 0x180d },
- { 0x180f, 0x1fff },
- { 0x200b, 0x2027 },
- { 0x202a, 0x202e },
- { 0x2030, 0x205e },
- { 0x2060, 0x2fff },
- { 0x3001, 0xffff }
-};
-CharacterClass& getCharacterClassNonspaces() {
- static CharacterClass charClass = {
- 0, 0,
- asciiNonspacesRange, 3,
- 0, 0,
- unicodeNonspacesRange, 9,
- };
-
- return charClass;
-}
-
-static const UChar asciiNonwordchar[1] = { '`' };
-static const CharacterClassRange asciiNonwordcharRange[4] = { { 0, '0' - 1 }, { '9' + 1, 'A' - 1 }, { 'Z' + 1, '_' - 1 }, { 'z' + 1, 0x7f } };
-static const CharacterClassRange unicodeNonwordcharRange[1] = { { 0x0080, 0xffff } };
-CharacterClass& getCharacterClassNonwordchar() {
- static CharacterClass charClass = {
- asciiNonwordchar, 1,
- asciiNonwordcharRange, 4,
- 0, 0,
- unicodeNonwordcharRange, 1,
- };
-
- return charClass;
-}
+namespace JSC { namespace WREC {
void CharacterClassConstructor::addSorted(Vector<UChar>& matches, UChar ch)
{
@@ -164,7 +61,7 @@ void CharacterClassConstructor::addSorted(Vector<UChar>& matches, UChar ch)
matches.insert(pos, ch);
}
-void CharacterClassConstructor::addSortedRange(Vector<CharacterClassRange>& ranges, UChar lo, UChar hi)
+void CharacterClassConstructor::addSortedRange(Vector<CharacterRange>& ranges, UChar lo, UChar hi)
{
unsigned end = ranges.size();
@@ -178,7 +75,7 @@ void CharacterClassConstructor::addSortedRange(Vector<CharacterClassRange>& rang
ranges[i].begin = lo;
return;
}
- CharacterClassRange r = {lo, hi};
+ CharacterRange r = {lo, hi};
ranges.insert(i, r);
return;
}
@@ -206,8 +103,8 @@ void CharacterClassConstructor::addSortedRange(Vector<CharacterClassRange>& rang
}
}
- // Range comes after all existing ranges.
- CharacterClassRange r = {lo, hi};
+ // CharacterRange comes after all existing ranges.
+ CharacterRange r = {lo, hi};
ranges.append(r);
}
@@ -260,19 +157,19 @@ void CharacterClassConstructor::put(UChar ch)
// 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 (; kjs_pcre_ucp_othercase(unicodeCurr) == -1; ++unicodeCurr) {
+ 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 = kjs_pcre_ucp_othercase(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) && (kjs_pcre_ucp_othercase(unicodeCurr + 1) == (otherCurr + 1))) {
+ 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;
@@ -317,7 +214,7 @@ void CharacterClassConstructor::flush()
} else {
addSorted(m_matchesUnicode, m_charBuffer);
if (m_isCaseInsensitive) {
- int other = kjs_pcre_ucp_othercase(m_charBuffer);
+ int other = jsc_pcre_ucp_othercase(m_charBuffer);
if (other != -1)
addSorted(m_matchesUnicode, other);
}
@@ -331,7 +228,7 @@ void CharacterClassConstructor::flush()
}
}
-void CharacterClassConstructor::append(CharacterClass& other)
+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.
@@ -355,6 +252,6 @@ void CharacterClassConstructor::append(CharacterClass& other)
}
}
-}
+} } // namespace JSC::WREC
#endif // ENABLE(WREC)
diff --git a/JavaScriptCore/wrec/CharacterClassConstructor.h b/JavaScriptCore/wrec/CharacterClassConstructor.h
index 5accdae..581733d 100644
--- a/JavaScriptCore/wrec/CharacterClassConstructor.h
+++ b/JavaScriptCore/wrec/CharacterClassConstructor.h
@@ -26,38 +26,16 @@
#ifndef CharacterClassConstructor_h
#define CharacterClassConstructor_h
-#if ENABLE(WREC)
-
-#include "ustring.h"
-
-namespace JSC {
-
- struct CharacterClassRange {
- UChar begin;
- UChar end;
- };
+#include <wtf/Platform.h>
- struct CharacterClass {
- const UChar* matches;
- unsigned numMatches;
-
- const CharacterClassRange* ranges;
- unsigned numRanges;
-
- const UChar* matchesUnicode;
- unsigned numMatchesUnicode;
+#if ENABLE(WREC)
- const CharacterClassRange* rangesUnicode;
- unsigned numRangesUnicode;
- };
+#include "CharacterClass.h"
+#include <wtf/AlwaysInline.h>
+#include <wtf/Vector.h>
+#include <wtf/unicode/Unicode.h>
- CharacterClass& getCharacterClassNewline();
- CharacterClass& getCharacterClassDigits();
- CharacterClass& getCharacterClassSpaces();
- CharacterClass& getCharacterClassWordchar();
- CharacterClass& getCharacterClassNondigits();
- CharacterClass& getCharacterClassNonspaces();
- CharacterClass& getCharacterClassNonwordchar();
+namespace JSC { namespace WREC {
class CharacterClassConstructor {
public:
@@ -83,7 +61,7 @@ namespace JSC {
}
void put(UChar ch);
- void append(CharacterClass& other);
+ void append(const CharacterClass& other);
bool isUpsideDown() { return m_isUpsideDown; }
@@ -101,7 +79,7 @@ namespace JSC {
private:
void addSorted(Vector<UChar>& matches, UChar ch);
- void addSortedRange(Vector<CharacterClassRange>& ranges, UChar lo, UChar hi);
+ void addSortedRange(Vector<CharacterRange>& ranges, UChar lo, UChar hi);
int m_charBuffer;
bool m_isPendingDash;
@@ -109,12 +87,12 @@ namespace JSC {
bool m_isUpsideDown;
Vector<UChar> m_matches;
- Vector<CharacterClassRange> m_ranges;
+ Vector<CharacterRange> m_ranges;
Vector<UChar> m_matchesUnicode;
- Vector<CharacterClassRange> m_rangesUnicode;
+ Vector<CharacterRange> m_rangesUnicode;
};
-}
+} } // namespace JSC::WREC
#endif // ENABLE(WREC)
diff --git a/JavaScriptCore/wrec/Escapes.h b/JavaScriptCore/wrec/Escapes.h
new file mode 100644
index 0000000..16c1d6f
--- /dev/null
+++ b/JavaScriptCore/wrec/Escapes.h
@@ -0,0 +1,150 @@
+/*
+ * 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/Quantifier.h b/JavaScriptCore/wrec/Quantifier.h
new file mode 100644
index 0000000..3da74cd
--- /dev/null
+++ b/JavaScriptCore/wrec/Quantifier.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Quantifier_h
+#define Quantifier_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(WREC)
+
+#include <wtf/Assertions.h>
+#include <limits.h>
+
+namespace JSC { namespace WREC {
+
+ struct Quantifier {
+ enum Type {
+ None,
+ Greedy,
+ NonGreedy,
+ Error,
+ };
+
+ Quantifier(Type type = None, unsigned min = 0, unsigned max = Infinity)
+ : type(type)
+ , min(min)
+ , max(max)
+ {
+ ASSERT(min <= max);
+ }
+
+ Type type;
+
+ unsigned min;
+ unsigned max;
+
+ static const unsigned Infinity = UINT_MAX;
+ };
+
+} } // namespace JSC::WREC
+
+#endif // ENABLE(WREC)
+
+#endif // Quantifier_h
diff --git a/JavaScriptCore/wrec/WREC.cpp b/JavaScriptCore/wrec/WREC.cpp
index 6d64a2c..099931b 100644
--- a/JavaScriptCore/wrec/WREC.cpp
+++ b/JavaScriptCore/wrec/WREC.cpp
@@ -29,1296 +29,61 @@
#if ENABLE(WREC)
#include "CharacterClassConstructor.h"
-#include "Machine.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 JSC { namespace WREC {
-class GenerateAtomFunctor {
-public:
- virtual ~GenerateAtomFunctor() {}
+// Patterns longer than this can hang the compiler.
+static const int MaxPatternSize = (1 << 13);
- virtual void generateAtom(WRECGenerator*, JmpSrcVector&) = 0;
- virtual void backtrack(WRECGenerator*) = 0;
-};
-
-class GeneratePatternCharacterFunctor : public GenerateAtomFunctor {
-public:
- GeneratePatternCharacterFunctor(const UChar ch)
- : m_ch(ch)
- {
- }
-
- virtual void generateAtom(WRECGenerator*, JmpSrcVector&);
- virtual void backtrack(WRECGenerator*);
-
-private:
- const UChar m_ch;
-};
-
-class GenerateCharacterClassFunctor : public GenerateAtomFunctor {
-public:
- GenerateCharacterClassFunctor(CharacterClass* charClass, bool invert)
- : m_charClass(charClass)
- , m_invert(invert)
- {
- }
-
- virtual void generateAtom(WRECGenerator*, JmpSrcVector&);
- virtual void backtrack(WRECGenerator*);
-
-private:
- CharacterClass* m_charClass;
- bool m_invert;
-};
-
-class GenerateBackreferenceFunctor : public GenerateAtomFunctor {
-public:
- GenerateBackreferenceFunctor(unsigned subpatternId)
- : m_subpatternId(subpatternId)
- {
- }
-
- virtual void generateAtom(WRECGenerator*, JmpSrcVector&);
- virtual void backtrack(WRECGenerator*);
-
-private:
- unsigned m_subpatternId;
-};
-
-class GenerateParenthesesNonGreedyFunctor : public GenerateAtomFunctor {
-public:
- GenerateParenthesesNonGreedyFunctor(WRECGenerator::JmpDst start, WRECGenerator::JmpSrc success, WRECGenerator::JmpSrc fail)
- : m_start(start)
- , m_success(success)
- , m_fail(fail)
- {
- }
-
- virtual void generateAtom(WRECGenerator*, JmpSrcVector&);
- virtual void backtrack(WRECGenerator*);
-
-private:
- WRECGenerator::JmpDst m_start;
- WRECGenerator::JmpSrc m_success;
- WRECGenerator::JmpSrc m_fail;
-};
-
-void GeneratePatternCharacterFunctor::generateAtom(WRECGenerator* wrec, JmpSrcVector& failures)
-{
- wrec->generatePatternCharacter(failures, m_ch);
-}
-void GeneratePatternCharacterFunctor::backtrack(WRECGenerator* wrec)
+CompiledRegExp Generator::compileRegExp(JSGlobalData* globalData, const UString& pattern, unsigned* numSubpatterns_ptr, const char** error_ptr, RefPtr<ExecutablePool>& pool, bool ignoreCase, bool multiline)
{
- wrec->generateBacktrack1();
-}
-
-void GenerateCharacterClassFunctor::generateAtom(WRECGenerator* wrec, JmpSrcVector& failures)
-{
- wrec->generateCharacterClass(failures, *m_charClass, m_invert);
-}
-void GenerateCharacterClassFunctor::backtrack(WRECGenerator* wrec)
-{
- wrec->generateBacktrack1();
-}
-
-void GenerateBackreferenceFunctor::generateAtom(WRECGenerator* wrec, JmpSrcVector& failures)
-{
- wrec->generateBackreference(failures, m_subpatternId);
-}
-void GenerateBackreferenceFunctor::backtrack(WRECGenerator* wrec)
-{
- wrec->generateBacktrackBackreference(m_subpatternId);
-}
-
-void GenerateParenthesesNonGreedyFunctor::generateAtom(WRECGenerator* wrec, JmpSrcVector& failures)
-{
- wrec->generateParenthesesNonGreedy(failures, m_start, m_success, m_fail);
-}
-
-void GenerateParenthesesNonGreedyFunctor::backtrack(WRECGenerator*)
-{
- // FIXME: do something about this.
- CRASH();
-}
-
-void WRECGenerator::generateBacktrack1()
-{
- m_jit.subl_i8r(1, currentPositionRegister);
-}
-
-void WRECGenerator::generateBacktrackBackreference(unsigned subpatternId)
-{
- m_jit.subl_mr((2 * subpatternId + 1) * sizeof(int), outputRegister, currentPositionRegister);
- m_jit.addl_mr((2 * subpatternId) * sizeof(int), outputRegister, currentPositionRegister);
-}
-
-void WRECGenerator::generateBackreferenceQuantifier(JmpSrcVector& failures, Quantifier::Type quantifierType, unsigned subpatternId, unsigned min, unsigned max)
-{
- GenerateBackreferenceFunctor functor(subpatternId);
-
- m_jit.movl_mr((2 * subpatternId) * sizeof(int), outputRegister, currentValueRegister);
- m_jit.cmpl_rm(currentValueRegister, ((2 * subpatternId) + 1) * sizeof(int), outputRegister);
- JmpSrc skipIfEmpty = m_jit.emitUnlinkedJe();
-
- ASSERT(quantifierType == Quantifier::Greedy || quantifierType == Quantifier::NonGreedy);
- if (quantifierType == Quantifier::Greedy)
- generateGreedyQuantifier(failures, functor, min, max);
- else
- generateNonGreedyQuantifier(failures, functor, min, max);
-
- m_jit.link(skipIfEmpty, m_jit.label());
-}
-
-void WRECGenerator::generateNonGreedyQuantifier(JmpSrcVector& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max)
-{
- // comment me better!
- JmpSrcVector newFailures;
-
- // (0) Setup:
- // init quantifierCountRegister
- m_jit.pushl_r(quantifierCountRegister);
- m_jit.xorl_rr(quantifierCountRegister, quantifierCountRegister);
- JmpSrc gotoStart = m_jit.emitUnlinkedJmp();
-
- // (4) Failure case
-
- JmpDst quantifierFailed = m_jit.label();
- // (4.1) Restore original value of quantifierCountRegister from the stack
- m_jit.popl_r(quantifierCountRegister);
- failures.append(m_jit.emitUnlinkedJmp());
-
- // (3) We just tried an alternative, and it failed - check we can try more.
-
- JmpDst alternativeFailed = m_jit.label();
- // (3.1) remove the value pushed prior to testing the alternative
- m_jit.popl_r(currentPositionRegister);
- // (3.2) if there is a limit, and we have reached it, game over.
- if (max != Quantifier::noMaxSpecified) {
- m_jit.cmpl_i32r(max, quantifierCountRegister);
- m_jit.link(m_jit.emitUnlinkedJe(), quantifierFailed);
+ if (pattern.size() > MaxPatternSize) {
+ *error_ptr = "regular expression too large";
+ return 0;
}
- // (1) Do a check for the atom
+ Parser parser(pattern, ignoreCase, multiline);
+ Generator& generator = parser.generator();
+ MacroAssembler::JumpList failures;
+ MacroAssembler::Jump endOfInput;
- // (1.0) This is where we start, if there is a minimum (then we must read at least one of the atom).
- JmpDst testQuantifiedAtom = m_jit.label();
- if (min)
- m_jit.link(gotoStart, testQuantifiedAtom);
- // (1.1) Do a check for the atom check.
- functor.generateAtom(this, newFailures);
- // (1.2) If we get here, successful match!
- m_jit.addl_i8r(1, quantifierCountRegister);
- // (1.3) We needed to read the atom, and we failed - that's terminally bad news.
- for (unsigned i = 0; i < newFailures.size(); ++i)
- m_jit.link(newFailures[i], quantifierFailed);
- newFailures.clear();
- // (1.4) If there is a minimum, check we have read enough ...
- if (min) {
- // ... except if min was 1 no need to keep checking!
- if (min != 1) {
- m_jit.cmpl_i32r(min, quantifierCountRegister);
- m_jit.link(m_jit.emitUnlinkedJl(), testQuantifiedAtom);
- }
- } else
- m_jit.link(gotoStart, m_jit.label());
- // if there was no minimum, this is where we start.
+ generator.generateEnter();
+ generator.generateSaveIndex();
- // (2) Plant an alternative check for the remainder of the expression
-
- // (2.1) recursively call to parseAlternative, if it falls through, success!
- m_jit.pushl_r(currentPositionRegister);
- m_parser.parseAlternative(newFailures);
- m_jit.addl_i8r(4, X86::esp);
- m_jit.popl_r(quantifierCountRegister);
- // (2.2) link failure cases to jump back up to alternativeFailed.
- for (unsigned i = 0; i < newFailures.size(); ++i)
- m_jit.link(newFailures[i], alternativeFailed);
- newFailures.clear();
-}
-
-void WRECGenerator::generateGreedyQuantifier(JmpSrcVector& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max)
-{
- if (!max)
- return;
-
- // comment me better!
- JmpSrcVector newFailures;
-
- // (0) Setup:
- // init quantifierCountRegister
- m_jit.pushl_r(quantifierCountRegister);
- m_jit.xorl_rr(quantifierCountRegister, quantifierCountRegister);
-
- // (1) Greedily read as many of the atom as possible
-
- JmpDst readMore = m_jit.label();
-
- // (1.1) Do a character class check.
- functor.generateAtom(this, newFailures);
- // (1.2) If we get here, successful match!
- m_jit.addl_i8r(1, quantifierCountRegister);
- // (1.3) loop, unless we've read max limit.
- if (max != Quantifier::noMaxSpecified) {
- if (max != 1) {
- // if there is a limit, only loop while less than limit, otherwise fall throught to...
- m_jit.cmpl_i32r(max, quantifierCountRegister);
- m_jit.link(m_jit.emitUnlinkedJne(), readMore);
- }
- // ...if there is no min we need jump to the alternative test, if there is we can just fall through to it.
- if (!min)
- newFailures.append(m_jit.emitUnlinkedJmp());
- } else
- m_jit.link(m_jit.emitUnlinkedJmp(), readMore);
- // (1.4) check enough matches to bother trying an alternative...
- if (min) {
- // We will fall through to here if (min && max), after the max check.
- // First, also link a
- JmpDst minimumTest = m_jit.label();
- for (unsigned i = 0; i < newFailures.size(); ++i)
- m_jit.link(newFailures[i], minimumTest);
- newFailures.clear();
- //
- m_jit.cmpl_i32r(min, quantifierCountRegister);
- newFailures.append(m_jit.emitUnlinkedJae());
- }
-
- // (4) Failure case
-
- JmpDst quantifierFailed = m_jit.label();
- // (4.1) Restore original value of quantifierCountRegister from the stack
- m_jit.popl_r(quantifierCountRegister);
- failures.append(m_jit.emitUnlinkedJmp());
-
- // (3) Backtrack
-
- JmpDst backtrack = m_jit.label();
- // (3.1) this was preserved prior to executing the alternative
- m_jit.popl_r(currentPositionRegister);
- // (3.2) check we can retry with fewer matches - backtracking fails if already at the minimum
- m_jit.cmpl_i32r(min, quantifierCountRegister);
- m_jit.link(m_jit.emitUnlinkedJe(), quantifierFailed);
- // (3.3) roll off one match, and retry.
- functor.backtrack(this);
- m_jit.subl_i8r(1, quantifierCountRegister);
+ Label beginPattern(&generator);
+ parser.parsePattern(failures);
+ generator.generateReturnSuccess();
- // (2) Try an alternative.
-
- // (2.1) point to retry
- JmpDst tryAlternative = m_jit.label();
- for (unsigned i = 0; i < newFailures.size(); ++i)
- m_jit.link(newFailures[i], tryAlternative);
- newFailures.clear();
- // (2.2) recursively call to parseAlternative, if it falls through, success!
- m_jit.pushl_r(currentPositionRegister);
- m_parser.parseAlternative(newFailures);
- m_jit.addl_i8r(4, X86::esp);
- m_jit.popl_r(quantifierCountRegister);
- // (2.3) link failure cases to here.
- for (unsigned i = 0; i < newFailures.size(); ++i)
- m_jit.link(newFailures[i], backtrack);
- newFailures.clear();
-}
-
-void WRECGenerator::generatePatternCharacter(JmpSrcVector& failures, int ch)
-{
- // check there is more input, read a char.
- m_jit.cmpl_rr(lengthRegister, currentPositionRegister);
- failures.append(m_jit.emitUnlinkedJe());
- m_jit.movzwl_mr(inputRegister, currentPositionRegister, 2, currentValueRegister);
+ failures.link(&generator);
+ generator.generateIncrementIndex(&endOfInput);
+ parser.parsePattern(failures);
+ generator.generateReturnSuccess();
- // used for unicode case insensitive
- bool hasUpper = false;
- JmpSrc isUpper;
+ failures.link(&generator);
+ generator.generateIncrementIndex();
+ generator.generateJumpIfNotEndOfInput(beginPattern);
- // if case insensitive match
- if (m_parser.m_ignoreCase) {
- UChar lower, upper;
-
- // check for ascii case sensitive characters
- if (isASCIIAlpha(ch)) {
- m_jit.orl_i32r(32, currentValueRegister);
- ch |= 32;
- } else if ((ch > 0x7f) && ((lower = Unicode::toLower(ch)) != (upper = Unicode::toUpper(ch)))) {
- // handle unicode case sentitive characters - branch to success on upper
- m_jit.cmpl_i32r(upper, currentValueRegister);
- isUpper = m_jit.emitUnlinkedJe();
- hasUpper = true;
- ch = lower;
- }
- }
-
- // checks for ch, or lower case version of ch, if insensitive
- m_jit.cmpl_i32r((unsigned short)ch, currentValueRegister);
- failures.append(m_jit.emitUnlinkedJne());
-
- if (m_parser.m_ignoreCase && hasUpper) {
- // for unicode case insensitive matches, branch here if upper matches.
- m_jit.link(isUpper, m_jit.label());
- }
-
- // on success consume the char
- m_jit.addl_i8r(1, currentPositionRegister);
-}
-
-void WRECGenerator::generateCharacterClassInvertedRange(JmpSrcVector& failures, JmpSrcVector& matchDest, const CharacterClassRange* 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;
-
- m_jit.cmpl_i32r((unsigned short)lo, currentValueRegister);
-
- // 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)) {
- JmpSrc loOrAbove = m_jit.emitUnlinkedJge();
-
- // generate code for all ranges before this one
- if (which)
- generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);
-
- do {
- m_jit.cmpl_i32r((unsigned short)matches[*matchIndex], currentValueRegister);
- matchDest.append(m_jit.emitUnlinkedJe());
- ++*matchIndex;
- } while ((*matchIndex < matchCount) && (matches[*matchIndex] < lo));
- failures.append(m_jit.emitUnlinkedJmp());
-
- m_jit.link(loOrAbove, m_jit.label());
- } else if (which) {
- JmpSrc loOrAbove = m_jit.emitUnlinkedJge();
-
- generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);
- failures.append(m_jit.emitUnlinkedJmp());
-
- m_jit.link(loOrAbove, m_jit.label());
- } else
- failures.append(m_jit.emitUnlinkedJl());
-
- while ((*matchIndex < matchCount) && (matches[*matchIndex] <= hi))
- ++*matchIndex;
-
- m_jit.cmpl_i32r((unsigned short)hi, currentValueRegister);
- matchDest.append(m_jit.emitUnlinkedJle());
- // 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 WRECGenerator::generateCharacterClassInverted(JmpSrcVector& matchDest, CharacterClass& charClass)
-{
- JmpSrc unicodeFail;
- if (charClass.numMatchesUnicode || charClass.numRangesUnicode) {
- m_jit.cmpl_i8r(0x7f, currentValueRegister);
- JmpSrc isAscii = m_jit.emitUnlinkedJle();
-
- if (charClass.numMatchesUnicode) {
- for (unsigned i = 0; i < charClass.numMatchesUnicode; ++i) {
- UChar ch = charClass.matchesUnicode[i];
- m_jit.cmpl_i32r((unsigned short)ch, currentValueRegister);
- matchDest.append(m_jit.emitUnlinkedJe());
- }
- }
-
- if (charClass.numRangesUnicode) {
- for (unsigned i = 0; i < charClass.numRangesUnicode; ++i) {
- UChar lo = charClass.rangesUnicode[i].begin;
- UChar hi = charClass.rangesUnicode[i].end;
-
- m_jit.cmpl_i32r((unsigned short)lo, currentValueRegister);
- JmpSrc below = m_jit.emitUnlinkedJl();
- m_jit.cmpl_i32r((unsigned short)hi, currentValueRegister);
- matchDest.append(m_jit.emitUnlinkedJle());
- m_jit.link(below, m_jit.label());
- }
- }
-
- unicodeFail = m_jit.emitUnlinkedJmp();
- m_jit.link(isAscii, m_jit.label());
- }
-
- if (charClass.numRanges) {
- unsigned matchIndex = 0;
- JmpSrcVector failures;
- generateCharacterClassInvertedRange(failures, matchDest, charClass.ranges, charClass.numRanges, &matchIndex, charClass.matches, charClass.numMatches);
- while (matchIndex < charClass.numMatches) {
- m_jit.cmpl_i32r((unsigned short)charClass.matches[matchIndex], currentValueRegister);
- matchDest.append(m_jit.emitUnlinkedJe());
- ++matchIndex;
- }
- JmpDst noMatch = m_jit.label();
- for (unsigned i = 0; i < failures.size(); ++i)
- m_jit.link(failures[i], noMatch);
- failures.clear();
- } 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.m_ignoreCase) {
- if (isASCIILower(ch)) {
- matchesAZaz.append(ch);
- continue;
- }
- if (isASCIIUpper(ch))
- continue;
- }
- m_jit.cmpl_i32r((unsigned short)ch, currentValueRegister);
- matchDest.append(m_jit.emitUnlinkedJe());
- }
-
- if (unsigned countAZaz = matchesAZaz.size()) {
- m_jit.orl_i32r(32, currentValueRegister);
-
- for (unsigned i = 0; i < countAZaz; ++i) {
- char ch = matchesAZaz[i];
- m_jit.cmpl_i32r((unsigned short)ch, currentValueRegister);
- matchDest.append(m_jit.emitUnlinkedJe());
- }
- }
- }
-
- if (charClass.numMatchesUnicode || charClass.numRangesUnicode)
- m_jit.link(unicodeFail, m_jit.label());
-}
-
-void WRECGenerator::generateCharacterClass(JmpSrcVector& failures, CharacterClass& charClass, bool invert)
-{
- m_jit.cmpl_rr(lengthRegister, currentPositionRegister);
- failures.append(m_jit.emitUnlinkedJe());
- m_jit.movzwl_mr(inputRegister, currentPositionRegister, 2, currentValueRegister);
-
- if (invert)
- generateCharacterClassInverted(failures, charClass);
- else {
- JmpSrcVector successes;
- generateCharacterClassInverted(successes, charClass);
- failures.append(m_jit.emitUnlinkedJmp());
- JmpDst here = m_jit.label();
- for (unsigned i = 0; i < successes.size(); ++i)
- m_jit.link(successes[i], here);
- }
-
- m_jit.addl_i8r(1, currentPositionRegister);
-}
-
-WRECGenerator::JmpSrc WRECGenerator::generateParentheses(ParenthesesType type)
-{
- unsigned subpatternId = (type == capturing) ? ++m_parser.m_numSubpatterns : m_parser.m_numSubpatterns;
+ endOfInput.link(&generator);
+ generator.generateReturnFailure();
- // push pos, both to preserve for fail + reloaded in parseDisjunction
- m_jit.pushl_r(currentPositionRegister);
-
- // Plant a disjunction, wrapped to invert behaviour -
- JmpSrcVector newFailures;
- m_parser.parseDisjunction(newFailures);
-
- if (type == capturing) {
- m_jit.popl_r(currentValueRegister);
- m_jit.movl_rm(currentValueRegister, (2 * subpatternId) * sizeof(int), outputRegister);
- m_jit.movl_rm(currentPositionRegister, (2 * subpatternId + 1) * sizeof(int), outputRegister);
- } else if (type == non_capturing)
- m_jit.addl_i8r(4, X86::esp);
- else
- m_jit.popl_r(currentPositionRegister);
-
- // This is a little lame - jump to jump if there is a nested disjunction.
- // (suggestion to fix: make parseDisjunction populate a JmpSrcVector of
- // disjunct successes... this is probably not worth the compile cost in
- // the common case to fix).
- JmpSrc successfulMatch = m_jit.emitUnlinkedJmp();
-
- JmpDst originalFailure = m_jit.label();
- for (unsigned i = 0; i < newFailures.size(); ++i)
- m_jit.link(newFailures[i], originalFailure);
- newFailures.clear();
- // fail: restore currentPositionRegister
- m_jit.popl_r(currentPositionRegister);
-
- JmpSrc jumpToFail;
- // If this was an inverted assert, fail = success! - just let the failure case drop through,
- // success case goes to failures. Both paths restore curr pos.
- if (type == inverted_assertion)
- jumpToFail = successfulMatch;
- else {
- // plant a jump so any fail will link off to 'failures',
- jumpToFail = m_jit.emitUnlinkedJmp();
- // link successes to jump here
- m_jit.link(successfulMatch, m_jit.label());
- }
- return jumpToFail;
-}
-
-void WRECGenerator::generateParenthesesNonGreedy(JmpSrcVector& failures, JmpDst start, JmpSrc success, JmpSrc fail)
-{
- m_jit.link(m_jit.emitUnlinkedJmp(), start);
- m_jit.link(success, m_jit.label());
-
- failures.append(fail);
-}
-
-WRECGenerator::JmpSrc WRECGenerator::generateParenthesesResetTrampoline(JmpSrcVector& newFailures, unsigned subpatternIdBefore, unsigned subpatternIdAfter)
-{
- JmpSrc skip = m_jit.emitUnlinkedJmp();
-
- JmpDst subPatternResetTrampoline = m_jit.label();
- for (unsigned i = 0; i < newFailures.size(); ++i)
- m_jit.link(newFailures[i], subPatternResetTrampoline);
- newFailures.clear();
- for (unsigned i = subpatternIdBefore + 1; i <= subpatternIdAfter; ++i) {
- m_jit.movl_i32m(-1, (2 * i) * sizeof(int), outputRegister);
- m_jit.movl_i32m(-1, (2 * i + 1) * sizeof(int), outputRegister);
- }
-
- JmpSrc newFailJump = m_jit.emitUnlinkedJmp();
- m_jit.link(skip, m_jit.label());
-
- return newFailJump;
-}
-
-void WRECGenerator::generateAssertionBOL(JmpSrcVector& failures)
-{
- if (m_parser.m_multiline) {
- JmpSrcVector previousIsNewline;
-
- // begin of input == success
- m_jit.cmpl_i8r(0, currentPositionRegister);
- previousIsNewline.append(m_jit.emitUnlinkedJe());
-
- // now check prev char against newline characters.
- m_jit.movzwl_mr(-2, inputRegister, currentPositionRegister, 2, currentValueRegister);
- generateCharacterClassInverted(previousIsNewline, getCharacterClassNewline());
-
- failures.append(m_jit.emitUnlinkedJmp());
-
- JmpDst success = m_jit.label();
- for (unsigned i = 0; i < previousIsNewline.size(); ++i)
- m_jit.link(previousIsNewline[i], success);
- previousIsNewline.clear();
- } else {
- m_jit.cmpl_i8r(0, currentPositionRegister);
- failures.append(m_jit.emitUnlinkedJne());
- }
-}
-
-void WRECGenerator::generateAssertionEOL(JmpSrcVector& failures)
-{
- if (m_parser.m_multiline) {
- JmpSrcVector nextIsNewline;
-
- // end of input == success
- m_jit.cmpl_rr(lengthRegister, currentPositionRegister);
- nextIsNewline.append(m_jit.emitUnlinkedJe());
-
- // now check next char against newline characters.
- m_jit.movzwl_mr(inputRegister, currentPositionRegister, 2, currentValueRegister);
- generateCharacterClassInverted(nextIsNewline, getCharacterClassNewline());
-
- failures.append(m_jit.emitUnlinkedJmp());
-
- JmpDst success = m_jit.label();
- for (unsigned i = 0; i < nextIsNewline.size(); ++i)
- m_jit.link(nextIsNewline[i], success);
- nextIsNewline.clear();
- } else {
- m_jit.cmpl_rr(lengthRegister, currentPositionRegister);
- failures.append(m_jit.emitUnlinkedJne());
+ if (parser.error()) {
+ *error_ptr = parser.syntaxError(); // NULL in the case of patterns that WREC doesn't support yet.
+ return 0;
}
-}
-
-void WRECGenerator::generateAssertionWordBoundary(JmpSrcVector& failures, bool invert)
-{
- JmpSrcVector wordBoundary;
- JmpSrcVector notWordBoundary;
-
- // (1) Check if the previous value was a word char
- // (1.1) check for begin of input
- m_jit.cmpl_i8r(0, currentPositionRegister);
- JmpSrc atBegin = m_jit.emitUnlinkedJe();
- // (1.2) load the last char, and chck if is word character
- m_jit.movzwl_mr(-2, inputRegister, currentPositionRegister, 2, currentValueRegister);
- JmpSrcVector previousIsWord;
- generateCharacterClassInverted(previousIsWord, getCharacterClassWordchar());
- // (1.3) if we get here, previous is not a word char
- m_jit.link(atBegin, m_jit.label());
-
- // (2) Handle situation where previous was NOT a \w
-
- // (2.1) check for end of input
- m_jit.cmpl_rr(lengthRegister, currentPositionRegister);
- notWordBoundary.append(m_jit.emitUnlinkedJe());
- // (2.2) load the next char, and chck if is word character
- m_jit.movzwl_mr(inputRegister, currentPositionRegister, 2, currentValueRegister);
- generateCharacterClassInverted(wordBoundary, getCharacterClassWordchar());
- // (2.3) If we get here, neither chars are word chars
- notWordBoundary.append(m_jit.emitUnlinkedJmp());
-
- // (3) Handle situation where previous was a \w
-
- // (3.0) link success in first match to here
- JmpDst section3 = m_jit.label();
- for (unsigned i = 0; i < previousIsWord.size(); ++i)
- m_jit.link(previousIsWord[i], section3);
- previousIsWord.clear();
- // (3.1) check for end of input
- m_jit.cmpl_rr(lengthRegister, currentPositionRegister);
- wordBoundary.append(m_jit.emitUnlinkedJe());
- // (3.2) load the next char, and chck if is word character
- m_jit.movzwl_mr(inputRegister, currentPositionRegister, 2, currentValueRegister);
- generateCharacterClassInverted(notWordBoundary, getCharacterClassWordchar());
- // (3.3) 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(m_jit.emitUnlinkedJmp());
-
- // looking for non word boundaries, so link boundary fails to here.
- JmpDst success = m_jit.label();
- for (unsigned i = 0; i < notWordBoundary.size(); ++i)
- m_jit.link(notWordBoundary[i], success);
- notWordBoundary.clear();
-
- failures.append(wordBoundary.begin(), wordBoundary.size());
- } else {
- // looking for word boundaries, so link successes here.
- JmpDst success = m_jit.label();
- for (unsigned i = 0; i < wordBoundary.size(); ++i)
- m_jit.link(wordBoundary[i], success);
- wordBoundary.clear();
-
- failures.append(notWordBoundary.begin(), notWordBoundary.size());
- }
-}
-
-void WRECGenerator::generateBackreference(JmpSrcVector& failures, unsigned subpatternId)
-{
- m_jit.pushl_r(currentPositionRegister);
- m_jit.pushl_r(quantifierCountRegister);
-
- // get the start pos of the backref into quantifierCountRegister (multipurpose!)
- m_jit.movl_mr((2 * subpatternId) * sizeof(int), outputRegister, quantifierCountRegister);
-
- JmpSrc skipIncrement = m_jit.emitUnlinkedJmp();
- JmpDst topOfLoop = m_jit.label();
- m_jit.addl_i8r(1, currentPositionRegister);
- m_jit.addl_i8r(1, quantifierCountRegister);
- m_jit.link(skipIncrement, m_jit.label());
-
- // check if we're at the end of backref (if we are, success!)
- m_jit.cmpl_rm(quantifierCountRegister, ((2 * subpatternId) + 1) * sizeof(int), outputRegister);
- JmpSrc endOfBackRef = m_jit.emitUnlinkedJe();
-
- m_jit.movzwl_mr(inputRegister, quantifierCountRegister, 2, currentValueRegister);
-
- // check if we've run out of input (this would be a can o'fail)
- m_jit.cmpl_rr(lengthRegister, currentPositionRegister);
- JmpSrc endOfInput = m_jit.emitUnlinkedJe();
-
- m_jit.cmpw_rm(currentValueRegister, inputRegister, currentPositionRegister, 2);
- m_jit.link(m_jit.emitUnlinkedJe(), topOfLoop);
-
- m_jit.link(endOfInput, m_jit.label());
- // Failure
- m_jit.popl_r(quantifierCountRegister);
- m_jit.popl_r(currentPositionRegister);
- failures.append(m_jit.emitUnlinkedJmp());
-
- // Success
- m_jit.link(endOfBackRef, m_jit.label());
- m_jit.popl_r(quantifierCountRegister);
- m_jit.addl_i8r(4, X86::esp);
-}
-
-void WRECGenerator::generateDisjunction(JmpSrcVector& successes, JmpSrcVector& failures)
-{
- successes.append(m_jit.emitUnlinkedJmp());
-
- JmpDst here = m_jit.label();
-
- for (unsigned i = 0; i < failures.size(); ++i)
- m_jit.link(failures[i], here);
- failures.clear();
-
- m_jit.movl_mr(X86::esp, currentPositionRegister);
-}
-
-void WRECGenerator::terminateDisjunction(JmpSrcVector& successes)
-{
- JmpDst here = m_jit.label();
- for (unsigned i = 0; i < successes.size(); ++i)
- m_jit.link(successes[i], here);
- successes.clear();
-}
-
-ALWAYS_INLINE Quantifier WRECParser::parseGreedyQuantifier()
-{
- 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 '{': {
- consume();
- // a numeric quantifier should always have a lower bound
- if (!peekIsDigit()) {
- m_err = Error_malformedQuantifier;
- return Quantifier(Quantifier::Error);
- }
- int min = consumeNumber();
-
- // this should either be a , or a }
- switch (peek()) {
- case '}':
- // {n} - exactly n times. (technically I think a '?' is valid in the bnf - bit meaningless).
- consume();
- return Quantifier(Quantifier::Greedy, min, min);
-
- case ',':
- consume();
- switch (peek()) {
- case '}':
- // {n,} - n to inf times.
- consume();
- return Quantifier(Quantifier::Greedy, min);
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- // {n,m} - n to m times.
- int max = consumeNumber();
-
- if (peek() != '}') {
- m_err = Error_malformedQuantifier;
- return Quantifier(Quantifier::Error);
- }
- consume();
-
- return Quantifier(Quantifier::Greedy, min, max);
- }
-
- default:
- m_err = Error_malformedQuantifier;
- return Quantifier(Quantifier::Error);
- }
-
- default:
- m_err = Error_malformedQuantifier;
- return Quantifier(Quantifier::Error);
- }
- }
- // None of the above - no quantifier
- default:
- return Quantifier();
- }
-}
-
-Quantifier WRECParser::parseQuantifier()
-{
- Quantifier q = parseGreedyQuantifier();
-
- if ((q.type == Quantifier::Greedy) && (peek() == '?')) {
- consume();
- q.type = Quantifier::NonGreedy;
- }
-
- return q;
-}
-
-bool WRECParser::parsePatternCharacterQualifier(JmpSrcVector& failures, int ch)
-{
- Quantifier q = parseQuantifier();
-
- switch (q.type) {
- case Quantifier::None: {
- m_generator.generatePatternCharacter(failures, ch);
- break;
- }
-
- case Quantifier::Greedy: {
- GeneratePatternCharacterFunctor functor(ch);
- m_generator.generateGreedyQuantifier(failures, functor, q.min, q.max);
- break;
- }
-
- case Quantifier::NonGreedy: {
- GeneratePatternCharacterFunctor functor(ch);
- m_generator.generateNonGreedyQuantifier(failures, functor, q.min, q.max);
- break;
- }
-
- case Quantifier::Error:
- return false;
- }
-
- return true;
-}
-
-bool WRECParser::parseCharacterClassQuantifier(JmpSrcVector& failures, CharacterClass& charClass, bool invert)
-{
- Quantifier q = parseQuantifier();
-
- 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 WRECParser::parseBackreferenceQuantifier(JmpSrcVector& failures, unsigned subpatternId)
-{
- Quantifier q = parseQuantifier();
-
- 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 WRECParser::parseParentheses(JmpSrcVector&)
-{
- // FIXME: We don't currently backtrack correctly within parentheses in cases such as
- // "c".match(/(.*)c/) so we fall back to PCRE for any regexp containing parentheses.
-
- m_err = TempError_unsupportedParentheses;
- return false;
-}
-
-bool WRECParser::parseCharacterClass(JmpSrcVector& failures)
-{
- bool invert = false;
- if (peek() == '^') {
- consume();
- invert = true;
- }
-
- CharacterClassConstructor charClassConstructor(m_ignoreCase);
-
- UChar ch;
- while ((ch = peek()) != ']') {
- switch (ch) {
- case EndOfPattern:
- m_err = Error_malformedCharacterClass;
- return false;
-
- case '\\':
- consume();
- switch (ch = peek()) {
- case EndOfPattern:
- m_err = Error_malformedEscape;
- return false;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- charClassConstructor.put(consumeOctal());
- break;
-
- // ControlEscape
- case 'b':
- consume();
- charClassConstructor.put('\b');
- break;
- case 'f':
- consume();
- charClassConstructor.put('\f');
- break;
- case 'n':
- consume();
- charClassConstructor.put('\n');
- break;
- case 'r':
- consume();
- charClassConstructor.put('\r');
- break;
- case 't':
- consume();
- charClassConstructor.put('\t');
- break;
- case 'v':
- consume();
- charClassConstructor.put('\v');
- break;
-
- // ControlLetter
- case 'c': {
- consume();
- int control = consume();
- if (!isASCIIAlpha(control)) {
- m_err = Error_malformedEscape;
- return false;
- }
- charClassConstructor.put(control&31);
- break;
- }
-
- // HexEscape
- case 'x': {
- consume();
- int x = consumeHex(2);
- if (x == -1) {
- m_err = Error_malformedEscape;
- return false;
- }
- charClassConstructor.put(x);
- break;
- }
-
- // UnicodeEscape
- case 'u': {
- consume();
- int x = consumeHex(4);
- if (x == -1) {
- m_err = Error_malformedEscape;
- return false;
- }
- charClassConstructor.put(x);
- break;
- }
-
- // CharacterClassEscape
- case 'd':
- consume();
- charClassConstructor.append(getCharacterClassDigits());
- break;
- case 's':
- consume();
- charClassConstructor.append(getCharacterClassSpaces());
- break;
- case 'w':
- consume();
- charClassConstructor.append(getCharacterClassWordchar());
- break;
- case 'D':
- consume();
- charClassConstructor.append(getCharacterClassNondigits());
- break;
- case 'S':
- consume();
- charClassConstructor.append(getCharacterClassNonspaces());
- break;
- case 'W':
- consume();
- charClassConstructor.append(getCharacterClassNonwordchar());
- break;
-
- case '-':
- consume();
- charClassConstructor.flushBeforeEscapedHyphen();
- charClassConstructor.put(ch);
- break;
-
- // IdentityEscape
- default: {
- // TODO: check this test for IdentifierPart.
- int ch = consume();
- if (isASCIIAlphanumeric(ch) || (ch == '_')) {
- m_err = Error_malformedEscape;
- return false;
- }
- charClassConstructor.put(ch);
- break;
- }
- }
- break;
-
- default:
- consume();
- charClassConstructor.put(ch);
- }
- }
- consume();
-
- // lazily catch reversed ranges ([z-a])in character classes
- if (charClassConstructor.isUpsideDown()) {
- m_err = Error_malformedCharacterClass;
- return false;
- }
-
- charClassConstructor.flush();
- CharacterClass charClass = charClassConstructor.charClass();
- return parseCharacterClassQuantifier(failures, charClass, invert);
-}
-
-bool WRECParser::parseOctalEscape(JmpSrcVector& failures)
-{
- return parsePatternCharacterQualifier(failures, consumeOctal());
-}
-
-bool WRECParser::parseEscape(JmpSrcVector& failures)
-{
- switch (peek()) {
- case EndOfPattern:
- m_err = Error_malformedEscape;
- return false;
-
- // Assertions
- case 'b':
- consume();
- m_generator.generateAssertionWordBoundary(failures, false);
- return true;
-
- case 'B':
- consume();
- m_generator.generateAssertionWordBoundary(failures, true);
- return true;
-
- // Octal escape
- case '0':
- consume();
- return parseOctalEscape(failures);
-
- // DecimalEscape
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7': {
- // FIXME: This does not support forward references. It's not clear whether they
- // should be valid.
- unsigned value = peekDigit();
- if (value > m_numSubpatterns)
- return parseOctalEscape(failures);
- }
- case '8':
- case '9': {
- unsigned value = peekDigit();
- if (value > m_numSubpatterns) {
- consume();
- m_err = Error_malformedEscape;
- return false;
- }
- consume();
-
- while (peekIsDigit()) {
- unsigned newValue = value * 10 + peekDigit();
- if (newValue > m_numSubpatterns)
- break;
- value = newValue;
- consume();
- }
-
- parseBackreferenceQuantifier(failures, value);
- return true;
- }
-
- // ControlEscape
- case 'f':
- consume();
- return parsePatternCharacterQualifier(failures, '\f');
- case 'n':
- consume();
- return parsePatternCharacterQualifier(failures, '\n');
- case 'r':
- consume();
- return parsePatternCharacterQualifier(failures, '\r');
- case 't':
- consume();
- return parsePatternCharacterQualifier(failures, '\t');
- case 'v':
- consume();
- return parsePatternCharacterQualifier(failures, '\v');
-
- // ControlLetter
- case 'c': {
- consume();
- int control = consume();
- if (!isASCIIAlpha(control)) {
- m_err = Error_malformedEscape;
- return false;
- }
- return parsePatternCharacterQualifier(failures, control&31);
- }
-
- // HexEscape
- case 'x': {
- consume();
- int x = consumeHex(2);
- if (x == -1) {
- m_err = Error_malformedEscape;
- return false;
- }
- return parsePatternCharacterQualifier(failures, x);
- }
-
- // UnicodeEscape
- case 'u': {
- consume();
- int x = consumeHex(4);
- if (x == -1) {
- m_err = Error_malformedEscape;
- return false;
- }
- return parsePatternCharacterQualifier(failures, x);
- }
-
- // CharacterClassEscape
- case 'd':
- consume();
- return parseCharacterClassQuantifier(failures, getCharacterClassDigits(), false);
- case 's':
- consume();
- return parseCharacterClassQuantifier(failures, getCharacterClassSpaces(), false);
- case 'w':
- consume();
- return parseCharacterClassQuantifier(failures, getCharacterClassWordchar(), false);
- case 'D':
- consume();
- return parseCharacterClassQuantifier(failures, getCharacterClassDigits(), true);
- case 'S':
- consume();
- return parseCharacterClassQuantifier(failures, getCharacterClassSpaces(), true);
- case 'W':
- consume();
- return parseCharacterClassQuantifier(failures, getCharacterClassWordchar(), true);
-
- // IdentityEscape
- default: {
- // TODO: check this test for IdentifierPart.
- int ch = consume();
- if (isASCIIAlphanumeric(ch) || (ch == '_')) {
- m_err = Error_malformedEscape;
- return false;
- }
- return parsePatternCharacterQualifier(failures, ch);
- }
- }
-}
-
-bool WRECParser::parseTerm(JmpSrcVector& failures)
-{
- switch (peek()) {
- case EndOfPattern:
- case '*':
- case '+':
- case '?':
- case ')':
- case ']':
- case '{':
- case '}':
- case '|':
- // Not allowed in a Term!
- return false;
-
- case '^':
- consume();
- m_generator.generateAssertionBOL(failures);
- return true;
-
- case '$':
- consume();
- m_generator.generateAssertionEOL(failures);
- return true;
-
- case '\\':
- // b & B are also assertions...
- consume();
- return parseEscape(failures);
-
- case '.':
- consume();
- return parseCharacterClassQuantifier(failures, getCharacterClassNewline(), true);
-
- case '[':
- // CharacterClass
- consume();
- return parseCharacterClass(failures);
-
- case '(':
- consume();
- return parseParentheses(failures);
-
- default:
- // Anything else is a PatternCharacter
- return parsePatternCharacterQualifier(failures, consume());
- }
-}
-
-/*
- interface req: CURR_POS is on stack (can be reloaded).
-*/
-void WRECParser::parseDisjunction(JmpSrcVector& failures)
-{
- parseAlternative(failures);
-
- if (peek() == '|') {
- JmpSrcVector successes;
-
- do {
- consume();
-
- m_generator.generateDisjunction(successes, failures);
-
- parseAlternative(failures);
- } while (peek() == '|');
-
- m_generator.terminateDisjunction(successes);
- }
+ *numSubpatterns_ptr = parser.numSubpatterns();
+ pool = globalData->poolForSize(generator.size());
+ return reinterpret_cast<CompiledRegExp>(generator.copyCode(pool.get()));
}
-} // namespace JSC
+} } // namespace JSC::WREC
#endif // ENABLE(WREC)
diff --git a/JavaScriptCore/wrec/WREC.h b/JavaScriptCore/wrec/WREC.h
index 301bd3b..483dce0 100644
--- a/JavaScriptCore/wrec/WREC.h
+++ b/JavaScriptCore/wrec/WREC.h
@@ -26,232 +26,28 @@
#ifndef WREC_h
#define WREC_h
+#include <wtf/Platform.h>
+
#if ENABLE(WREC)
-#include "ustring.h"
-#include <masm/X86Assembler.h>
-#include <wtf/ASCIICType.h>
-#include <wtf/Vector.h>
+#include <wtf/unicode/Unicode.h>
-#if COMPILER(GCC)
+#if COMPILER(GCC) && PLATFORM(X86)
#define WREC_CALL __attribute__ ((regparm (3)))
#else
#define WREC_CALL
#endif
namespace JSC {
+ class Interpreter;
+ class UString;
+}
- typedef int (*WRECFunction)(const UChar* input, unsigned start, unsigned length, int* output) WREC_CALL;
-
- class GenerateAtomFunctor;
- struct CharacterClassRange;
- struct CharacterClass;
-
- struct Quantifier {
- enum Type {
- None,
- Greedy,
- NonGreedy,
- Error,
- };
-
- Quantifier()
- : type(None)
- {
- }
-
- Quantifier(Type type, unsigned min = 0, unsigned max = noMaxSpecified)
- : type(type)
- , min(min)
- , max(max)
- {
- }
-
- Type type;
-
- unsigned min;
- unsigned max;
-
- static const unsigned noMaxSpecified = UINT_MAX;
- };
-
- class WRECParser;
-
- typedef Vector<X86Assembler::JmpSrc> JmpSrcVector;
-
- class WRECGenerator {
- public:
- WRECGenerator(WRECParser& parser, X86Assembler& jit)
- : m_parser(parser)
- , m_jit(jit)
- {
- }
-
- typedef X86Assembler::JmpSrc JmpSrc;
- typedef X86Assembler::JmpDst JmpDst;
-
- // these regs setup by the params
- static const X86Assembler::RegisterID inputRegister = X86::eax;
- static const X86Assembler::RegisterID currentPositionRegister = X86::edx;
- static const X86Assembler::RegisterID lengthRegister = X86::ecx;
- static const X86Assembler::RegisterID currentValueRegister = X86::esi;
- static const X86Assembler::RegisterID outputRegister = X86::edi;
- static const X86Assembler::RegisterID quantifierCountRegister = X86::ebx;
-
- friend class GenerateAtomFunctor;
- friend class GeneratePatternCharacterFunctor;
- friend class GenerateCharacterClassFunctor;
- friend class GenerateBackreferenceFunctor;
- friend class GenerateParenthesesNonGreedyFunctor;
-
- void generateGreedyQuantifier(JmpSrcVector& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max);
- void generateNonGreedyQuantifier(JmpSrcVector& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max);
- void generateBacktrack1();
- void generateBacktrackBackreference(unsigned subpatternId);
- void generateCharacterClass(JmpSrcVector& failures, CharacterClass& charClass, bool invert);
- void generateCharacterClassInverted(JmpSrcVector& failures, CharacterClass& charClass);
- void generateCharacterClassInvertedRange(JmpSrcVector& failures, JmpSrcVector& matchDest, const CharacterClassRange* ranges, unsigned count, unsigned* matchIndex, const UChar* matches, unsigned matchCount);
- void generatePatternCharacter(JmpSrcVector& failures, int ch);
- void generateAssertionWordBoundary(JmpSrcVector& failures, bool invert);
- void generateAssertionBOL(JmpSrcVector& failures);
- void generateAssertionEOL(JmpSrcVector& failures);
- void generateBackreference(JmpSrcVector& failures, unsigned subpatternID);
- void generateBackreferenceQuantifier(JmpSrcVector& failures, Quantifier::Type quantifierType, unsigned subpatternId, unsigned min, unsigned max);
- enum ParenthesesType { capturing, non_capturing, assertion, inverted_assertion }; // order is relied on in generateParentheses()
- JmpSrc generateParentheses(ParenthesesType type);
- JmpSrc generateParenthesesResetTrampoline(JmpSrcVector& newFailures, unsigned subpatternIdBefore, unsigned subpatternIdAfter);
- void generateParenthesesNonGreedy(JmpSrcVector& failures, JmpDst start, JmpSrc success, JmpSrc fail);
-
- void generateDisjunction(JmpSrcVector& successes, JmpSrcVector& failures);
- void terminateDisjunction(JmpSrcVector& successes);
-
- private:
- WRECParser& m_parser;
- X86Assembler& m_jit;
- };
-
- class WRECParser {
- public:
- bool m_ignoreCase;
- bool m_multiline;
- unsigned m_numSubpatterns;
- enum WRECError {
- NoError,
- Error_malformedCharacterClass,
- Error_malformedParentheses,
- Error_malformedPattern,
- Error_malformedQuantifier,
- Error_malformedEscape,
- TempError_unsupportedQuantifier,
- TempError_unsupportedParentheses,
- } m_err;
-
- WRECParser(const UString& pattern, bool ignoreCase, bool multiline, X86Assembler& jit)
- : m_ignoreCase(ignoreCase)
- , m_multiline(multiline)
- , m_numSubpatterns(0)
- , m_err(NoError)
- , m_generator(*this, jit)
- , m_data(pattern.data())
- , m_size(pattern.size())
- , m_index(0)
- {
- }
-
- void parseAlternative(JmpSrcVector& failures)
- {
- while (parseTerm(failures)) { }
- }
-
- void parseDisjunction(JmpSrcVector& failures);
-
- bool parseTerm(JmpSrcVector& failures);
- bool parseEscape(JmpSrcVector& failures);
- bool parseOctalEscape(JmpSrcVector& failures);
- bool parseParentheses(JmpSrcVector& failures);
- bool parseCharacterClass(JmpSrcVector& failures);
- bool parseCharacterClassQuantifier(JmpSrcVector& failures, CharacterClass& charClass, bool invert);
- bool parsePatternCharacterQualifier(JmpSrcVector& failures, int ch);
- bool parseBackreferenceQuantifier(JmpSrcVector& failures, unsigned subpatternId);
-
- ALWAYS_INLINE Quantifier parseGreedyQuantifier();
- Quantifier parseQuantifier();
-
- static const int EndOfPattern = -1;
-
- 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 + (consume() - '0');
- return n;
- }
+namespace JSC { namespace WREC {
- bool isEndOfPattern()
- {
- return peek() != EndOfPattern;
- }
-
- private:
- WRECGenerator m_generator;
- const UChar* m_data;
- unsigned m_size;
- unsigned m_index;
- };
+ typedef int (*CompiledRegExp)(const UChar* input, unsigned start, unsigned length, int* output) WREC_CALL;
-} // namespace JSC
+} } // namespace JSC::WREC
#endif // ENABLE(WREC)
diff --git a/JavaScriptCore/wrec/WRECFunctors.cpp b/JavaScriptCore/wrec/WRECFunctors.cpp
new file mode 100644
index 0000000..5f1674e
--- /dev/null
+++ b/JavaScriptCore/wrec/WRECFunctors.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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
new file mode 100644
index 0000000..610ce55
--- /dev/null
+++ b/JavaScriptCore/wrec/WRECFunctors.h
@@ -0,0 +1,109 @@
+/*
+ * 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
new file mode 100644
index 0000000..4b5f3d4
--- /dev/null
+++ b/JavaScriptCore/wrec/WRECGenerator.cpp
@@ -0,0 +1,665 @@
+/*
+ * 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 PLATFORM(X86_64)
+ // On x86-64 edi and esi are caller preserved, so nothing to do here.
+ // The four arguments have been passed in the registers %rdi, %rsi,
+ // %rdx, %rcx - shuffle these into the expected locations.
+ move(X86::edi, input); // (arg 1) edi -> eax
+ move(X86::ecx, output); // (arg 4) ecx -> edi
+ move(X86::edx, length); // (arg 3) edx -> ecx
+ move(X86::esi, index); // (arg 2) esi -> edx
+
+#else
+ // On x86 edi & esi are callee preserved registers.
+ push(X86::edi);
+ push(X86::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
+
+#ifndef NDEBUG
+ // ASSERT that the output register is not null.
+ Jump outputNotNull = jnzPtr(output);
+ breakpoint();
+ outputNotNull.link(this);
+#endif
+}
+
+void Generator::generateReturnSuccess()
+{
+ // Set return value.
+ pop(X86::eax); // match begin
+ store32(X86::eax, output);
+ store32(index, Address(output, 4)); // match end
+
+ // Restore callee save registers.
+#if !PLATFORM(X86_64)
+ pop(X86::esi);
+ pop(X86::edi);
+#endif
+ ret();
+}
+
+void Generator::generateSaveIndex()
+{
+ push(index);
+}
+
+void Generator::generateIncrementIndex(Jump* failure)
+{
+ peek(index);
+ if (failure)
+ *failure = je32(length, index);
+ add32(Imm32(1), index);
+ poke(index);
+}
+
+void Generator::generateLoadCharacter(JumpList& failures)
+{
+ failures.append(je32(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)
+{
+ jle32(index, length, target);
+}
+
+void Generator::generateReturnFailure()
+{
+ pop();
+ move(Imm32(-1), X86::eax);
+#if !PLATFORM(X86_64)
+ pop(X86::esi);
+ pop(X86::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 = je32(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)
+ je32(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)
+ jl32(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 {
+ jne32(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);
+ jl32(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(jg32(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(jne32(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 = je32(character, Imm32(upper));
+ hasUpper = true;
+ ch = lower;
+ }
+ }
+
+ // checks for ch, or lower case version of ch, if insensitive
+ failures.append(jne32(character, Imm32((unsigned short)ch)));
+
+ 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 = jge32(character, Imm32((unsigned short)lo));
+
+ // generate code for all ranges before this one
+ if (which)
+ generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);
+
+ while ((*matchIndex < matchCount) && (matches[*matchIndex] < lo)) {
+ matchDest.append(je32(character, Imm32((unsigned short)matches[*matchIndex])));
+ ++*matchIndex;
+ }
+ failures.append(jump());
+
+ loOrAbove.link(this);
+ } else if (which) {
+ Jump loOrAbove = jge32(character, Imm32((unsigned short)lo));
+
+ generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);
+ failures.append(jump());
+
+ loOrAbove.link(this);
+ } else
+ failures.append(jl32(character, Imm32((unsigned short)lo)));
+
+ while ((*matchIndex < matchCount) && (matches[*matchIndex] <= hi))
+ ++*matchIndex;
+
+ matchDest.append(jle32(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 = jle32(character, Imm32(0x7f));
+
+ if (charClass.numMatchesUnicode) {
+ for (unsigned i = 0; i < charClass.numMatchesUnicode; ++i) {
+ UChar ch = charClass.matchesUnicode[i];
+ matchDest.append(je32(character, Imm32(ch)));
+ }
+ }
+
+ 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 = jl32(character, Imm32(lo));
+ matchDest.append(jle32(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(je32(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(je32(character, Imm32((unsigned short)ch)));
+ }
+
+ if (unsigned countAZaz = matchesAZaz.size()) {
+ or32(Imm32(32), character);
+ for (unsigned i = 0; i < countAZaz; ++i)
+ matchDest.append(je32(character, Imm32(matchesAZaz[i])));
+ }
+ }
+
+ 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(je32(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(jne32(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(jne32(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 = je32(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 = je32(Address(output, ((2 * subpatternId) + 1) * sizeof(int)), repeatCount);
+
+ load16(BaseIndex(input, repeatCount, MacroAssembler::TimesTwo), character);
+
+ // check if we've run out of input (this would be a can o'fail)
+ Jump endOfInput = je32(length, index);
+
+ je16(character, BaseIndex(input, index, TimesTwo), 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
new file mode 100644
index 0000000..af4101a
--- /dev/null
+++ b/JavaScriptCore/wrec/WRECGenerator.h
@@ -0,0 +1,112 @@
+/*
+ * 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)
+ {
+ }
+
+ static const RegisterID input = X86::eax;
+ static const RegisterID length = X86::ecx;
+ static const RegisterID index = X86::edx;
+ static const RegisterID character = X86::esi;
+ static const RegisterID output = X86::edi;
+ static const RegisterID repeatCount = X86::ebx; // How many times the current atom repeats in the current match.
+
+ 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
new file mode 100644
index 0000000..1709bf9
--- /dev/null
+++ b/JavaScriptCore/wrec/WRECParser.cpp
@@ -0,0 +1,643 @@
+/*
+ * 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
new file mode 100644
index 0000000..a3e151b
--- /dev/null
+++ b/JavaScriptCore/wrec/WRECParser.h
@@ -0,0 +1,214 @@
+/*
+ * 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/wtf/ASCIICType.h b/JavaScriptCore/wtf/ASCIICType.h
index b1ee3dc..0c2ca70 100644
--- a/JavaScriptCore/wtf/ASCIICType.h
+++ b/JavaScriptCore/wtf/ASCIICType.h
@@ -44,6 +44,13 @@
namespace WTF {
+ inline bool isASCII(char c) { return !(c & ~0x7F); }
+ inline bool isASCII(unsigned short c) { return !(c & ~0x7F); }
+#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+ inline bool isASCII(wchar_t c) { return !(c & ~0x7F); }
+#endif
+ inline bool isASCII(int c) { return !(c & ~0x7F); }
+
inline bool isASCIIAlpha(char c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; }
inline bool isASCIIAlpha(unsigned short c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; }
#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
diff --git a/JavaScriptCore/wtf/AVLTree.h b/JavaScriptCore/wtf/AVLTree.h
index cd1511f..18db8ff 100644
--- a/JavaScriptCore/wtf/AVLTree.h
+++ b/JavaScriptCore/wtf/AVLTree.h
@@ -29,12 +29,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef KJS_AVL_TREE_H_
-#define KJS_AVL_TREE_H_
+#ifndef AVL_TREE_H_
+#define AVL_TREE_H_
#include "Assertions.h"
-namespace JSC {
+namespace WTF {
// Here is the reference class for BSet.
//
@@ -203,17 +203,19 @@ public:
break;
}
cmp = -target_cmp;
- } else if (target_cmp != 0)
- if (!((cmp ^ target_cmp) & MASK_HIGH_BIT))
+ } else if (target_cmp != 0) {
+ if (!((cmp ^ target_cmp) & MASK_HIGH_BIT)) {
// cmp and target_cmp are both negative or both positive.
depth = d;
- h = cmp < 0 ? get_lt(h) : get_gt(h);
- if (h == null())
- break;
- branch[d] = cmp > 0;
- path_h[d++] = h;
+ }
}
+ h = cmp < 0 ? get_lt(h) : get_gt(h);
+ if (h == null())
+ break;
+ branch[d] = cmp > 0;
+ path_h[d++] = h;
}
+ }
void start_iter_least(AVLTree &tree)
{
@@ -822,7 +824,7 @@ AVLTree<Abstractor, maxDepth, BSet>::remove(key k)
cmp_shortened_sub_with_path = cmp;
// Get the handle of the opposite child, which may not be null.
- child = cmp > 0 ? get_lt(h, false) : get_gt(h, false);
+ child = cmp > 0 ? get_lt(h) : get_gt(h);
}
if (parent == null())
@@ -841,8 +843,8 @@ AVLTree<Abstractor, maxDepth, BSet>::remove(key k)
if (h != rm) {
// Poke in the replacement for the node to be removed.
- set_lt(h, get_lt(rm, false));
- set_gt(h, get_gt(rm, false));
+ set_lt(h, get_lt(rm));
+ set_gt(h, get_gt(rm));
set_bf(h, get_bf(rm));
if (parent_rm == null())
abs.root = h;
@@ -934,8 +936,8 @@ AVLTree<Abstractor, maxDepth, BSet>::subst(handle new_node)
}
/* Copy tree housekeeping fields from node in tree to new node. */
- set_lt(new_node, get_lt(h, false));
- set_gt(new_node, get_gt(h, false));
+ set_lt(new_node, get_lt(h));
+ set_gt(new_node, get_gt(h));
set_bf(new_node, get_bf(h));
if (parent == null())
@@ -952,7 +954,6 @@ AVLTree<Abstractor, maxDepth, BSet>::subst(handle new_node)
return h;
}
-
}
#endif
diff --git a/JavaScriptCore/wtf/AlwaysInline.h b/JavaScriptCore/wtf/AlwaysInline.h
index d39b2b9..64fdd99 100644
--- a/JavaScriptCore/wtf/AlwaysInline.h
+++ b/JavaScriptCore/wtf/AlwaysInline.h
@@ -22,7 +22,7 @@
#ifndef ALWAYS_INLINE
#if COMPILER(GCC) && defined(NDEBUG) && !COMPILER(MINGW)
-#define ALWAYS_INLINE inline __attribute__ ((__always_inline__))
+#define ALWAYS_INLINE inline __attribute__((__always_inline__))
#elif COMPILER(MSVC) && defined(NDEBUG)
#define ALWAYS_INLINE __forceinline
#else
@@ -32,7 +32,7 @@
#ifndef NEVER_INLINE
#if COMPILER(GCC)
-#define NEVER_INLINE __attribute__ ((__noinline__))
+#define NEVER_INLINE __attribute__((__noinline__))
#else
#define NEVER_INLINE
#endif
@@ -53,3 +53,11 @@
#define LIKELY(x) (x)
#endif
#endif
+
+#ifndef NO_RETURN
+#if COMPILER(GCC)
+#define NO_RETURN __attribute((__noreturn__))
+#else
+#define NO_RETURN
+#endif
+#endif
diff --git a/JavaScriptCore/wtf/Assertions.cpp b/JavaScriptCore/wtf/Assertions.cpp
index 98de91c..6e04fe1 100644
--- a/JavaScriptCore/wtf/Assertions.cpp
+++ b/JavaScriptCore/wtf/Assertions.cpp
@@ -34,7 +34,7 @@
#include <CoreFoundation/CFString.h>
#endif
-#if COMPILER(MSVC)
+#if COMPILER(MSVC) && !PLATFORM(WIN_CE)
#ifndef WINVER
#define WINVER 0x0500
#endif
@@ -66,7 +66,7 @@ static void vprintf_stderr_common(const char* format, va_list args)
CFRelease(str);
CFRelease(cfFormat);
} else
-#elif COMPILER(MSVC)
+#elif COMPILER(MSVC) && !PLATFORM(WIN_CE)
if (IsDebuggerPresent()) {
size_t size = 1024;
diff --git a/JavaScriptCore/wtf/Assertions.h b/JavaScriptCore/wtf/Assertions.h
index 8449563..c17e501 100644
--- a/JavaScriptCore/wtf/Assertions.h
+++ b/JavaScriptCore/wtf/Assertions.h
@@ -120,11 +120,22 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
/* CRASH -- gets us into the debugger or the crash reporter -- signals are ignored by the crash reporter so we must do better */
#ifndef CRASH
-#define CRASH() *(int *)(uintptr_t)0xbbadbeef = 0
+#define CRASH() do { \
+ *(int *)(uintptr_t)0xbbadbeef = 0; \
+ ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
+} while(false)
#endif
/* ASSERT, ASSERT_WITH_MESSAGE, ASSERT_NOT_REACHED */
+#if PLATFORM(WIN_CE)
+/* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
+#include <windows.h>
+#undef min
+#undef max
+#undef ERROR
+#endif
+
#if PLATFORM(WIN_OS)
/* FIXME: Change to use something other than ASSERT to avoid this conflict with win32. */
#undef ASSERT
@@ -135,6 +146,7 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
#define ASSERT(assertion) ((void)0)
#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
#define ASSERT_NOT_REACHED() ((void)0)
+#define ASSERT_UNUSED(variable, assertion) ((void)variable)
#else
@@ -159,6 +171,8 @@ while (0)
CRASH(); \
} while (0)
+#define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
+
#endif
/* ASSERT_ARG */
diff --git a/JavaScriptCore/wtf/ByteArray.cpp b/JavaScriptCore/wtf/ByteArray.cpp
new file mode 100644
index 0000000..526f147
--- /dev/null
+++ b/JavaScriptCore/wtf/ByteArray.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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 "ByteArray.h"
+
+namespace WTF {
+
+PassRefPtr<ByteArray> ByteArray::create(size_t size)
+{
+ unsigned char* buffer = new unsigned char[size + sizeof(ByteArray) - sizeof(size_t)];
+ ASSERT((reinterpret_cast<size_t>(buffer) & 3) == 0);
+ return adoptRef(new (buffer) ByteArray(size));
+}
+
+}
diff --git a/JavaScriptCore/wtf/ByteArray.h b/JavaScriptCore/wtf/ByteArray.h
new file mode 100644
index 0000000..865c30e
--- /dev/null
+++ b/JavaScriptCore/wtf/ByteArray.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ByteArray_h
+#define ByteArray_h
+
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+
+namespace WTF {
+ class ByteArray : public RefCountedBase {
+ public:
+ unsigned length() const { return m_size; }
+
+ void set(unsigned index, double value)
+ {
+ if (index >= m_size)
+ return;
+ if (!(value > 0)) // Clamp NaN to 0
+ value = 0;
+ else if (value > 255)
+ value = 255;
+ m_data[index] = static_cast<unsigned char>(value + 0.5);
+ }
+
+ bool get(unsigned index, unsigned char& result) const
+ {
+ if (index >= m_size)
+ return false;
+ result = m_data[index];
+ return true;
+ }
+
+ unsigned char* data() { return m_data; }
+
+ void deref()
+ {
+ if (derefBase()) {
+ // We allocated with new unsigned char[] in create(),
+ // and then used placement new to construct the object.
+ this->~ByteArray();
+ delete[] reinterpret_cast<unsigned char*>(this);
+ }
+ }
+
+ static PassRefPtr<ByteArray> create(size_t size);
+
+ private:
+ ByteArray(size_t size)
+ : RefCountedBase(1)
+ , m_size(size)
+ {
+ }
+ size_t m_size;
+ unsigned char m_data[sizeof(size_t)];
+ };
+}
+
+#endif
diff --git a/JavaScriptCore/wtf/CONTRIBUTORS.pthreads-win32 b/JavaScriptCore/wtf/CONTRIBUTORS.pthreads-win32
new file mode 100644
index 0000000..7de0f26
--- /dev/null
+++ b/JavaScriptCore/wtf/CONTRIBUTORS.pthreads-win32
@@ -0,0 +1,137 @@
+This is a copy of CONTRIBUTORS file for the Pthreads-win32 library, downloaded
+from http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/pthreads/CONTRIBUTORS?rev=1.32&cvsroot=pthreads-win32
+
+Included here to compliment the Pthreads-win32 license header in wtf/ThreadingWin.cpp file.
+WebKit is using derived sources of ThreadCondition code from Pthreads-win32.
+
+-------------------------------------------------------------------------------
+
+Contributors (in approximate order of appearance)
+
+[See also the ChangeLog file where individuals are
+attributed in log entries. Likewise in the FAQ file.]
+
+Ben Elliston bje at cygnus dot com
+ Initiated the project;
+ setup the project infrastructure (CVS, web page, etc.);
+ early prototype routines.
+Ross Johnson rpj at callisto dot canberra dot edu dot au
+ early prototype routines;
+ ongoing project coordination/maintenance;
+ implementation of spin locks and barriers;
+ various enhancements;
+ bug fixes;
+ documentation;
+ testsuite.
+Robert Colquhoun rjc at trump dot net dot au
+ Early bug fixes.
+John E. Bossom John dot Bossom at cognos dot com
+ Contributed substantial original working implementation;
+ bug fixes;
+ ongoing guidance and standards interpretation.
+Anders Norlander anorland at hem2 dot passagen dot se
+ Early enhancements and runtime checking for supported
+ Win32 routines.
+Tor Lillqvist tml at iki dot fi
+ General enhancements;
+ early bug fixes to condition variables.
+Scott Lightner scott at curriculum dot com
+ Bug fix.
+Kevin Ruland Kevin dot Ruland at anheuser-busch dot com
+ Various bug fixes.
+Mike Russo miker at eai dot com
+ Bug fix.
+Mark E. Armstrong avail at pacbell dot net
+ Bug fixes.
+Lorin Hochstein lmh at xiphos dot ca
+ general bug fixes; bug fixes to condition variables.
+Peter Slacik Peter dot Slacik at tatramed dot sk
+ Bug fixes.
+Mumit Khan khan at xraylith dot wisc dot edu
+ Fixes to work with Mingw32.
+Milan Gardian mg at tatramed dot sk
+ Bug fixes and reports/analyses of obscure problems.
+Aurelio Medina aureliom at crt dot com
+ First implementation of read-write locks.
+Graham Dumpleton Graham dot Dumpleton at ra dot pad dot otc dot telstra dot com dot au
+ Bug fix in condition variables.
+Tristan Savatier tristan at mpegtv dot com
+ WinCE port.
+Erik Hensema erik at hensema dot xs4all dot nl
+ Bug fixes.
+Rich Peters rpeters at micro-magic dot com
+Todd Owen towen at lucidcalm dot dropbear dot id dot au
+ Bug fixes to dll loading.
+Jason Nye jnye at nbnet dot nb dot ca
+ Implementation of async cancelation.
+Fred Forester fforest at eticomm dot net
+Kevin D. Clark kclark at cabletron dot com
+David Baggett dmb at itasoftware dot com
+ Bug fixes.
+Paul Redondo paul at matchvision dot com
+Scott McCaskill scott at 3dfx dot com
+ Bug fixes.
+Jef Gearhart jgearhart at tpssys dot com
+ Bug fix.
+Arthur Kantor akantor at bexusa dot com
+ Mutex enhancements.
+Steven Reddie smr at essemer dot com dot au
+ Bug fix.
+Alexander Terekhov TEREKHOV at de dot ibm dot com
+ Re-implemented and improved read-write locks;
+ (with Louis Thomas) re-implemented and improved
+ condition variables;
+ enhancements to semaphores;
+ enhancements to mutexes;
+ new mutex implementation in 'futex' style;
+ suggested a robust implementation of pthread_once
+ similar to that implemented by V.Kliathcko;
+ system clock change handling re CV timeouts;
+ bug fixes.
+Thomas Pfaff tpfaff at gmx dot net
+ Changes to make C version usable with C++ applications;
+ re-implemented mutex routines to avoid Win32 mutexes
+ and TryEnterCriticalSection;
+ procedure to fix Mingw32 thread-safety issues.
+Franco Bez franco dot bez at gmx dot de
+ procedure to fix Mingw32 thread-safety issues.
+Louis Thomas lthomas at arbitrade dot com
+ (with Alexander Terekhov) re-implemented and improved
+ condition variables.
+David Korn dgk at research dot att dot com
+ Ported to UWIN.
+Phil Frisbie, Jr. phil at hawksoft dot com
+ Bug fix.
+Ralf Brese Ralf dot Brese at pdb4 dot siemens dot de
+ Bug fix.
+prionx at juno dot com prionx at juno dot com
+ Bug fixes.
+Max Woodbury mtew at cds dot duke dot edu
+ POSIX versioning conditionals;
+ reduced namespace pollution;
+ idea to separate routines to reduce statically
+ linked image sizes.
+Rob Fanner rfanner at stonethree dot com
+ Bug fix.
+Michael Johnson michaelj at maine dot rr dot com
+ Bug fix.
+Nicolas Barry boozai at yahoo dot com
+ Bug fixes.
+Piet van Bruggen pietvb at newbridges dot nl
+ Bug fix.
+Makoto Kato raven at oldskool dot jp
+ AMD64 port.
+Panagiotis E. Hadjidoukas peh at hpclab dot ceid dot upatras dot gr
+ Contributed the QueueUserAPCEx package which
+ makes preemptive async cancelation possible.
+Will Bryant will dot bryant at ecosm dot com
+ Borland compiler patch and makefile.
+Anuj Goyal anuj dot goyal at gmail dot com
+ Port to Digital Mars compiler.
+Gottlob Frege gottlobfrege at gmail dot com
+ re-implemented pthread_once (version 2)
+ (pthread_once cancellation added by rpj).
+Vladimir Kliatchko vladimir at kliatchko dot com
+ reimplemented pthread_once with the same form
+ as described by A.Terekhov (later version 2);
+ implementation of MCS (Mellor-Crummey/Scott) locks. \ No newline at end of file
diff --git a/JavaScriptCore/wtf/CurrentTime.cpp b/JavaScriptCore/wtf/CurrentTime.cpp
new file mode 100644
index 0000000..d9ea448
--- /dev/null
+++ b/JavaScriptCore/wtf/CurrentTime.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2008 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CurrentTime.h"
+
+#if PLATFORM(MAC)
+#include <CoreFoundation/CFDate.h>
+#elif PLATFORM(GTK)
+#include <glib.h>
+#elif PLATFORM(WX)
+#include <wx/datetime.h>
+#elif PLATFORM(WIN_OS)
+// If defined, WIN32_LEAN_AND_MEAN disables timeBeginPeriod/timeEndPeriod.
+#undef WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <math.h>
+#include <stdint.h>
+#include <sys/timeb.h>
+#include <sys/types.h>
+#include <time.h>
+#else // Posix systems relying on the gettimeofday()
+#include <sys/time.h>
+#endif
+
+namespace WTF {
+
+const double msPerSecond = 1000.0;
+
+#if PLATFORM(MAC)
+
+double currentTime()
+{
+ return CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970;
+}
+
+#elif PLATFORM(GTK)
+
+// Note: GTK on Windows will pick up the PLATFORM(WIN) implementation above which provides
+// better accuracy compared with Windows implementation of g_get_current_time:
+// (http://www.google.com/codesearch/p?hl=en#HHnNRjks1t0/glib-2.5.2/glib/gmain.c&q=g_get_current_time).
+// Non-Windows GTK builds could use gettimeofday() directly but for the sake of consistency lets use GTK function.
+double currentTime()
+{
+ GTimeVal now;
+ g_get_current_time(&now);
+ return static_cast<double>(now.tv_sec) + static_cast<double>(now.tv_usec / 1000000.0);
+}
+
+#elif PLATFORM(WX)
+
+double currentTime()
+{
+ wxDateTime now = wxDateTime::UNow();
+ return (double)now.GetTicks() + (double)(now.GetMillisecond() / 1000.0);
+}
+
+#elif PLATFORM(WIN_OS)
+
+static LARGE_INTEGER qpcFrequency;
+static bool syncedTime;
+
+static double highResUpTime()
+{
+ // We use QPC, but only after sanity checking its result, due to bugs:
+ // http://support.microsoft.com/kb/274323
+ // http://support.microsoft.com/kb/895980
+ // http://msdn.microsoft.com/en-us/library/ms644904.aspx ("...you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL)."
+
+ static LARGE_INTEGER qpcLast;
+ static DWORD tickCountLast;
+ static bool inited;
+
+ LARGE_INTEGER qpc;
+ QueryPerformanceCounter(&qpc);
+ DWORD tickCount = GetTickCount();
+
+ if (inited) {
+ __int64 qpcElapsed = ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFrequency.QuadPart;
+ __int64 tickCountElapsed;
+ if (tickCount >= tickCountLast)
+ tickCountElapsed = (tickCount - tickCountLast);
+ else {
+#if COMPILER(MINGW)
+ __int64 tickCountLarge = tickCount + 0x100000000ULL;
+#else
+ __int64 tickCountLarge = tickCount + 0x100000000I64;
+#endif
+ tickCountElapsed = tickCountLarge - tickCountLast;
+ }
+
+ // force a re-sync if QueryPerformanceCounter differs from GetTickCount by more than 500ms.
+ // (500ms value is from http://support.microsoft.com/kb/274323)
+ __int64 diff = tickCountElapsed - qpcElapsed;
+ if (diff > 500 || diff < -500)
+ syncedTime = false;
+ } else
+ inited = true;
+
+ qpcLast = qpc;
+ tickCountLast = tickCount;
+
+ return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart);
+}
+
+static double lowResUTCTime()
+{
+#if PLATFORM(WIN_CE)
+ SYSTEMTIME systemTime;
+ GetSystemTime(&systemTime);
+ struct tm tmtime;
+ tmtime.tm_year = systemTime.wYear - 1900;
+ tmtime.tm_mon = systemTime.wMonth - 1;
+ tmtime.tm_mday = systemTime.wDay;
+ tmtime.tm_wday = systemTime.wDayOfWeek;
+ tmtime.tm_hour = systemTime.wHour;
+ tmtime.tm_min = systemTime.wMinute;
+ tmtime.tm_sec = systemTime.wSecond;
+ time_t timet = mktime(&tmtime);
+ return timet * msPerSecond + systemTime.wMilliseconds;
+#else // PLATFORM(WIN_CE)
+ struct _timeb timebuffer;
+ _ftime(&timebuffer);
+ return timebuffer.time * msPerSecond + timebuffer.millitm;
+#endif // PLATFORM(WIN_CE)
+}
+
+static bool qpcAvailable()
+{
+ static bool available;
+ static bool checked;
+
+ if (checked)
+ return available;
+
+ available = QueryPerformanceFrequency(&qpcFrequency);
+ checked = true;
+ return available;
+}
+
+double currentTime()
+{
+ // Use a combination of ftime and QueryPerformanceCounter.
+ // ftime returns the information we want, but doesn't have sufficient resolution.
+ // QueryPerformanceCounter has high resolution, but is only usable to measure time intervals.
+ // To combine them, we call ftime and QueryPerformanceCounter initially. Later calls will use QueryPerformanceCounter
+ // by itself, adding the delta to the saved ftime. We periodically re-sync to correct for drift.
+ static bool started;
+ static double syncLowResUTCTime;
+ static double syncHighResUpTime;
+ static double lastUTCTime;
+
+ double lowResTime = lowResUTCTime();
+
+ if (!qpcAvailable())
+ return lowResTime / 1000.0;
+
+ double highResTime = highResUpTime();
+
+ if (!syncedTime) {
+ timeBeginPeriod(1); // increase time resolution around low-res time getter
+ syncLowResUTCTime = lowResTime = lowResUTCTime();
+ timeEndPeriod(1); // restore time resolution
+ syncHighResUpTime = highResTime;
+ syncedTime = true;
+ }
+
+ double highResElapsed = highResTime - syncHighResUpTime;
+ double utc = syncLowResUTCTime + highResElapsed;
+
+ // force a clock re-sync if we've drifted
+ double lowResElapsed = lowResTime - syncLowResUTCTime;
+ const double maximumAllowedDriftMsec = 15.625 * 2.0; // 2x the typical low-res accuracy
+ if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec)
+ syncedTime = false;
+
+ // make sure time doesn't run backwards (only correct if difference is < 2 seconds, since DST or clock changes could occur)
+ const double backwardTimeLimit = 2000.0;
+ if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit)
+ return lastUTCTime / 1000.0;
+ lastUTCTime = utc;
+ return utc / 1000.0;
+}
+
+#else // Other Posix systems rely on the gettimeofday().
+
+double currentTime()
+{
+ struct timeval now;
+ struct timezone zone;
+
+ gettimeofday(&now, &zone);
+ return static_cast<double>(now.tv_sec) + (double)(now.tv_usec / 1000000.0);
+}
+
+#endif
+
+#if PLATFORM(ANDROID)
+
+uint32_t get_thread_msec()
+{
+#if defined(HAVE_POSIX_CLOCKS)
+ struct timespec tm;
+
+ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm);
+ return tm.tv_sec * 1000LL + tm.tv_nsec / 1000000;
+#else
+ struct timeval now;
+ struct timezone zone;
+
+ gettimeofday(&now, &zone);
+ return now.tv_sec * 1000LL + now.tv_usec / 1000;
+#endif
+}
+
+#endif
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/CurrentTime.h b/JavaScriptCore/wtf/CurrentTime.h
new file mode 100644
index 0000000..f70f98f
--- /dev/null
+++ b/JavaScriptCore/wtf/CurrentTime.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2008 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CurrentTime_h
+#define CurrentTime_h
+
+namespace WTF {
+
+ // Returns the current system (UTC) time in seconds, starting January 1, 1970.
+ // Precision varies depending on a platform but usually is as good or better
+ // then a millisecond.
+ double currentTime();
+
+#if PLATFORM(ANDROID)
+ uint32_t get_thread_msec();
+#endif
+
+} // namespace WTF
+
+using WTF::currentTime;
+
+#endif // CurrentTime_h
+
diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp
index 8f7d5ef..88c10ca 100644
--- a/JavaScriptCore/wtf/FastMalloc.cpp
+++ b/JavaScriptCore/wtf/FastMalloc.cpp
@@ -191,7 +191,7 @@ void* fastMalloc(size_t n)
ASSERT(!isForbidden());
void* result = malloc(n);
if (!result)
- abort();
+ CRASH();
return result;
}
@@ -206,7 +206,7 @@ void* fastCalloc(size_t n_elements, size_t element_size)
ASSERT(!isForbidden());
void* result = calloc(n_elements, element_size);
if (!result)
- abort();
+ CRASH();
return result;
}
@@ -227,33 +227,17 @@ void* fastRealloc(void* p, size_t n)
ASSERT(!isForbidden());
void* result = realloc(p, n);
if (!result)
- abort();
+ CRASH();
return result;
}
void releaseFastMallocFreeMemory() { }
-
-#if HAVE(VIRTUALALLOC)
-void* fastMallocExecutable(size_t n)
-{
- return VirtualAlloc(0, n, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
-}
-
-void fastFreeExecutable(void* p)
-{
- VirtualFree(p, 0, MEM_RELEASE);
-}
-#else
-void* fastMallocExecutable(size_t n)
+
+FastMallocStatistics fastMallocStatistics()
{
- return fastMalloc(n);
-}
-
-void fastFreeExecutable(void* p)
-{
- fastFree(p);
+ FastMallocStatistics statistics = { 0, 0, 0, 0 };
+ return statistics;
}
-#endif
} // namespace WTF
@@ -686,11 +670,11 @@ static void InitSizeClasses() {
// Do some sanity checking on add_amount[]/shift_amount[]/class_array[]
if (ClassIndex(0) < 0) {
MESSAGE("Invalid class index %d for size 0\n", ClassIndex(0));
- abort();
+ CRASH();
}
if (static_cast<size_t>(ClassIndex(kMaxSize)) >= sizeof(class_array)) {
MESSAGE("Invalid class index %d for kMaxSize\n", ClassIndex(kMaxSize));
- abort();
+ CRASH();
}
// Compute the size classes we want to use
@@ -742,7 +726,7 @@ static void InitSizeClasses() {
if (sc != kNumClasses) {
MESSAGE("wrong number of size classes: found %" PRIuS " instead of %d\n",
sc, int(kNumClasses));
- abort();
+ CRASH();
}
// Initialize the mapping arrays
@@ -760,25 +744,25 @@ static void InitSizeClasses() {
const size_t sc = SizeClass(size);
if (sc == 0) {
MESSAGE("Bad size class %" PRIuS " for %" PRIuS "\n", sc, size);
- abort();
+ CRASH();
}
if (sc > 1 && size <= class_to_size[sc-1]) {
MESSAGE("Allocating unnecessarily large class %" PRIuS " for %" PRIuS
"\n", sc, size);
- abort();
+ CRASH();
}
if (sc >= kNumClasses) {
MESSAGE("Bad size class %" PRIuS " for %" PRIuS "\n", sc, size);
- abort();
+ CRASH();
}
const size_t s = class_to_size[sc];
if (size > s) {
MESSAGE("Bad size %" PRIuS " for %" PRIuS " (sc = %" PRIuS ")\n", s, size, sc);
- abort();
+ CRASH();
}
if (s == 0) {
MESSAGE("Bad size %" PRIuS " for %" PRIuS " (sc = %" PRIuS ")\n", s, size, sc);
- abort();
+ CRASH();
}
}
@@ -861,7 +845,7 @@ class PageHeapAllocator {
if (free_avail_ < kAlignedSize) {
// Need more room
free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement));
- if (free_area_ == NULL) abort();
+ if (free_area_ == NULL) CRASH();
free_avail_ = kAllocIncrement;
}
result = free_area_;
@@ -995,7 +979,6 @@ static ALWAYS_INLINE bool DLL_IsEmpty(const Span* list) {
return list->next == list;
}
-#ifndef WTF_CHANGES
static int DLL_Length(const Span* list) {
int result = 0;
for (Span* s = list->next; s != list; s = s->next) {
@@ -1003,7 +986,6 @@ static int DLL_Length(const Span* list) {
}
return result;
}
-#endif
#if 0 /* Not needed at the moment -- causes compiler warnings if not used */
static void DLL_Print(const char* label, const Span* list) {
@@ -1055,11 +1037,30 @@ template <int BITS> class MapSelector {
typedef PackedCache<BITS, uint64_t> CacheType;
};
+#if defined(WTF_CHANGES)
+#if PLATFORM(X86_64)
+// On all known X86-64 platforms, the upper 16 bits are always unused and therefore
+// can be excluded from the PageMap key.
+// See http://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details
+
+static const size_t kBitsUnusedOn64Bit = 16;
+#else
+static const size_t kBitsUnusedOn64Bit = 0;
+#endif
+
+// A three-level map for 64-bit machines
+template <> class MapSelector<64> {
+ public:
+ typedef TCMalloc_PageMap3<64 - kPageShift - kBitsUnusedOn64Bit> Type;
+ typedef PackedCache<64, uint64_t> CacheType;
+};
+#endif
+
// A two-level map for 32-bit machines
template <> class MapSelector<32> {
public:
- typedef TCMalloc_PageMap2<32-kPageShift> Type;
- typedef PackedCache<32-kPageShift, uint16_t> CacheType;
+ typedef TCMalloc_PageMap2<32 - kPageShift> Type;
+ typedef PackedCache<32 - kPageShift, uint16_t> CacheType;
};
// -------------------------------------------------------------------------
@@ -1109,6 +1110,8 @@ class TCMalloc_PageHeap {
pagemap_.Ensure(p, 1);
return GetDescriptor(p);
}
+
+ size_t ReturnedBytes() const;
#endif
// Dump state to stderr
@@ -1491,6 +1494,21 @@ void TCMalloc_PageHeap::RegisterSizeClass(Span* span, size_t sc) {
pagemap_.set(span->start+i, span);
}
}
+
+#ifdef WTF_CHANGES
+size_t TCMalloc_PageHeap::ReturnedBytes() const {
+ size_t result = 0;
+ for (unsigned s = 0; s < kMaxPages; s++) {
+ const int r_length = DLL_Length(&free_[s].returned);
+ unsigned r_pages = s * r_length;
+ result += r_pages << kPageShift;
+ }
+
+ for (Span* s = large_.returned.next; s != &large_.returned; s = s->next)
+ result += s->length << kPageShift;
+ return result;
+}
+#endif
#ifndef WTF_CHANGES
static double PagesToMB(uint64_t pages) {
@@ -3023,7 +3041,7 @@ static inline void* SpanToMallocResult(Span *span) {
}
#ifdef WTF_CHANGES
-template <bool abortOnFailure>
+template <bool crashOnFailure>
#endif
static ALWAYS_INLINE void* do_malloc(size_t size) {
void* ret = NULL;
@@ -3056,8 +3074,8 @@ static ALWAYS_INLINE void* do_malloc(size_t size) {
}
if (!ret) {
#ifdef WTF_CHANGES
- if (abortOnFailure) // This branch should be optimized out by the compiler.
- abort();
+ if (crashOnFailure) // This branch should be optimized out by the compiler.
+ CRASH();
#else
errno = ENOMEM;
#endif
@@ -3226,9 +3244,9 @@ static inline struct mallinfo do_mallinfo() {
#ifndef WTF_CHANGES
extern "C"
#else
-#define do_malloc do_malloc<abortOnFailure>
+#define do_malloc do_malloc<crashOnFailure>
-template <bool abortOnFailure>
+template <bool crashOnFailure>
void* malloc(size_t);
void* fastMalloc(size_t size)
@@ -3241,7 +3259,7 @@ void* tryFastMalloc(size_t size)
return malloc<false>(size);
}
-template <bool abortOnFailure>
+template <bool crashOnFailure>
ALWAYS_INLINE
#endif
void* malloc(size_t size) {
@@ -3265,7 +3283,7 @@ void free(void* ptr) {
#ifndef WTF_CHANGES
extern "C"
#else
-template <bool abortOnFailure>
+template <bool crashOnFailure>
void* calloc(size_t, size_t);
void* fastCalloc(size_t n, size_t elem_size)
@@ -3278,7 +3296,7 @@ void* tryFastCalloc(size_t n, size_t elem_size)
return calloc<false>(n, elem_size);
}
-template <bool abortOnFailure>
+template <bool crashOnFailure>
ALWAYS_INLINE
#endif
void* calloc(size_t n, size_t elem_size) {
@@ -3298,6 +3316,8 @@ void* calloc(size_t n, size_t elem_size) {
return result;
}
+// Since cfree isn't used anywhere, we don't compile it in.
+#ifndef WTF_CHANGES
#ifndef WTF_CHANGES
extern "C"
#endif
@@ -3307,11 +3327,12 @@ void cfree(void* ptr) {
#endif
do_free(ptr);
}
+#endif
#ifndef WTF_CHANGES
extern "C"
#else
-template <bool abortOnFailure>
+template <bool crashOnFailure>
void* realloc(void*, size_t);
void* fastRealloc(void* old_ptr, size_t new_size)
@@ -3324,7 +3345,7 @@ void* tryFastRealloc(void* old_ptr, size_t new_size)
return realloc<false>(old_ptr, new_size);
}
-template <bool abortOnFailure>
+template <bool crashOnFailure>
ALWAYS_INLINE
#endif
void* realloc(void* old_ptr, size_t new_size) {
@@ -3385,16 +3406,6 @@ void* realloc(void* old_ptr, size_t new_size) {
}
}
-void* fastMallocExecutable(size_t n)
-{
- return malloc<false>(n);
-}
-
-void fastFreeExecutable(void* p)
-{
- free(p);
-}
-
#ifdef WTF_CHANGES
#undef do_malloc
#else
@@ -3821,13 +3832,41 @@ void FastMallocZone::init()
#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;
+}
-#if WTF_CHANGES
} // namespace WTF
#endif
diff --git a/JavaScriptCore/wtf/FastMalloc.h b/JavaScriptCore/wtf/FastMalloc.h
index fb2762c..f1264ac 100644
--- a/JavaScriptCore/wtf/FastMalloc.h
+++ b/JavaScriptCore/wtf/FastMalloc.h
@@ -27,7 +27,7 @@
namespace WTF {
- // These functions call abort() if an allocation fails.
+ // These functions call CRASH() if an allocation fails.
void* fastMalloc(size_t n);
void* fastZeroedMalloc(size_t n);
void* fastCalloc(size_t n_elements, size_t element_size);
@@ -41,15 +41,20 @@ namespace WTF {
void fastFree(void* p);
- void* fastMallocExecutable(size_t n);
- void fastFreeExecutable(void* p);
-
#ifndef NDEBUG
void fastMallocForbid();
void fastMallocAllow();
#endif
void releaseFastMallocFreeMemory();
+
+ struct FastMallocStatistics {
+ size_t heapSize;
+ size_t freeSizeInHeap;
+ size_t freeSizeInCaches;
+ size_t returnedSize;
+ };
+ FastMallocStatistics fastMallocStatistics();
} // namespace WTF
diff --git a/JavaScriptCore/wtf/HashCountedSet.h b/JavaScriptCore/wtf/HashCountedSet.h
index 8095a2b..6fc0234 100644
--- a/JavaScriptCore/wtf/HashCountedSet.h
+++ b/JavaScriptCore/wtf/HashCountedSet.h
@@ -1,6 +1,5 @@
/*
- * This file is part of the KDE libraries
- * Copyright (C) 2005 Apple Computer, Inc.
+ * Copyright (C) 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
diff --git a/JavaScriptCore/wtf/HashFunctions.h b/JavaScriptCore/wtf/HashFunctions.h
index 2c66a2d..13afb72 100644
--- a/JavaScriptCore/wtf/HashFunctions.h
+++ b/JavaScriptCore/wtf/HashFunctions.h
@@ -173,6 +173,9 @@ namespace WTF {
template<typename P> struct DefaultHash<RefPtr<P> > { typedef PtrHash<RefPtr<P> > Hash; };
template<typename T, typename U> struct DefaultHash<std::pair<T, U> > { typedef PairHash<T, U> Hash; };
+
+ // Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
+ static const unsigned stringHashingStartValue = 0x9e3779b9U;
} // namespace WTF
diff --git a/JavaScriptCore/wtf/HashTable.cpp b/JavaScriptCore/wtf/HashTable.cpp
index f1f2a4f..71d3f86 100644
--- a/JavaScriptCore/wtf/HashTable.cpp
+++ b/JavaScriptCore/wtf/HashTable.cpp
@@ -34,9 +34,17 @@ int HashTableStats::numReinserts;
static HashTableStats logger;
+static Mutex& hashTableStatsMutex()
+{
+ AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+ return mutex;
+}
+
HashTableStats::~HashTableStats()
{
- printf("\nkhtml::HashTable statistics\n\n");
+ // Don't lock hashTableStatsMutex here because it can cause deadlocks at shutdown
+ // if any thread was killed while holding the mutex.
+ printf("\nWTF::HashTable statistics\n\n");
printf("%d accesses\n", numAccesses);
printf("%d total collisions, average %.2f probes per access\n", numCollisions, 1.0 * (numAccesses + numCollisions) / numAccesses);
printf("longest collision chain: %d\n", maxCollisions);
@@ -49,6 +57,7 @@ HashTableStats::~HashTableStats()
void HashTableStats::recordCollisionAtCount(int count)
{
+ MutexLocker lock(hashTableStatsMutex());
if (count > maxCollisions)
maxCollisions = count;
numCollisions++;
diff --git a/JavaScriptCore/wtf/HashTable.h b/JavaScriptCore/wtf/HashTable.h
index 4c7790a..3b283f8 100644
--- a/JavaScriptCore/wtf/HashTable.h
+++ b/JavaScriptCore/wtf/HashTable.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 David Levin <levin@chromium.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,6 +25,7 @@
#include "FastMalloc.h"
#include "HashTraits.h"
#include <wtf/Assertions.h>
+#include <wtf/Threading.h>
namespace WTF {
@@ -42,13 +44,19 @@ namespace WTF {
struct HashTableStats {
~HashTableStats();
+ // All of the variables are accessed in ~HashTableStats when the static struct is destroyed.
+
+ // The following variables are all atomically incremented when modified.
static int numAccesses;
- static int numCollisions;
- static int collisionGraph[4096];
- static int maxCollisions;
static int numRehashes;
static int numRemoves;
static int numReinserts;
+
+ // The following variables are only modified in the recordCollisionAtCount method within a mutex.
+ static int maxCollisions;
+ static int numCollisions;
+ static int collisionGraph[4096];
+
static void recordCollisionAtCount(int count);
};
@@ -201,6 +209,8 @@ namespace WTF {
#if CHECK_HASHTABLE_ITERATORS
public:
+ // Any modifications of the m_next or m_previous of an iterator that is in a linked list of a HashTable::m_iterator,
+ // should be guarded with m_table->m_mutex.
mutable const HashTableType* m_table;
mutable const_iterator* m_next;
mutable const_iterator* m_previous;
@@ -397,7 +407,9 @@ namespace WTF {
#if CHECK_HASHTABLE_ITERATORS
public:
+ // All access to m_iterators should be guarded with m_mutex.
mutable const_iterator* m_iterators;
+ mutable Mutex m_mutex;
#endif
};
@@ -466,7 +478,7 @@ namespace WTF {
return 0;
#if DUMP_HASHTABLE_STATS
- ++HashTableStats::numAccesses;
+ atomicIncrement(&HashTableStats::numAccesses);
int probeCount = 0;
#endif
@@ -511,7 +523,7 @@ namespace WTF {
int i = h & sizeMask;
#if DUMP_HASHTABLE_STATS
- ++HashTableStats::numAccesses;
+ atomicIncrement(&HashTableStats::numAccesses);
int probeCount = 0;
#endif
@@ -563,7 +575,7 @@ namespace WTF {
int i = h & sizeMask;
#if DUMP_HASHTABLE_STATS
- ++HashTableStats::numAccesses;
+ atomicIncrement(&HashTableStats::numAccesses);
int probeCount = 0;
#endif
@@ -623,7 +635,7 @@ namespace WTF {
int i = h & sizeMask;
#if DUMP_HASHTABLE_STATS
- ++HashTableStats::numAccesses;
+ atomicIncrement(&HashTableStats::numAccesses);
int probeCount = 0;
#endif
@@ -738,7 +750,7 @@ namespace WTF {
ASSERT(!lookupForWriting(Extractor::extract(entry)).second);
ASSERT(!isDeletedBucket(*(lookupForWriting(Extractor::extract(entry)).first)));
#if DUMP_HASHTABLE_STATS
- ++HashTableStats::numReinserts;
+ atomicIncrement(&HashTableStats::numReinserts);
#endif
Mover<ValueType, Traits::needsDestruction>::move(entry, *lookupForWriting(Extractor::extract(entry)).first);
@@ -801,7 +813,7 @@ namespace WTF {
void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::remove(ValueType* pos)
{
#if DUMP_HASHTABLE_STATS
- ++HashTableStats::numRemoves;
+ atomicIncrement(&HashTableStats::numRemoves);
#endif
deleteBucket(*pos);
@@ -887,7 +899,7 @@ namespace WTF {
#if DUMP_HASHTABLE_STATS
if (oldTableSize != 0)
- ++HashTableStats::numRehashes;
+ atomicIncrement(&HashTableStats::numRehashes);
#endif
m_tableSize = newTableSize;
@@ -1016,6 +1028,7 @@ namespace WTF {
template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::invalidateIterators()
{
+ MutexLocker lock(m_mutex);
const_iterator* next;
for (const_iterator* p = m_iterators; p; p = next) {
next = p->m_next;
@@ -1037,6 +1050,7 @@ namespace WTF {
if (!table) {
it->m_next = 0;
} else {
+ MutexLocker lock(table->m_mutex);
ASSERT(table->m_iterators != it);
it->m_next = table->m_iterators;
table->m_iterators = it;
@@ -1058,6 +1072,7 @@ namespace WTF {
ASSERT(!it->m_next);
ASSERT(!it->m_previous);
} else {
+ MutexLocker lock(it->m_table->m_mutex);
if (it->m_next) {
ASSERT(it->m_next->m_previous == it);
it->m_next->m_previous = it->m_previous;
diff --git a/JavaScriptCore/wtf/ListHashSet.h b/JavaScriptCore/wtf/ListHashSet.h
index 2f75c33..38cc998 100644
--- a/JavaScriptCore/wtf/ListHashSet.h
+++ b/JavaScriptCore/wtf/ListHashSet.h
@@ -60,6 +60,8 @@ namespace WTF {
typedef ListHashSetNodeHashFunctions<ValueArg, HashArg> NodeHash;
typedef HashTable<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplType;
+ typedef HashTableIterator<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplTypeIterator;
+ typedef HashTableConstIterator<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplTypeConstIterator;
typedef HashArg HashFunctions;
@@ -441,7 +443,7 @@ namespace WTF {
inline typename ListHashSet<T, U>::iterator ListHashSet<T, U>::find(const ValueType& value)
{
typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
- typename ImplType::iterator it = m_impl.template find<ValueType, Translator>(value);
+ ImplTypeIterator it = m_impl.template find<ValueType, Translator>(value);
if (it == m_impl.end())
return end();
return makeIterator(*it);
@@ -451,7 +453,7 @@ namespace WTF {
inline typename ListHashSet<T, U>::const_iterator ListHashSet<T, U>::find(const ValueType& value) const
{
typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
- typename ImplType::const_iterator it = m_impl.template find<ValueType, Translator>(value);
+ ImplTypeConstIterator it = m_impl.template find<ValueType, Translator>(value);
if (it == m_impl.end())
return end();
return makeConstIterator(*it);
diff --git a/JavaScriptCore/wtf/MainThread.cpp b/JavaScriptCore/wtf/MainThread.cpp
index 6fe3021..c7a6caa 100644
--- a/JavaScriptCore/wtf/MainThread.cpp
+++ b/JavaScriptCore/wtf/MainThread.cpp
@@ -29,6 +29,7 @@
#include "config.h"
#include "MainThread.h"
+#include "StdLibExtras.h"
#include "Threading.h"
#include "Vector.h"
@@ -49,17 +50,17 @@ struct FunctionWithContext {
typedef Vector<FunctionWithContext> FunctionQueue;
-static bool callbacksPaused; // This global varialble is only accessed from main thread.
+static bool callbacksPaused; // This global variable is only accessed from main thread.
Mutex& mainThreadFunctionQueueMutex()
{
- static Mutex staticMutex;
+ DEFINE_STATIC_LOCAL(Mutex, staticMutex, ());
return staticMutex;
}
static FunctionQueue& functionQueue()
{
- static FunctionQueue staticFunctionQueue;
+ DEFINE_STATIC_LOCAL(FunctionQueue, staticFunctionQueue, ());
return staticFunctionQueue;
}
diff --git a/JavaScriptCore/wtf/MathExtras.h b/JavaScriptCore/wtf/MathExtras.h
index cfe5468..76488b4 100644
--- a/JavaScriptCore/wtf/MathExtras.h
+++ b/JavaScriptCore/wtf/MathExtras.h
@@ -28,7 +28,6 @@
#include <math.h>
#include <stdlib.h>
-#include <time.h>
#if PLATFORM(SOLARIS)
#include <ieeefp.h>
@@ -40,8 +39,11 @@
#endif
#if COMPILER(MSVC)
-
+#if PLATFORM(WIN_CE)
+#include <stdlib.h>
+#else
#include <xmath.h>
+#endif
#include <limits>
#if HAVE(FLOAT_H)
@@ -100,17 +102,22 @@ inline bool signbit(double x) { struct ieee_double *p = (struct ieee_double *)&x
#endif
-#if COMPILER(MSVC)
+#if COMPILER(MSVC) || COMPILER(RVCT)
-inline bool isinf(double num) { return !_finite(num) && !_isnan(num); }
-inline bool isnan(double num) { return !!_isnan(num); }
inline long lround(double num) { return static_cast<long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); }
inline long lroundf(float num) { return static_cast<long>(num > 0 ? num + 0.5f : ceilf(num - 0.5f)); }
inline double round(double num) { return num > 0 ? floor(num + 0.5) : ceil(num - 0.5); }
inline float roundf(float num) { return num > 0 ? floorf(num + 0.5f) : ceilf(num - 0.5f); }
-inline bool signbit(double num) { return _copysign(1.0, num) < 0; }
inline double trunc(double num) { return num > 0 ? floor(num) : ceil(num); }
+#endif
+
+#if COMPILER(MSVC)
+
+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; }
+
inline double nextafter(double x, double y) { return _nextafter(x, y); }
inline float nextafterf(float x, float y) { return x > y ? x - FLT_EPSILON : x + FLT_EPSILON; }
@@ -150,45 +157,14 @@ inline double wtf_pow(double x, double y) { return y == 0 ? 1 : pow(x, y); }
#define fmod(x, y) wtf_fmod(x, y)
#define pow(x, y) wtf_pow(x, y)
-#if defined(_CRT_RAND_S)
-// Initializes the random number generator.
-inline void wtf_random_init()
-{
- // No need to initialize for rand_s.
-}
-
-// Returns a pseudo-random number in the range [0, 1).
-inline double wtf_random()
-{
- unsigned u;
- rand_s(&u);
-
- return static_cast<double>(u) / (static_cast<double>(UINT_MAX) + 1.0);
-}
-#endif // _CRT_RAND_S
-
#endif // COMPILER(MSVC)
-#if !COMPILER(MSVC) || !defined(_CRT_RAND_S)
-
-// Initializes the random number generator.
-inline void wtf_random_init()
-{
- srand(static_cast<unsigned>(time(0)));
-}
-
-// Returns a pseudo-random number in the range [0, 1).
-inline double wtf_random()
-{
- return static_cast<double>(rand()) / (static_cast<double>(RAND_MAX) + 1.0);
-}
-
-#endif // #if COMPILER(MSVC)
-
inline double deg2rad(double d) { return d * piDouble / 180.0; }
inline double rad2deg(double r) { return r * 180.0 / piDouble; }
inline double deg2grad(double d) { return d * 400.0 / 360.0; }
inline double grad2deg(double g) { return g * 360.0 / 400.0; }
+inline double turn2deg(double t) { return t * 360.0; }
+inline double deg2turn(double d) { return d / 360.0; }
inline double rad2grad(double r) { return r * 200.0 / piDouble; }
inline double grad2rad(double g) { return g * piDouble / 200.0; }
@@ -196,6 +172,8 @@ inline float deg2rad(float d) { return d * piFloat / 180.0f; }
inline float rad2deg(float r) { return r * 180.0f / piFloat; }
inline float deg2grad(float d) { return d * 400.0f / 360.0f; }
inline float grad2deg(float g) { return g * 360.0f / 400.0f; }
+inline float turn2deg(float t) { return t * 360.0f; }
+inline float deg2turn(float d) { return d / 360.0f; }
inline float rad2grad(float r) { return r * 200.0f / piFloat; }
inline float grad2rad(float g) { return g * piFloat / 200.0f; }
diff --git a/JavaScriptCore/wtf/MessageQueue.h b/JavaScriptCore/wtf/MessageQueue.h
index 481211d..19c5c10 100644
--- a/JavaScriptCore/wtf/MessageQueue.h
+++ b/JavaScriptCore/wtf/MessageQueue.h
@@ -36,6 +36,12 @@
namespace WTF {
+ enum MessageQueueWaitResult {
+ MessageQueueTerminated, // Queue was destroyed while waiting for message.
+ MessageQueueTimeout, // Timeout was specified and it expired.
+ MessageQueueMessageReceived, // A message was successfully received and returned.
+ };
+
template<typename DataType>
class MessageQueue : Noncopyable {
public:
@@ -44,6 +50,7 @@ namespace WTF {
void append(const DataType&);
void prepend(const DataType&);
bool waitForMessage(DataType&);
+ MessageQueueWaitResult waitForMessageTimed(DataType&, double absoluteTime);
void kill();
bool tryGetMessage(DataType&);
@@ -79,7 +86,7 @@ namespace WTF {
inline bool MessageQueue<DataType>::waitForMessage(DataType& result)
{
MutexLocker lock(m_mutex);
-
+
while (!m_killed && m_queue.isEmpty())
m_condition.wait(m_mutex);
@@ -93,6 +100,27 @@ namespace WTF {
}
template<typename DataType>
+ inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageTimed(DataType& result, double absoluteTime)
+ {
+ MutexLocker lock(m_mutex);
+ bool timedOut = false;
+
+ while (!m_killed && !timedOut && m_queue.isEmpty())
+ timedOut = !m_condition.timedWait(m_mutex, absoluteTime);
+
+ if (m_killed)
+ return MessageQueueTerminated;
+
+ if (timedOut)
+ return MessageQueueTimeout;
+
+ ASSERT(!m_queue.isEmpty());
+ result = m_queue.first();
+ m_queue.removeFirst();
+ return MessageQueueMessageReceived;
+ }
+
+ template<typename DataType>
inline bool MessageQueue<DataType>::tryGetMessage(DataType& result)
{
MutexLocker lock(m_mutex);
@@ -132,5 +160,10 @@ namespace WTF {
}
using WTF::MessageQueue;
+// MessageQueueWaitResult enum and all its values.
+using WTF::MessageQueueWaitResult;
+using WTF::MessageQueueTerminated;
+using WTF::MessageQueueTimeout;
+using WTF::MessageQueueMessageReceived;
#endif // MessageQueue_h
diff --git a/JavaScriptCore/wtf/OwnPtr.h b/JavaScriptCore/wtf/OwnPtr.h
index 969950f..256b55c 100644
--- a/JavaScriptCore/wtf/OwnPtr.h
+++ b/JavaScriptCore/wtf/OwnPtr.h
@@ -22,6 +22,7 @@
#define WTF_OwnPtr_h
#include <algorithm>
+#include <memory>
#include <wtf/Assertions.h>
#include <wtf/Noncopyable.h>
@@ -66,12 +67,17 @@ namespace WTF {
typedef ValueType* PtrType;
explicit OwnPtr(PtrType ptr = 0) : m_ptr(ptr) { }
+ OwnPtr(std::auto_ptr<ValueType> autoPtr) : m_ptr(autoPtr.release()) { }
~OwnPtr() { deleteOwnedPtr(m_ptr); }
PtrType get() const { return m_ptr; }
PtrType release() { PtrType ptr = m_ptr; m_ptr = 0; return ptr; }
+ // FIXME: This should be renamed to adopt.
void set(PtrType ptr) { ASSERT(!ptr || m_ptr != ptr); deleteOwnedPtr(m_ptr); m_ptr = ptr; }
+
+ void adopt(std::auto_ptr<ValueType> autoPtr) { ASSERT(!autoPtr.get() || m_ptr != autoPtr.get()); deleteOwnedPtr(m_ptr); m_ptr = autoPtr.release(); }
+
void clear() { deleteOwnedPtr(m_ptr); m_ptr = 0; }
ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; }
diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h
index ca8f2cb..c1dc309 100644
--- a/JavaScriptCore/wtf/PassRefPtr.h
+++ b/JavaScriptCore/wtf/PassRefPtr.h
@@ -56,9 +56,12 @@ namespace WTF {
bool operator!() const { return !m_ptr; }
// This conversion operator allows implicit conversion to bool but not to other integer types.
+#if COMPILER(WINSCW)
+ operator bool() const { return m_ptr; }
+#else
typedef T* PassRefPtr::*UnspecifiedBoolType;
operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; }
-
+#endif
PassRefPtr& operator=(T*);
PassRefPtr& operator=(const PassRefPtr&);
template <typename U> PassRefPtr& operator=(const PassRefPtr<U>&);
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index 80a7bf1..fea00c4 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -78,15 +78,33 @@
#define WTF_PLATFORM_SOLARIS 1
#endif
+#if defined (__S60__) || defined (__SYMBIAN32__)
+/* we are cross-compiling, it is not really windows */
+#undef WTF_PLATFORM_WIN_OS
+#undef WTF_PLATFORM_WIN
+#undef WTF_PLATFORM_CAIRO
+#define WTF_PLATFORM_S60 1
+#define WTF_PLATFORM_SYMBIAN 1
+#endif
+
+
+/* PLATFORM(NETBSD) */
+/* Operating system level dependencies for NetBSD that should be used */
+/* regardless of operating environment */
+#if defined(__NetBSD__)
+#define WTF_PLATFORM_NETBSD 1
+#endif
+
/* PLATFORM(UNIX) */
/* Operating system level dependencies for Unix-like systems that */
/* should be used regardless of operating environment */
#if PLATFORM(DARWIN) \
|| PLATFORM(FREEBSD) \
+ || PLATFORM(S60) \
+ || PLATFORM(NETBSD) \
|| defined(unix) \
|| defined(__unix) \
|| defined(__unix__) \
- || defined (__NetBSD__) \
|| defined(_AIX)
#define WTF_PLATFORM_UNIX 1
#endif
@@ -126,25 +144,23 @@
#define WTF_PLATFORM_CI 1
#endif
-/* PLATFORM(SKIA) */
+/* PLATFORM(SKIA) for Win/Linux, CG/CI for Mac */
#if PLATFORM(CHROMIUM)
+#if PLATFORM(DARWIN)
+#define WTF_PLATFORM_CG 1
+#define WTF_PLATFORM_CI 1
+#define WTF_USE_ATSUI 1
+#else
#define WTF_PLATFORM_SKIA 1
#endif
+#endif
/* Makes PLATFORM(WIN) default to PLATFORM(CAIRO) */
-#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(WX)
+/* FIXME: This should be changed from a blacklist to a whitelist */
+#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(WX) && !PLATFORM(CHROMIUM)
#define WTF_PLATFORM_CAIRO 1
#endif
-#ifdef __S60__
-// we are cross-compiling, it is not really windows
-#undef WTF_PLATFORM_WIN_OS
-#undef WTF_PLATFORM_WIN
-#undef WTF_PLATFORM_CAIRO
-#define WTF_PLATFORM_S60 1
-#define WTF_PLATFORM_SYMBIAN 1
-#endif
-
#ifdef ANDROID
#define WTF_PLATFORM_ANDROID 1
#define WTF_PLATFORM_LINUX 1
@@ -228,6 +244,20 @@
#define WTF_PLATFORM_BIG_ENDIAN 1
#endif
+/* PLATFORM(WIN_CE) && PLATFORM(QT)
+ We can not determine the endianess at compile time. For
+ Qt for Windows CE the endianess is specified in the
+ device specific makespec
+*/
+#if PLATFORM(WIN_CE) && PLATFORM(QT)
+# include <QtGlobal>
+# undef WTF_PLATFORM_BIG_ENDIAN
+# undef WTF_PLATFORM_MIDDLE_ENDIAN
+# if Q_BYTE_ORDER == Q_BIG_EDIAN
+# define WTF_PLATFORM_BIG_ENDIAN 1
+# endif
+#endif
+
/* Compiler */
/* COMPILER(MSVC) */
@@ -260,6 +290,16 @@
#define WTF_COMPILER_CYGWIN 1
#endif
+/* COMPILER(RVCT) */
+#if defined(__CC_ARM) || defined(__ARMCC__)
+#define WTF_COMPILER_RVCT 1
+#endif
+
+/* COMPILER(WINSCW) */
+#if defined(__WINSCW__)
+#define WTF_COMPILER_WINSCW 1
+#endif
+
#if (PLATFORM(MAC) || PLATFORM(WIN)) && !defined(ENABLE_JSC_MULTIPLE_THREADS)
#define ENABLE_JSC_MULTIPLE_THREADS 1
#endif
@@ -290,6 +330,11 @@
#endif
#endif
+#if PLATFORM(CHROMIUM) && PLATFORM(DARWIN)
+#define WTF_PLATFORM_CF 1
+#define WTF_USE_PTHREADS 1
+#endif
+
#if PLATFORM(WIN)
#define WTF_USE_WININET 1
#endif
@@ -305,9 +350,11 @@
#endif
#endif
+#if !defined(HAVE_ACCESSIBILITY)
#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(CHROMIUM)
#define HAVE_ACCESSIBILITY 1
#endif
+#endif /* !defined(HAVE_ACCESSIBILITY) */
#if COMPILER(GCC)
#define HAVE_COMPUTED_GOTO 1
@@ -327,9 +374,26 @@
#elif PLATFORM(WIN_OS)
#define HAVE_FLOAT_H 1
+#if PLATFORM(WIN_CE)
+#define HAVE_ERRNO_H 0
+#else
#define HAVE_SYS_TIMEB_H 1
+#endif
#define HAVE_VIRTUALALLOC 1
+#elif PLATFORM(SYMBIAN)
+
+#define HAVE_ERRNO_H 1
+#define HAVE_MMAP 0
+#define HAVE_SBRK 1
+
+#define HAVE_SYS_TIME_H 1
+#define HAVE_STRINGS_H 1
+
+#if !COMPILER(RVCT)
+#define HAVE_SYS_PARAM_H 1
+#endif
+
#else
/* FIXME: is this actually used or do other platforms generate their own config.h? */
@@ -402,24 +466,58 @@
#define ENABLE_ARCHIVE 1
#endif
-// CTI only supports x86 at the moment, and has only been tested on Mac and Windows.
-#if !defined(ENABLE_CTI) && PLATFORM(X86) && (PLATFORM(MAC) || PLATFORM(WIN))
-#define ENABLE_CTI 1
+#if !defined(WTF_USE_ALTERNATE_JSIMMEDIATE) && PLATFORM(X86_64) && PLATFORM(MAC)
+#define WTF_USE_ALTERNATE_JSIMMEDIATE 1
#endif
-// WREC only supports x86 at the moment, and has only been tested on Mac and Windows.
-#if !defined(ENABLE_WREC) && ENABLE(CTI) && PLATFORM(X86) && (PLATFORM(MAC) || PLATFORM(WIN))
+#if !defined(ENABLE_JIT)
+/* x86-64 support is under development. */
+#if PLATFORM(X86_64) && PLATFORM(MAC)
+ #define ENABLE_JIT 0
+ #define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1
+/* The JIT is tested & working on x86 Mac */
+#elif PLATFORM(X86) && PLATFORM(MAC)
+ #define ENABLE_JIT 1
+ #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1
+/* The JIT is tested & working on x86 Windows */
+#elif PLATFORM(X86) && PLATFORM(WIN)
+ #define ENABLE_JIT 1
+ #define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1
+#endif
+ #define ENABLE_JIT_OPTIMIZE_CALL 1
+ #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1
+ #define ENABLE_JIT_OPTIMIZE_ARITHMETIC 1
+#endif
+
+#if ENABLE(JIT)
+#if !(USE(JIT_STUB_ARGUMENT_VA_LIST) || USE(JIT_STUB_ARGUMENT_REGISTER) || USE(JIT_STUB_ARGUMENT_STACK))
+#error Please define one of the JIT_STUB_ARGUMENT settings.
+#elif (USE(JIT_STUB_ARGUMENT_VA_LIST) && USE(JIT_STUB_ARGUMENT_REGISTER)) \
+ || (USE(JIT_STUB_ARGUMENT_VA_LIST) && USE(JIT_STUB_ARGUMENT_STACK)) \
+ || (USE(JIT_STUB_ARGUMENT_REGISTER) && USE(JIT_STUB_ARGUMENT_STACK))
+#error Please do not define more than one of the JIT_STUB_ARGUMENT settings.
+#endif
+#endif
+
+/* WREC supports x86 & x86-64, and has been tested on Mac and Windows ('cept on 64-bit on Mac). */
+#if (!defined(ENABLE_WREC) && PLATFORM(X86) && PLATFORM(MAC)) \
+ || (!defined(ENABLE_WREC) && PLATFORM(X86_64) && PLATFORM(MAC)) \
+ || (!defined(ENABLE_WREC) && PLATFORM(X86) && PLATFORM(WIN))
#define ENABLE_WREC 1
#endif
-#if ENABLE(CTI) || ENABLE(WREC)
-#define ENABLE_MASM 1
+#if ENABLE(JIT) || ENABLE(WREC)
+#define ENABLE_ASSEMBLER 1
#endif
-#if !defined(ENABLE_PAN_SCROLLING) && (PLATFORM(WIN) || PLATFORM(CHROMIUM) || (PLATFORM(WX) && PLATFORM(WIN_OS)))
+#if !defined(ENABLE_PAN_SCROLLING) && PLATFORM(WIN_OS)
#define ENABLE_PAN_SCROLLING 1
#endif
+#if !defined(ENABLE_ACTIVEX_TYPE_CONVERSION_WMPLAYER)
+#define ENABLE_ACTIVEX_TYPE_CONVERSION_WMPLAYER 1
+#endif
+
/* Use the QtXmlStreamReader implementation for XMLTokenizer */
#if PLATFORM(QT)
#if !ENABLE(XSLT)
@@ -427,10 +525,8 @@
#endif
#endif
-// Use "fastcall" calling convention on MSVC
-#if COMPILER(MSVC)
-#define WTF_USE_FAST_CALL_CTI_ARGUMENT 1
-#define WTF_USE_CTI_ARGUMENT 1
+#if !PLATFORM(QT)
+#define WTF_USE_FONT_FAST_PATH 1
#endif
#endif /* WTF_Platform_h */
diff --git a/JavaScriptCore/wtf/PtrAndFlags.h b/JavaScriptCore/wtf/PtrAndFlags.h
new file mode 100644
index 0000000..477e893
--- /dev/null
+++ b/JavaScriptCore/wtf/PtrAndFlags.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PtrAndFlags_h
+#define PtrAndFlags_h
+
+#include <wtf/Assertions.h>
+
+namespace WTF {
+ template<class T, typename FlagEnum> class PtrAndFlags {
+ public:
+ PtrAndFlags() : m_ptrAndFlags(0) {}
+
+ bool isFlagSet(FlagEnum flagNumber) const { ASSERT(flagNumber < 2); return m_ptrAndFlags & (1 << flagNumber); }
+ void setFlag(FlagEnum flagNumber) { ASSERT(flagNumber < 2); m_ptrAndFlags |= (1 << flagNumber);}
+ void clearFlag(FlagEnum flagNumber) { ASSERT(flagNumber < 2); m_ptrAndFlags &= ~(1 << flagNumber);}
+ T* get() const { return reinterpret_cast<T*>(m_ptrAndFlags & ~3); }
+ void set(T* ptr) { ASSERT(!(reinterpret_cast<intptr_t>(ptr) & 3)); m_ptrAndFlags = reinterpret_cast<intptr_t>(ptr) | (m_ptrAndFlags & 3);}
+ private:
+ intptr_t m_ptrAndFlags;
+ };
+} // namespace WTF
+
+using WTF::PtrAndFlags;
+
+#endif // PtrAndFlags_h
diff --git a/JavaScriptCore/wtf/RandomNumber.cpp b/JavaScriptCore/wtf/RandomNumber.cpp
new file mode 100644
index 0000000..c94d5a4
--- /dev/null
+++ b/JavaScriptCore/wtf/RandomNumber.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 "RandomNumber.h"
+
+#include "RandomNumberSeed.h"
+
+#include <limits>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+namespace WTF {
+
+double weakRandomNumber()
+{
+#if COMPILER(MSVC) && defined(_CRT_RAND_S)
+ // rand_s is incredibly slow on windows so we fall back on rand for Math.random
+ return (rand() + (rand() / (RAND_MAX + 1.0))) / (RAND_MAX + 1.0);
+#else
+ return randomNumber();
+#endif
+}
+
+double randomNumber()
+{
+#if !ENABLE(JSC_MULTIPLE_THREADS)
+ static bool s_initialized = false;
+ if (!s_initialized) {
+ initializeRandomNumberGenerator();
+ s_initialized = true;
+ }
+#endif
+
+#if COMPILER(MSVC) && defined(_CRT_RAND_S)
+ uint32_t bits;
+ rand_s(&bits);
+ return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0);
+#elif PLATFORM(DARWIN)
+ uint32_t bits = arc4random();
+ return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0);
+#elif PLATFORM(UNIX)
+ uint32_t part1 = random() & (RAND_MAX - 1);
+ uint32_t part2 = random() & (RAND_MAX - 1);
+ // random only provides 31 bits
+ uint64_t fullRandom = part1;
+ fullRandom <<= 31;
+ fullRandom |= part2;
+
+ // Mask off the low 53bits
+ fullRandom &= (1LL << 53) - 1;
+ return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53);
+#else
+ uint32_t part1 = rand() & (RAND_MAX - 1);
+ uint32_t part2 = rand() & (RAND_MAX - 1);
+ // rand only provides 31 bits, and the low order bits of that aren't very random
+ // so we take the high 26 bits of part 1, and the high 27 bits of part2.
+ part1 >>= 5; // drop the low 5 bits
+ part2 >>= 4; // drop the low 4 bits
+ uint64_t fullRandom = part1;
+ fullRandom <<= 27;
+ fullRandom |= part2;
+
+ // Mask off the low 53bits
+ fullRandom &= (1LL << 53) - 1;
+ return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53);
+#endif
+}
+
+}
diff --git a/JavaScriptCore/wtf/RandomNumber.h b/JavaScriptCore/wtf/RandomNumber.h
new file mode 100644
index 0000000..fe1687c
--- /dev/null
+++ b/JavaScriptCore/wtf/RandomNumber.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 WTF_RandomNumber_h
+#define WTF_RandomNumber_h
+
+namespace WTF {
+
+ // Returns a pseudo-random number in the range [0, 1), attempts to be
+ // cryptographically secure if possible on the target platform
+ double randomNumber();
+
+ // Returns a pseudo-random number in the range [0, 1), attempts to
+ // produce a reasonable "random" number fast.
+ // We only need this because rand_s is so slow on windows.
+ double weakRandomNumber();
+
+}
+
+#endif
diff --git a/JavaScriptCore/wtf/RandomNumberSeed.h b/JavaScriptCore/wtf/RandomNumberSeed.h
new file mode 100644
index 0000000..f994fd9
--- /dev/null
+++ b/JavaScriptCore/wtf/RandomNumberSeed.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 WTF_RandomNumberSeed_h
+#define WTF_RandomNumberSeed_h
+
+#include <stdlib.h>
+#include <time.h>
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if PLATFORM(UNIX)
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+// Internal JavaScriptCore usage only
+namespace WTF {
+
+inline void initializeRandomNumberGenerator()
+{
+#if PLATFORM(DARWIN)
+ // On Darwin we use arc4random which initialises itself.
+#elif COMPILER(MSVC) && defined(_CRT_RAND_S)
+ // On Windows we use rand_s which intialises itself
+#elif PLATFORM(UNIX)
+ // srandomdev is not guaranteed to exist on linux so we use this poor seed, this should be improved
+ timeval time;
+ gettimeofday(&time, 0);
+ srandom(static_cast<unsigned>(time.tv_usec * getpid()));
+#else
+ srand(static_cast<unsigned>(time(0)));
+#endif
+}
+
+inline void initializeWeakRandomNumberGenerator()
+{
+#if COMPILER(MSVC) && defined(_CRT_RAND_S)
+ // We need to initialise windows rand() explicitly for Math.random
+ unsigned seed = 0;
+ rand_s(&seed);
+ srand(seed);
+#endif
+}
+}
+
+#endif
diff --git a/JavaScriptCore/wtf/RefCounted.h b/JavaScriptCore/wtf/RefCounted.h
index 2dd5b2a..ac8e167 100644
--- a/JavaScriptCore/wtf/RefCounted.h
+++ b/JavaScriptCore/wtf/RefCounted.h
@@ -75,7 +75,7 @@ protected:
return false;
}
-private:
+protected:
int m_refCount;
#ifndef NDEBUG
bool m_deletionHasBegun;
diff --git a/JavaScriptCore/wtf/RefPtr.h b/JavaScriptCore/wtf/RefPtr.h
index 78bd257..929e745 100644
--- a/JavaScriptCore/wtf/RefPtr.h
+++ b/JavaScriptCore/wtf/RefPtr.h
@@ -62,8 +62,12 @@ namespace WTF {
bool operator!() const { return !m_ptr; }
// This conversion operator allows implicit conversion to bool but not to other integer types.
+#if COMPILER(WINSCW)
+ operator bool() const { return m_ptr; }
+#else
typedef T* RefPtr::*UnspecifiedBoolType;
operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
+#endif
RefPtr& operator=(const RefPtr&);
RefPtr& operator=(T*);
diff --git a/JavaScriptCore/wtf/RetainPtr.h b/JavaScriptCore/wtf/RetainPtr.h
index 2d73603..a66a127 100644
--- a/JavaScriptCore/wtf/RetainPtr.h
+++ b/JavaScriptCore/wtf/RetainPtr.h
@@ -1,6 +1,5 @@
/*
- * This file is part of the KDE libraries
- * Copyright (C) 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 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
diff --git a/JavaScriptCore/wtf/StdLibExtras.h b/JavaScriptCore/wtf/StdLibExtras.h
new file mode 100644
index 0000000..14227ab
--- /dev/null
+++ b/JavaScriptCore/wtf/StdLibExtras.h
@@ -0,0 +1,63 @@
+/*
+ * 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 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
+// it is leaked so that its destructors are not called at exit. Using this
+// macro also allows workarounds a compiler bug present in Apple's version of GCC 4.0.1.
+#if COMPILER(GCC) && defined(__APPLE_CC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 1
+#define DEFINE_STATIC_LOCAL(type, name, arguments) \
+ static type* name##Ptr = new type arguments; \
+ type& name = *name##Ptr
+#else
+#define DEFINE_STATIC_LOCAL(type, name, arguments) \
+ static type& name = *new type arguments
+#endif
+
+namespace WTF {
+
+ /*
+ * C++'s idea of a reinterpret_cast lacks sufficient cojones.
+ */
+ template<typename TO, typename FROM>
+ TO bitwise_cast(FROM in)
+ {
+ COMPILE_ASSERT(sizeof(TO) == sizeof(FROM), WTF_wtf_reinterpret_cast_sizeof_types_is_equal);
+ union {
+ FROM from;
+ TO to;
+ } u;
+ u.from = in;
+ return u.to;
+ }
+
+} // namespace WTF
+
+#endif
diff --git a/JavaScriptCore/wtf/TCSpinLock.h b/JavaScriptCore/wtf/TCSpinLock.h
index 3c6ac11..d651e31 100644
--- a/JavaScriptCore/wtf/TCSpinLock.h
+++ b/JavaScriptCore/wtf/TCSpinLock.h
@@ -46,7 +46,6 @@
#else
#include <sys/types.h>
#endif
-#include <stdlib.h> /* for abort() */
#if PLATFORM(WIN_OS)
#ifndef WIN32_LEAN_AND_MEAN
@@ -199,16 +198,16 @@ struct TCMalloc_SpinLock {
pthread_mutex_t private_lock_;
inline void Init() {
- if (pthread_mutex_init(&private_lock_, NULL) != 0) abort();
+ if (pthread_mutex_init(&private_lock_, NULL) != 0) CRASH();
}
inline void Finalize() {
- if (pthread_mutex_destroy(&private_lock_) != 0) abort();
+ if (pthread_mutex_destroy(&private_lock_) != 0) CRASH();
}
inline void Lock() {
- if (pthread_mutex_lock(&private_lock_) != 0) abort();
+ if (pthread_mutex_lock(&private_lock_) != 0) CRASH();
}
inline void Unlock() {
- if (pthread_mutex_unlock(&private_lock_) != 0) abort();
+ if (pthread_mutex_unlock(&private_lock_) != 0) CRASH();
}
};
diff --git a/JavaScriptCore/wtf/TCSystemAlloc.cpp b/JavaScriptCore/wtf/TCSystemAlloc.cpp
index bd6eb33..3a8908d 100644
--- a/JavaScriptCore/wtf/TCSystemAlloc.cpp
+++ b/JavaScriptCore/wtf/TCSystemAlloc.cpp
@@ -170,7 +170,7 @@ static void* TryMmap(size_t size, size_t *actual_size, size_t alignment) {
extra = alignment - pagesize;
}
void* result = mmap(NULL, size + extra,
- PROT_READ|PROT_WRITE,
+ PROT_READ | PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0);
if (result == reinterpret_cast<void*>(MAP_FAILED)) {
@@ -224,7 +224,7 @@ static void* TryVirtualAlloc(size_t size, size_t *actual_size, size_t alignment)
}
void* result = VirtualAlloc(NULL, size + extra,
MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN,
- PAGE_EXECUTE_READWRITE);
+ PAGE_READWRITE);
if (result == NULL) {
VirtualAlloc_failure = true;
@@ -302,7 +302,7 @@ static void* TryDevMem(size_t size, size_t *actual_size, size_t alignment) {
devmem_failure = true;
return NULL;
}
- void *result = mmap(0, size + extra, PROT_WRITE|PROT_READ,
+ void *result = mmap(0, size + extra, PROT_READ | PROT_WRITE,
MAP_SHARED, physmem_fd, physmem_base);
if (result == reinterpret_cast<void*>(MAP_FAILED)) {
devmem_failure = true;
@@ -383,8 +383,6 @@ void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size, size_t alignment) {
void TCMalloc_SystemRelease(void* start, size_t length)
{
- UNUSED_PARAM(start);
- UNUSED_PARAM(length);
#if HAVE(MADV_DONTNEED)
if (FLAGS_malloc_devmem_start) {
// It's not safe to use MADV_DONTNEED if we've been mapping
@@ -421,18 +419,20 @@ void TCMalloc_SystemRelease(void* start, size_t length)
#endif
#if HAVE(MMAP)
- void *newAddress = mmap(start, length, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
- UNUSED_PARAM(newAddress);
+ void* newAddress = mmap(start, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
// If the mmap failed then that's ok, we just won't return the memory to the system.
- ASSERT(newAddress == start || newAddress == reinterpret_cast<void*>(MAP_FAILED));
+ ASSERT_UNUSED(newAddress, newAddress == start || newAddress == reinterpret_cast<void*>(MAP_FAILED));
return;
#endif
+
+#if !HAVE(MADV_DONTNEED) && !HAVE(MMAP)
+ UNUSED_PARAM(start);
+ UNUSED_PARAM(length);
+#endif
}
#if HAVE(VIRTUALALLOC)
-void TCMalloc_SystemCommit(void* start, size_t length)
+void TCMalloc_SystemCommit(void*, size_t)
{
- UNUSED_PARAM(start);
- UNUSED_PARAM(length);
}
#endif
diff --git a/JavaScriptCore/wtf/ThreadSpecific.h b/JavaScriptCore/wtf/ThreadSpecific.h
index 87709a1..7603802 100644
--- a/JavaScriptCore/wtf/ThreadSpecific.h
+++ b/JavaScriptCore/wtf/ThreadSpecific.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Jian Li <jianli@chromium.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,19 +27,36 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/* Thread local storage is implemented by using either pthread API or Windows
+ * native API. There is subtle semantic discrepancy for the cleanup function
+ * implementation as noted below:
+ * @ In pthread implementation, the destructor function will be called
+ * repeatedly if there is still non-NULL value associated with the function.
+ * @ In Windows native implementation, the destructor function will be called
+ * only once.
+ * This semantic discrepancy does not impose any problem because nowhere in
+ * WebKit the repeated call bahavior is utilized.
+ */
+
#ifndef WTF_ThreadSpecific_h
#define WTF_ThreadSpecific_h
#include <wtf/Noncopyable.h>
-#if USE(PTHREADS) || PLATFORM(WIN)
-// Windows currently doesn't use pthreads for basic threading, but implementing destructor functions is easier
-// with pthreads, so we use it here.
+#if USE(PTHREADS)
#include <pthread.h>
+#elif PLATFORM(WIN_OS)
+#include <windows.h>
#endif
namespace WTF {
+#if !USE(PTHREADS) && PLATFORM(WIN_OS)
+// ThreadSpecificThreadExit should be called each time when a thread is detached.
+// This is done automatically for threads created with WTF::createThread.
+void ThreadSpecificThreadExit();
+#endif
+
template<typename T> class ThreadSpecific : Noncopyable {
public:
ThreadSpecific();
@@ -48,23 +66,34 @@ public:
~ThreadSpecific();
private:
+#if !USE(PTHREADS) && PLATFORM(WIN_OS)
+ friend void ThreadSpecificThreadExit();
+#endif
+
T* get();
void set(T*);
void static destroy(void* ptr);
-#if USE(PTHREADS) || PLATFORM(WIN)
+#if USE(PTHREADS) || PLATFORM(WIN_OS)
struct Data : Noncopyable {
Data(T* value, ThreadSpecific<T>* owner) : value(value), owner(owner) {}
T* value;
ThreadSpecific<T>* owner;
+#if !USE(PTHREADS)
+ void (*destructor)(void*);
+#endif
};
+#endif
+#if USE(PTHREADS)
pthread_key_t m_key;
+#elif PLATFORM(WIN_OS)
+ int m_index;
#endif
};
-#if USE(PTHREADS) || PLATFORM(WIN)
+#if USE(PTHREADS)
template<typename T>
inline ThreadSpecific<T>::ThreadSpecific()
{
@@ -93,26 +122,92 @@ inline void ThreadSpecific<T>::set(T* ptr)
pthread_setspecific(m_key, new Data(ptr, this));
}
+#elif PLATFORM(WIN_OS)
+
+// The maximum number of TLS keys that can be created. For simplification, we assume that:
+// 1) Once the instance of ThreadSpecific<> is created, it will not be destructed until the program dies.
+// 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed number should be far enough.
+const int kMaxTlsKeySize = 256;
+
+extern long g_tls_key_count;
+extern DWORD g_tls_keys[kMaxTlsKeySize];
+
+template<typename T>
+inline ThreadSpecific<T>::ThreadSpecific()
+ : m_index(-1)
+{
+ DWORD tls_key = TlsAlloc();
+ if (tls_key == TLS_OUT_OF_INDEXES)
+ CRASH();
+
+ m_index = InterlockedIncrement(&g_tls_key_count) - 1;
+ if (m_index >= kMaxTlsKeySize)
+ CRASH();
+ g_tls_keys[m_index] = tls_key;
+}
+
+template<typename T>
+inline ThreadSpecific<T>::~ThreadSpecific()
+{
+ // Does not invoke destructor functions. They will be called from ThreadSpecificThreadExit when the thread is detached.
+ TlsFree(g_tls_keys[m_index]);
+}
+
+template<typename T>
+inline T* ThreadSpecific<T>::get()
+{
+ Data* data = static_cast<Data*>(TlsGetValue(g_tls_keys[m_index]));
+ return data ? data->value : 0;
+}
+
+template<typename T>
+inline void ThreadSpecific<T>::set(T* ptr)
+{
+ ASSERT(!get());
+ Data* data = new Data(ptr, this);
+ data->destructor = &ThreadSpecific<T>::destroy;
+ TlsSetValue(g_tls_keys[m_index], data);
+}
+
+#else
+#error ThreadSpecific is not implemented for this platform.
+#endif
+
template<typename T>
inline void ThreadSpecific<T>::destroy(void* ptr)
{
Data* data = static_cast<Data*>(ptr);
- pthread_setspecific(data->owner->m_key, 0);
- delete data->value;
- delete data;
-}
+#if USE(PTHREADS)
+ // We want get() to keep working while data destructor works, because it can be called indirectly by the destructor.
+ // Some pthreads implementations zero out the pointer before calling destroy(), so we temporarily reset it.
+ pthread_setspecific(data->owner->m_key, ptr);
+#endif
+
+ data->value->~T();
+ fastFree(data->value);
+
+#if USE(PTHREADS)
+ pthread_setspecific(data->owner->m_key, 0);
+#elif PLATFORM(WIN_OS)
+ TlsSetValue(g_tls_keys[data->owner->m_index], 0);
#else
#error ThreadSpecific is not implemented for this platform.
#endif
+ delete data;
+}
+
template<typename T>
inline ThreadSpecific<T>::operator T*()
{
T* ptr = static_cast<T*>(get());
if (!ptr) {
- ptr = new T();
+ // Set up thread-specific value's memory pointer before invoking constructor, in case any function it calls
+ // needs to access the value, to avoid recursion.
+ ptr = static_cast<T*>(fastMalloc(sizeof(T)));
set(ptr);
+ new (ptr) T;
}
return ptr;
}
diff --git a/JavaScriptCore/wtf/ThreadSpecificWin.cpp b/JavaScriptCore/wtf/ThreadSpecificWin.cpp
new file mode 100644
index 0000000..1a3febb
--- /dev/null
+++ b/JavaScriptCore/wtf/ThreadSpecificWin.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Jian Li <jianli@chromium.org>
+ *
+ * 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 "ThreadSpecific.h"
+#include <wtf/Noncopyable.h>
+
+#if USE(PTHREADS)
+#error This file should not be compiled by ports that do not use Windows native ThreadSpecific implementation.
+#endif
+
+namespace WTF {
+
+long g_tls_key_count = 0;
+DWORD g_tls_keys[kMaxTlsKeySize];
+
+void ThreadSpecificThreadExit()
+{
+ for (long i = 0; i < g_tls_key_count; i++) {
+ // The layout of ThreadSpecific<T>::Data does not depend on T. So we are safe to do the static cast to ThreadSpecific<int> in order to access its data member.
+ ThreadSpecific<int>::Data* data = static_cast<ThreadSpecific<int>::Data*>(TlsGetValue(g_tls_keys[i]));
+ if (data)
+ data->destructor(data);
+ }
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/Threading.cpp b/JavaScriptCore/wtf/Threading.cpp
new file mode 100644
index 0000000..41c9135
--- /dev/null
+++ b/JavaScriptCore/wtf/Threading.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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 AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Threading.h"
+
+namespace WTF {
+
+struct NewThreadContext {
+ NewThreadContext(ThreadFunction entryPoint, void* data)
+ : entryPoint(entryPoint)
+ , data(data)
+ { }
+
+ ThreadFunction entryPoint;
+ void* data;
+
+ Mutex creationMutex;
+};
+
+static void* threadEntryPoint(void* contextData)
+{
+ NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData);
+
+ // Block until our creating thread has completed any extra setup work
+ {
+ MutexLocker locker(context->creationMutex);
+ }
+
+ // Grab the info that we need out of the context, then deallocate it.
+ ThreadFunction entryPoint = context->entryPoint;
+ void* data = context->data;
+ delete context;
+
+ return entryPoint(data);
+}
+
+ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
+{
+ NewThreadContext* context = new NewThreadContext(entryPoint, data);
+
+ // Prevent the thread body from executing until we've established the thread identifier
+ MutexLocker locker(context->creationMutex);
+
+ return createThreadInternal(threadEntryPoint, context, name);
+}
+
+#if PLATFORM(MAC) || PLATFORM(WIN)
+
+// This function is deprecated but needs to be kept around for backward
+// compatibility. Use the 3-argument version of createThread above.
+
+ThreadIdentifier createThread(ThreadFunction entryPoint, void* data);
+
+ThreadIdentifier createThread(ThreadFunction entryPoint, void* data)
+{
+ return createThread(entryPoint, data, 0);
+}
+#endif
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/Threading.h b/JavaScriptCore/wtf/Threading.h
index b464da3..1c0dab1 100644
--- a/JavaScriptCore/wtf/Threading.h
+++ b/JavaScriptCore/wtf/Threading.h
@@ -59,11 +59,15 @@
#ifndef Threading_h
#define Threading_h
+#if PLATFORM(WIN_CE)
+#include <windows.h>
+#endif
+
#include <wtf/Assertions.h>
#include <wtf/Locker.h>
#include <wtf/Noncopyable.h>
-#if PLATFORM(WIN_OS)
+#if PLATFORM(WIN_OS) && !PLATFORM(WIN_CE)
#include <windows.h>
#elif PLATFORM(DARWIN)
#include <libkern/OSAtomic.h>
@@ -108,6 +112,7 @@ typedef void* (*ThreadFunction)(void* argument);
// Returns 0 if thread creation failed
ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);
+ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);
ThreadIdentifier currentThread();
bool isMainThread();
@@ -129,12 +134,15 @@ struct PlatformMutex {
size_t m_recursionCount;
};
struct PlatformCondition {
- size_t m_timedOut;
- size_t m_blocked;
- size_t m_waitingForRemoval;
- HANDLE m_gate;
- HANDLE m_queue;
- HANDLE m_mutex;
+ size_t m_waitersGone;
+ size_t m_waitersBlocked;
+ size_t m_waitersToUnblock;
+ HANDLE m_blockLock;
+ HANDLE m_blockQueue;
+ HANDLE m_unblockLock;
+
+ bool timedWait(PlatformMutex&, DWORD durationMilliseconds);
+ void signal(bool unblockAll);
};
#else
typedef void* PlatformMutex;
@@ -164,8 +172,9 @@ public:
~ThreadCondition();
void wait(Mutex& mutex);
- // Returns true if the condition was signaled before the timeout, false if the timeout was reached
- bool timedWait(Mutex&, double interval);
+ // Returns true if the condition was signaled before absoluteTime, false if the absoluteTime was reached or is in the past.
+ // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the same time zone as WTF::currentTime().
+ bool timedWait(Mutex&, double absoluteTime);
void signal();
void broadcast();
@@ -176,7 +185,7 @@ private:
#if PLATFORM(WIN_OS)
#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
-#if COMPILER(MINGW) || COMPILER(MSVC7)
+#if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WIN_CE)
inline void atomicIncrement(int* addend) { InterlockedIncrement(reinterpret_cast<long*>(addend)); }
inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }
#else
@@ -258,14 +267,8 @@ private:
// Darwin is an exception to this rule: it is OK to call it from any thread, the only requirement is that the calls are not reentrant.
void initializeThreading();
-#if !PLATFORM(WIN_OS) || PLATFORM(WX)
-extern Mutex* atomicallyInitializedStaticMutex;
-inline void lockAtomicallyInitializedStaticMutex() { atomicallyInitializedStaticMutex->lock(); }
-inline void unlockAtomicallyInitializedStaticMutex() { atomicallyInitializedStaticMutex->unlock(); }
-#else
void lockAtomicallyInitializedStaticMutex();
void unlockAtomicallyInitializedStaticMutex();
-#endif
} // namespace WTF
diff --git a/JavaScriptCore/wtf/ThreadingGtk.cpp b/JavaScriptCore/wtf/ThreadingGtk.cpp
index 53fd1fe..24c34ca 100644
--- a/JavaScriptCore/wtf/ThreadingGtk.cpp
+++ b/JavaScriptCore/wtf/ThreadingGtk.cpp
@@ -32,15 +32,17 @@
#if !USE(PTHREADS)
+#include "CurrentTime.h"
#include "HashMap.h"
#include "MainThread.h"
-#include "MathExtras.h"
+#include "RandomNumberSeed.h"
#include <glib.h>
+#include <limits.h>
namespace WTF {
-Mutex* atomicallyInitializedStaticMutex;
+static Mutex* atomicallyInitializedStaticMutex;
static ThreadIdentifier mainThreadIdentifier;
@@ -59,27 +61,27 @@ void initializeThreading()
if (!atomicallyInitializedStaticMutex) {
atomicallyInitializedStaticMutex = new Mutex;
threadMapMutex();
- wtf_random_init();
+ initializeRandomNumberGenerator();
mainThreadIdentifier = currentThread();
initializeMainThread();
}
}
-static HashMap<ThreadIdentifier, GThread*>& threadMap()
+void lockAtomicallyInitializedStaticMutex()
{
- static HashMap<ThreadIdentifier, GThread*> map;
- return map;
+ ASSERT(atomicallyInitializedStaticMutex);
+ atomicallyInitializedStaticMutex->lock();
}
-static ThreadIdentifier establishIdentifierForThread(GThread*& thread)
+void unlockAtomicallyInitializedStaticMutex()
{
- MutexLocker locker(threadMapMutex());
-
- static ThreadIdentifier identifierCount = 1;
-
- threadMap().add(identifierCount, thread);
+ atomicallyInitializedStaticMutex->unlock();
+}
- return identifierCount++;
+static HashMap<ThreadIdentifier, GThread*>& threadMap()
+{
+ static HashMap<ThreadIdentifier, GThread*> map;
+ return map;
}
static ThreadIdentifier identifierByGthreadHandle(GThread*& thread)
@@ -95,6 +97,19 @@ static ThreadIdentifier identifierByGthreadHandle(GThread*& thread)
return 0;
}
+static ThreadIdentifier establishIdentifierForThread(GThread*& thread)
+{
+ ASSERT(!identifierByGthreadHandle(thread));
+
+ MutexLocker locker(threadMapMutex());
+
+ static ThreadIdentifier identifierCount = 1;
+
+ threadMap().add(identifierCount, thread);
+
+ return identifierCount++;
+}
+
static GThread* threadForIdentifier(ThreadIdentifier id)
{
MutexLocker locker(threadMapMutex());
@@ -111,7 +126,7 @@ static void clearThreadForIdentifier(ThreadIdentifier id)
threadMap().remove(id);
}
-ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*)
+ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
{
GThread* thread;
if (!(thread = g_thread_create(entryPoint, data, TRUE, 0))) {
@@ -129,7 +144,9 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
GThread* thread = threadForIdentifier(threadID);
- *result = g_thread_join(thread);
+ void* joinResult = g_thread_join(thread);
+ if (result)
+ *result = joinResult;
clearThreadForIdentifier(threadID);
return 0;
@@ -190,25 +207,24 @@ void ThreadCondition::wait(Mutex& mutex)
g_cond_wait(m_condition.get(), mutex.impl().get());
}
-bool ThreadCondition::timedWait(Mutex& mutex, double interval)
+bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
{
- if (interval < 0.0) {
+ // Time is in the past - return right away.
+ if (absoluteTime < currentTime())
+ return false;
+
+ // Time is too far in the future for g_cond_timed_wait - wait forever.
+ if (absoluteTime > INT_MAX) {
wait(mutex);
return true;
}
-
- int intervalSeconds = static_cast<int>(interval);
- int intervalMicroseconds = static_cast<int>((interval - intervalSeconds) * 1000000.0);
+
+ int timeSeconds = static_cast<int>(absoluteTime);
+ int timeMicroseconds = static_cast<int>((absoluteTime - timeSeconds) * 1000000.0);
GTimeVal targetTime;
- g_get_current_time(&targetTime);
-
- targetTime.tv_sec += intervalSeconds;
- targetTime.tv_usec += intervalMicroseconds;
- if (targetTime.tv_usec > 1000000) {
- targetTime.tv_usec -= 1000000;
- targetTime.tv_sec++;
- }
+ targetTime.tv_sec = timeSeconds;
+ targetTime.tv_usec = timeMicroseconds;
return g_cond_timed_wait(m_condition.get(), mutex.impl().get(), &targetTime);
}
diff --git a/JavaScriptCore/wtf/ThreadingNone.cpp b/JavaScriptCore/wtf/ThreadingNone.cpp
index c17b3b2..0be2a4b 100644
--- a/JavaScriptCore/wtf/ThreadingNone.cpp
+++ b/JavaScriptCore/wtf/ThreadingNone.cpp
@@ -26,31 +26,33 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#include "config.h"
#include "Threading.h"
namespace WTF {
-Mutex* atomicallyInitializedStaticMutex;
-
-void initializeThreading() {}
-ThreadIdentifier createThread(ThreadFunction, void*, const char*) { return 0; }
+void initializeThreading() { }
+ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char*) { return 0; }
int waitForThreadCompletion(ThreadIdentifier, void**) { return 0; }
void detachThread(ThreadIdentifier) { }
ThreadIdentifier currentThread() { return 0; }
-bool isMainThread() { return false; }
+bool isMainThread() { return true; }
-Mutex::Mutex() {}
-Mutex::~Mutex() {}
-void Mutex::lock() {}
+Mutex::Mutex() { }
+Mutex::~Mutex() { }
+void Mutex::lock() { }
bool Mutex::tryLock() { return false; }
-void Mutex::unlock() {};
+void Mutex::unlock() { }
+
+ThreadCondition::ThreadCondition() { }
+ThreadCondition::~ThreadCondition() { }
+void ThreadCondition::wait(Mutex& mutex) { }
+bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) { return false; }
+void ThreadCondition::signal() { }
+void ThreadCondition::broadcast() { }
-ThreadCondition::ThreadCondition() {}
-ThreadCondition::~ThreadCondition() {}
-void ThreadCondition::wait(Mutex& mutex) {}
-bool ThreadCondition::timedWait(Mutex& mutex, double interval) { return false; }
-void ThreadCondition::signal() {}
-void ThreadCondition::broadcast() {}
+void lockAtomicallyInitializedStaticMutex() { }
+void unlockAtomicallyInitializedStaticMutex() { }
} // namespace WebCore
diff --git a/JavaScriptCore/wtf/ThreadingPthreads.cpp b/JavaScriptCore/wtf/ThreadingPthreads.cpp
index d17a03d..105e42a 100644
--- a/JavaScriptCore/wtf/ThreadingPthreads.cpp
+++ b/JavaScriptCore/wtf/ThreadingPthreads.cpp
@@ -29,18 +29,24 @@
#include "config.h"
#include "Threading.h"
+#include "StdLibExtras.h"
+
#if USE(PTHREADS)
+#include "CurrentTime.h"
#include "HashMap.h"
#include "MainThread.h"
-#include "MathExtras.h"
+#include "RandomNumberSeed.h"
#include <errno.h>
+#include <limits.h>
#include <sys/time.h>
namespace WTF {
-Mutex* atomicallyInitializedStaticMutex;
+typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap;
+
+static Mutex* atomicallyInitializedStaticMutex;
#if !PLATFORM(DARWIN)
static ThreadIdentifier mainThreadIdentifier; // The thread that was the first to call initializeThreading(), which must be the main thread.
@@ -48,7 +54,7 @@ static ThreadIdentifier mainThreadIdentifier; // The thread that was the first t
static Mutex& threadMapMutex()
{
- static Mutex mutex;
+ DEFINE_STATIC_LOCAL(Mutex, mutex, ());
return mutex;
}
@@ -57,7 +63,7 @@ void initializeThreading()
if (!atomicallyInitializedStaticMutex) {
atomicallyInitializedStaticMutex = new Mutex;
threadMapMutex();
- wtf_random_init();
+ initializeRandomNumberGenerator();
#if !PLATFORM(DARWIN)
mainThreadIdentifier = currentThread();
#endif
@@ -65,28 +71,28 @@ void initializeThreading()
}
}
-static HashMap<ThreadIdentifier, pthread_t>& threadMap()
+void lockAtomicallyInitializedStaticMutex()
{
- static HashMap<ThreadIdentifier, pthread_t> map;
- return map;
+ ASSERT(atomicallyInitializedStaticMutex);
+ atomicallyInitializedStaticMutex->lock();
}
-static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHandle)
+void unlockAtomicallyInitializedStaticMutex()
{
- MutexLocker locker(threadMapMutex());
-
- static ThreadIdentifier identifierCount = 1;
+ atomicallyInitializedStaticMutex->unlock();
+}
- threadMap().add(identifierCount, pthreadHandle);
-
- return identifierCount++;
+static ThreadMap& threadMap()
+{
+ DEFINE_STATIC_LOCAL(ThreadMap, map, ());
+ return map;
}
static ThreadIdentifier identifierByPthreadHandle(const pthread_t& pthreadHandle)
{
MutexLocker locker(threadMapMutex());
- HashMap<ThreadIdentifier, pthread_t>::iterator i = threadMap().begin();
+ ThreadMap::iterator i = threadMap().begin();
for (; i != threadMap().end(); ++i) {
if (pthread_equal(i->second, pthreadHandle))
return i->first;
@@ -95,6 +101,19 @@ static ThreadIdentifier identifierByPthreadHandle(const pthread_t& pthreadHandle
return 0;
}
+static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHandle)
+{
+ ASSERT(!identifierByPthreadHandle(pthreadHandle));
+
+ MutexLocker locker(threadMapMutex());
+
+ static ThreadIdentifier identifierCount = 1;
+
+ threadMap().add(identifierCount, pthreadHandle);
+
+ return identifierCount++;
+}
+
static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id)
{
MutexLocker locker(threadMapMutex());
@@ -111,7 +130,7 @@ static void clearPthreadHandleForIdentifier(ThreadIdentifier id)
threadMap().remove(id);
}
-ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*)
+ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
{
pthread_t threadHandle;
if (pthread_create(&threadHandle, NULL, entryPoint, data)) {
@@ -119,19 +138,9 @@ ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*
return 0;
}
- ThreadIdentifier threadID = establishIdentifierForPthreadHandle(threadHandle);
- return threadID;
+ return establishIdentifierForPthreadHandle(threadHandle);
}
-#if PLATFORM(MAC)
-// This function is deprecated but needs to be kept around for backward
-// compatibility. Use the 3-argument version of createThread above instead.
-ThreadIdentifier createThread(ThreadFunction entryPoint, void* data)
-{
- return createThread(entryPoint, data, 0);
-}
-#endif
-
int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
{
ASSERT(threadID);
@@ -208,7 +217,7 @@ void Mutex::unlock()
if (pthread_mutex_unlock(&m_mutex) != 0)
ASSERT(false);
}
-
+
ThreadCondition::ThreadCondition()
{
pthread_cond_init(&m_condition, NULL);
@@ -225,28 +234,22 @@ void ThreadCondition::wait(Mutex& mutex)
ASSERT(false);
}
-bool ThreadCondition::timedWait(Mutex& mutex, double secondsToWait)
+bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
{
- if (secondsToWait < 0.0) {
+ if (absoluteTime < currentTime())
+ return false;
+
+ if (absoluteTime > INT_MAX) {
wait(mutex);
return true;
}
- int intervalSeconds = static_cast<int>(secondsToWait);
- int intervalMicroseconds = static_cast<int>((secondsToWait - intervalSeconds) * 1000000.0);
+ int timeSeconds = static_cast<int>(absoluteTime);
+ int timeNanoseconds = static_cast<int>((absoluteTime - timeSeconds) * 1E9);
- // Current time comes in sec/microsec
- timeval currentTime;
- gettimeofday(&currentTime, NULL);
-
- // Target time comes in sec/nanosec
timespec targetTime;
- targetTime.tv_sec = currentTime.tv_sec + intervalSeconds;
- targetTime.tv_nsec = (currentTime.tv_usec + intervalMicroseconds) * 1000;
- if (targetTime.tv_nsec > 1000000000) {
- targetTime.tv_nsec -= 1000000000;
- targetTime.tv_sec++;
- }
+ targetTime.tv_sec = timeSeconds;
+ targetTime.tv_nsec = timeNanoseconds;
return pthread_cond_timedwait(&m_condition, &mutex.impl(), &targetTime) == 0;
}
diff --git a/JavaScriptCore/wtf/ThreadingQt.cpp b/JavaScriptCore/wtf/ThreadingQt.cpp
index b24f241..55a479b 100644
--- a/JavaScriptCore/wtf/ThreadingQt.cpp
+++ b/JavaScriptCore/wtf/ThreadingQt.cpp
@@ -29,9 +29,10 @@
#include "config.h"
#include "Threading.h"
+#include "CurrentTime.h"
#include "HashMap.h"
#include "MainThread.h"
-#include "MathExtras.h"
+#include "RandomNumberSeed.h"
#include <QCoreApplication>
#include <QMutex>
@@ -64,7 +65,7 @@ void ThreadPrivate::run()
}
-Mutex* atomicallyInitializedStaticMutex;
+static Mutex* atomicallyInitializedStaticMutex;
static ThreadIdentifier mainThreadIdentifier;
@@ -80,8 +81,23 @@ static HashMap<ThreadIdentifier, QThread*>& threadMap()
return map;
}
+static ThreadIdentifier identifierByQthreadHandle(QThread*& thread)
+{
+ MutexLocker locker(threadMapMutex());
+
+ HashMap<ThreadIdentifier, QThread*>::iterator i = threadMap().begin();
+ for (; i != threadMap().end(); ++i) {
+ if (i->second == thread)
+ return i->first;
+ }
+
+ return 0;
+}
+
static ThreadIdentifier establishIdentifierForThread(QThread*& thread)
{
+ ASSERT(!identifierByQthreadHandle(thread));
+
MutexLocker locker(threadMapMutex());
static ThreadIdentifier identifierCount = 1;
@@ -100,19 +116,6 @@ static void clearThreadForIdentifier(ThreadIdentifier id)
threadMap().remove(id);
}
-static ThreadIdentifier identifierByQthreadHandle(QThread*& thread)
-{
- MutexLocker locker(threadMapMutex());
-
- HashMap<ThreadIdentifier, QThread*>::iterator i = threadMap().begin();
- for (; i != threadMap().end(); ++i) {
- if (i->second == thread)
- return i->first;
- }
-
- return 0;
-}
-
static QThread* threadForIdentifier(ThreadIdentifier id)
{
MutexLocker locker(threadMapMutex());
@@ -122,10 +125,10 @@ static QThread* threadForIdentifier(ThreadIdentifier id)
void initializeThreading()
{
- if(!atomicallyInitializedStaticMutex) {
+ if (!atomicallyInitializedStaticMutex) {
atomicallyInitializedStaticMutex = new Mutex;
threadMapMutex();
- wtf_random_init();
+ initializeRandomNumberGenerator();
QThread* mainThread = QCoreApplication::instance()->thread();
mainThreadIdentifier = identifierByQthreadHandle(mainThread);
if (!mainThreadIdentifier)
@@ -134,7 +137,18 @@ void initializeThreading()
}
}
-ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*)
+void lockAtomicallyInitializedStaticMutex()
+{
+ ASSERT(atomicallyInitializedStaticMutex);
+ atomicallyInitializedStaticMutex->lock();
+}
+
+void unlockAtomicallyInitializedStaticMutex()
+{
+ atomicallyInitializedStaticMutex->unlock();
+}
+
+ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
{
ThreadPrivate* thread = new ThreadPrivate(entryPoint, data);
if (!thread) {
@@ -157,7 +171,8 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
bool res = thread->wait();
clearThreadForIdentifier(threadID);
- *result = static_cast<ThreadPrivate*>(thread)->getReturnValue();
+ if (result)
+ *result = static_cast<ThreadPrivate*>(thread)->getReturnValue();
return !res;
}
@@ -219,15 +234,20 @@ void ThreadCondition::wait(Mutex& mutex)
m_condition->wait(mutex.impl());
}
-bool ThreadCondition::timedWait(Mutex& mutex, double secondsToWait)
+bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
{
- if (secondsToWait < 0.0) {
- wait(mutex);
- return true;
- }
+ double currentTime = WTF::currentTime();
+
+ // Time is in the past - return immediately.
+ if (absoluteTime < currentTime)
+ return false;
+
+ double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
+ // Qt defines wait for up to ULONG_MAX milliseconds.
+ if (intervalMilliseconds >= ULONG_MAX)
+ intervalMilliseconds = ULONG_MAX;
- unsigned long millisecondsToWait = static_cast<unsigned long>(secondsToWait * 1000.0);
- return m_condition->wait(mutex.impl(), millisecondsToWait);
+ return m_condition->wait(mutex.impl(), static_cast<unsigned long>(intervalMilliseconds));
}
void ThreadCondition::signal()
diff --git a/JavaScriptCore/wtf/ThreadingWin.cpp b/JavaScriptCore/wtf/ThreadingWin.cpp
index 00ad149..399fb38 100644
--- a/JavaScriptCore/wtf/ThreadingWin.cpp
+++ b/JavaScriptCore/wtf/ThreadingWin.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,56 +25,76 @@
* 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.
+ */
+
+/*
+ * There are numerous academic and practical works on how to implement pthread_cond_wait/pthread_cond_signal/pthread_cond_broadcast
+ * functions on Win32. Here is one example: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html which is widely credited as a 'starting point'
+ * of modern attempts. There are several more or less proven implementations, one in Boost C++ library (http://www.boost.org) and another
+ * in pthreads-win32 (http://sourceware.org/pthreads-win32/).
+ *
+ * The number of articles and discussions is the evidence of significant difficulties in implementing these primitives correctly.
+ * The brief search of revisions, ChangeLog entries, discussions in comp.programming.threads and other places clearly documents
+ * numerous pitfalls and performance problems the authors had to overcome to arrive to the suitable implementations.
+ * Optimally, WebKit would use one of those supported/tested libraries directly. To roll out our own implementation is impractical,
+ * if even for the lack of sufficient testing. However, a faithful reproduction of the code from one of the popular supported
+ * libraries seems to be a good compromise.
+ *
+ * The early Boost implementation (http://www.boxbackup.org/trac/browser/box/nick/win/lib/win32/boost_1_32_0/libs/thread/src/condition.cpp?rev=30)
+ * is identical to pthreads-win32 (http://sourceware.org/cgi-bin/cvsweb.cgi/pthreads/pthread_cond_wait.c?rev=1.10&content-type=text/x-cvsweb-markup&cvsroot=pthreads-win32).
+ * Current Boost uses yet another (although seemingly equivalent) algorithm which came from their 'thread rewrite' effort.
*
- * =============================================================================
- * Note: The implementation of condition variables under the Windows
- * plaform was based on that of the excellent BOOST C++ library. It
- * has been rewritten to fit in with the WebKit architecture and to
- * use its coding conventions.
- * =============================================================================
+ * This file includes timedWait/signal/broadcast implementations translated to WebKit coding style from the latest algorithm by
+ * Alexander Terekhov and Louis Thomas, as captured here: http://sourceware.org/cgi-bin/cvsweb.cgi/pthreads/pthread_cond_wait.c?rev=1.10&content-type=text/x-cvsweb-markup&cvsroot=pthreads-win32
+ * It replaces the implementation of their previous algorithm, also documented in the same source above.
+ * The naming and comments are left very close to original to enable easy cross-check.
*
- * The Boost license is virtually identical to the Apple variation at the
- * top of this file, but is included here for completeness:
+ * The corresponding Pthreads-win32 License is included below, and CONTRIBUTORS file which it refers to is added to
+ * source directory (as CONTRIBUTORS.pthreads-win32).
+ */
+
+/*
+ * Pthreads-win32 - POSIX Threads Library for Win32
+ * Copyright(C) 1998 John E. Bossom
+ * Copyright(C) 1999,2005 Pthreads-win32 contributors
*
- * Boost Software License - Version 1.0 - August 17th, 2003
+ * Contact Email: rpj@callisto.canberra.edu.au
*
- * Permission is hereby granted, free of charge, to any person or organization
- * obtaining a copy of the software and accompanying documentation covered by
- * this license (the "Software") to use, reproduce, display, distribute,
- * execute, and transmit the Software, and to prepare derivative works of the
- * Software, and to permit third-parties to whom the Software is furnished to
- * do so, all subject to the following:
+ * The current list of contributors is contained
+ * in the file CONTRIBUTORS included with the source
+ * code distribution. The list can also be seen at the
+ * following World Wide Web location:
+ * http://sources.redhat.com/pthreads-win32/contributors.html
*
- * The copyright notices in the Software and this entire statement, including
- * the above license grant, this restriction and the following disclaimer,
- * must be included in all copies of the Software, in whole or in part, and
- * all derivative works of the Software, unless such copies or derivative
- * works are solely in the form of machine-executable object code generated by
- * a source language processor.
+ * 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.
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
- * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
+ * 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 in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include "config.h"
#include "Threading.h"
#include "MainThread.h"
+#if !USE(PTHREADS) && PLATFORM(WIN_OS)
+#include "ThreadSpecific.h"
+#endif
#include <process.h>
#include <windows.h>
+#include <wtf/CurrentTime.h>
#include <wtf/HashMap.h>
#include <wtf/MathExtras.h>
-
-#if PLATFORM(WIN) && USE(PTHREADS)
-// Currently, Apple's Windows port uses a mixture of native and pthreads functions in FastMalloc.
-// To ensure that thread-specific data is properly destroyed, we need to end each thread with pthread_exit().
-#include <pthread.h>
-#endif
+#include <wtf/RandomNumberSeed.h>
namespace WTF {
@@ -111,6 +132,7 @@ static Mutex* atomicallyInitializedStaticMutex;
void lockAtomicallyInitializedStaticMutex()
{
+ ASSERT(atomicallyInitializedStaticMutex);
atomicallyInitializedStaticMutex->lock();
}
@@ -132,7 +154,7 @@ void initializeThreading()
if (!atomicallyInitializedStaticMutex) {
atomicallyInitializedStaticMutex = new Mutex;
threadMapMutex();
- wtf_random_init();
+ initializeRandomNumberGenerator();
initializeMainThread();
mainThreadIdentifier = currentThread();
setThreadName(mainThreadIdentifier, "Main Thread");
@@ -148,6 +170,7 @@ static HashMap<DWORD, HANDLE>& threadMap()
static void storeThreadHandleByIdentifier(DWORD threadID, HANDLE threadHandle)
{
MutexLocker locker(threadMapMutex());
+ ASSERT(!threadMap().contains(threadID));
threadMap().add(threadID, threadHandle);
}
@@ -178,15 +201,15 @@ static unsigned __stdcall wtfThreadEntryPoint(void* param)
void* result = invocation.function(invocation.data);
-#if PLATFORM(WIN) && USE(PTHREADS)
- // pthreads-win32 knows how to work with threads created with Win32 or CRT functions, so it's OK to mix APIs.
- pthread_exit(result);
+#if !USE(PTHREADS) && PLATFORM(WIN_OS)
+ // Do the TLS cleanup.
+ ThreadSpecificThreadExit();
#endif
return reinterpret_cast<unsigned>(result);
}
-ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* threadName)
+ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char* threadName)
{
unsigned threadIdentifier = 0;
ThreadIdentifier threadID = 0;
@@ -206,13 +229,6 @@ ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*
return threadID;
}
-// This function is deprecated but needs to be kept around for backward
-// compatibility. Use the 3-argument version of createThread above.
-ThreadIdentifier createThread(ThreadFunction entryPoint, void* data)
-{
- return createThread(entryPoint, data, 0);
-}
-
int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
{
ASSERT(threadID);
@@ -221,11 +237,11 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
if (!threadHandle)
LOG_ERROR("ThreadIdentifier %u did not correspond to an active thread when trying to quit", threadID);
- DWORD joinResult = ::WaitForSingleObject(threadHandle, INFINITE);
+ DWORD joinResult = WaitForSingleObject(threadHandle, INFINITE);
if (joinResult == WAIT_FAILED)
LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
- ::CloseHandle(threadHandle);
+ CloseHandle(threadHandle);
clearThreadHandleForIdentifier(threadID);
return joinResult;
@@ -237,13 +253,13 @@ void detachThread(ThreadIdentifier threadID)
HANDLE threadHandle = threadHandleForIdentifier(threadID);
if (threadHandle)
- ::CloseHandle(threadHandle);
+ CloseHandle(threadHandle);
clearThreadHandleForIdentifier(threadID);
}
ThreadIdentifier currentThread()
{
- return static_cast<ThreadIdentifier>(::GetCurrentThreadId());
+ return static_cast<ThreadIdentifier>(GetCurrentThreadId());
}
bool isMainThread()
@@ -254,17 +270,17 @@ bool isMainThread()
Mutex::Mutex()
{
m_mutex.m_recursionCount = 0;
- ::InitializeCriticalSection(&m_mutex.m_internalMutex);
+ InitializeCriticalSection(&m_mutex.m_internalMutex);
}
Mutex::~Mutex()
{
- ::DeleteCriticalSection(&m_mutex.m_internalMutex);
+ DeleteCriticalSection(&m_mutex.m_internalMutex);
}
void Mutex::lock()
{
- ::EnterCriticalSection(&m_mutex.m_internalMutex);
+ EnterCriticalSection(&m_mutex.m_internalMutex);
++m_mutex.m_recursionCount;
}
@@ -276,14 +292,14 @@ bool Mutex::tryLock()
// treats this as a successful case, it changes the behavior of several
// tests in WebKit that check to see if the current thread already
// owned this mutex (see e.g., IconDatabase::getOrCreateIconRecord)
- DWORD result = ::TryEnterCriticalSection(&m_mutex.m_internalMutex);
+ DWORD result = TryEnterCriticalSection(&m_mutex.m_internalMutex);
if (result != 0) { // We got the lock
// If this thread already had the lock, we must unlock and
// return false so that we mimic the behavior of POSIX's
// pthread_mutex_trylock:
if (m_mutex.m_recursionCount > 0) {
- ::LeaveCriticalSection(&m_mutex.m_internalMutex);
+ LeaveCriticalSection(&m_mutex.m_internalMutex);
return false;
}
@@ -297,183 +313,165 @@ bool Mutex::tryLock()
void Mutex::unlock()
{
--m_mutex.m_recursionCount;
- ::LeaveCriticalSection(&m_mutex.m_internalMutex);
+ LeaveCriticalSection(&m_mutex.m_internalMutex);
}
-static const long MaxSemaphoreCount = static_cast<long>(~0UL >> 1);
-
-ThreadCondition::ThreadCondition()
+bool PlatformCondition::timedWait(PlatformMutex& mutex, DWORD durationMilliseconds)
{
- m_condition.m_timedOut = 0;
- m_condition.m_blocked = 0;
- m_condition.m_waitingForRemoval = 0;
- m_condition.m_gate = ::CreateSemaphore(0, 1, 1, 0);
- m_condition.m_queue = ::CreateSemaphore(0, 0, MaxSemaphoreCount, 0);
- m_condition.m_mutex = ::CreateMutex(0, 0, 0);
-
- if (!m_condition.m_gate || !m_condition.m_queue || !m_condition.m_mutex) {
- if (m_condition.m_gate)
- ::CloseHandle(m_condition.m_gate);
- if (m_condition.m_queue)
- ::CloseHandle(m_condition.m_queue);
- if (m_condition.m_mutex)
- ::CloseHandle(m_condition.m_mutex);
- }
-}
-
-ThreadCondition::~ThreadCondition()
-{
- ::CloseHandle(m_condition.m_gate);
- ::CloseHandle(m_condition.m_queue);
- ::CloseHandle(m_condition.m_mutex);
-}
-
-void ThreadCondition::wait(Mutex& mutex)
-{
- PlatformMutex& cs = mutex.impl();
-
// Enter the wait state.
- DWORD res = ::WaitForSingleObject(m_condition.m_gate, INFINITE);
+ DWORD res = WaitForSingleObject(m_blockLock, INFINITE);
ASSERT(res == WAIT_OBJECT_0);
- ++m_condition.m_blocked;
- res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0);
+ ++m_waitersBlocked;
+ res = ReleaseSemaphore(m_blockLock, 1, 0);
ASSERT(res);
- ::LeaveCriticalSection(&cs.m_internalMutex);
+ LeaveCriticalSection(&mutex.m_internalMutex);
- res = ::WaitForSingleObject(m_condition.m_queue, INFINITE);
- ASSERT(res == WAIT_OBJECT_0);
+ // Main wait - use timeout.
+ bool timedOut = (WaitForSingleObject(m_blockQueue, durationMilliseconds) == WAIT_TIMEOUT);
- res = ::WaitForSingleObject(m_condition.m_mutex, INFINITE);
+ res = WaitForSingleObject(m_unblockLock, INFINITE);
ASSERT(res == WAIT_OBJECT_0);
- size_t wasWaiting = m_condition.m_waitingForRemoval;
- size_t wasTimedOut = m_condition.m_timedOut;
- if (wasWaiting != 0) {
- if (--m_condition.m_waitingForRemoval == 0) {
- if (m_condition.m_blocked != 0) {
- res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0); // open m_gate
- ASSERT(res);
- wasWaiting = 0;
- }
- else if (m_condition.m_timedOut != 0)
- m_condition.m_timedOut = 0;
- }
- } else if (++m_condition.m_timedOut == ((std::numeric_limits<unsigned>::max)() / 2)) {
- // timeout occured, normalize the m_condition.m_timedOut count
+
+ int signalsLeft = m_waitersToUnblock;
+
+ if (m_waitersToUnblock)
+ --m_waitersToUnblock;
+ else if (++m_waitersGone == (INT_MAX / 2)) { // timeout/canceled or spurious semaphore
+ // timeout or spurious wakeup occured, normalize the m_waitersGone count
// this may occur if many calls to wait with a timeout are made and
// no call to notify_* is made
- res = ::WaitForSingleObject(m_condition.m_gate, INFINITE);
+ res = WaitForSingleObject(m_blockLock, INFINITE);
ASSERT(res == WAIT_OBJECT_0);
- m_condition.m_blocked -= m_condition.m_timedOut;
- res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0);
+ m_waitersBlocked -= m_waitersGone;
+ res = ReleaseSemaphore(m_blockLock, 1, 0);
ASSERT(res);
- m_condition.m_timedOut = 0;
+ m_waitersGone = 0;
}
- res = ::ReleaseMutex(m_condition.m_mutex);
+
+ res = ReleaseMutex(m_unblockLock);
ASSERT(res);
- if (wasWaiting == 1) {
- for (/**/ ; wasTimedOut; --wasTimedOut) {
- // better now than spurious later
- res = ::WaitForSingleObject(m_condition.m_queue, INFINITE);
- ASSERT(res == WAIT_OBJECT_0);
- }
- res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0);
+ if (signalsLeft == 1) {
+ res = ReleaseSemaphore(m_blockLock, 1, 0); // Open the gate.
ASSERT(res);
}
- ::EnterCriticalSection (&cs.m_internalMutex);
-}
+ EnterCriticalSection (&mutex.m_internalMutex);
-bool ThreadCondition::timedWait(Mutex& mutex, double interval)
-{
- // Empty for now
- ASSERT(false);
- return false;
+ return !timedOut;
}
-void ThreadCondition::signal()
+void PlatformCondition::signal(bool unblockAll)
{
- unsigned signals = 0;
+ unsigned signalsToIssue = 0;
- DWORD res = ::WaitForSingleObject(m_condition.m_mutex, INFINITE);
+ DWORD res = WaitForSingleObject(m_unblockLock, INFINITE);
ASSERT(res == WAIT_OBJECT_0);
- if (m_condition.m_waitingForRemoval != 0) { // the m_gate is already closed
- if (m_condition.m_blocked == 0) {
- res = ::ReleaseMutex(m_condition.m_mutex);
+ if (m_waitersToUnblock) { // the gate is already closed
+ if (!m_waitersBlocked) { // no-op
+ res = ReleaseMutex(m_unblockLock);
ASSERT(res);
return;
}
- ++m_condition.m_waitingForRemoval;
- --m_condition.m_blocked;
-
- signals = 1;
- } else {
- res = ::WaitForSingleObject(m_condition.m_gate, INFINITE);
+ if (unblockAll) {
+ signalsToIssue = m_waitersBlocked;
+ m_waitersToUnblock += m_waitersBlocked;
+ m_waitersBlocked = 0;
+ } else {
+ signalsToIssue = 1;
+ ++m_waitersToUnblock;
+ --m_waitersBlocked;
+ }
+ } else if (m_waitersBlocked > m_waitersGone) {
+ res = WaitForSingleObject(m_blockLock, INFINITE); // Close the gate.
ASSERT(res == WAIT_OBJECT_0);
- if (m_condition.m_blocked > m_condition.m_timedOut) {
- if (m_condition.m_timedOut != 0) {
- m_condition.m_blocked -= m_condition.m_timedOut;
- m_condition.m_timedOut = 0;
- }
- signals = m_condition.m_waitingForRemoval = 1;
- --m_condition.m_blocked;
+ if (m_waitersGone != 0) {
+ m_waitersBlocked -= m_waitersGone;
+ m_waitersGone = 0;
+ }
+ if (unblockAll) {
+ signalsToIssue = m_waitersBlocked;
+ m_waitersToUnblock = m_waitersBlocked;
+ m_waitersBlocked = 0;
} else {
- res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0);
- ASSERT(res);
+ signalsToIssue = 1;
+ m_waitersToUnblock = 1;
+ --m_waitersBlocked;
}
+ } else { // No-op.
+ res = ReleaseMutex(m_unblockLock);
+ ASSERT(res);
+ return;
}
- res =::ReleaseMutex(m_condition.m_mutex);
+ res = ReleaseMutex(m_unblockLock);
ASSERT(res);
- if (signals) {
- res = ::ReleaseSemaphore(m_condition.m_queue, signals, 0);
+ if (signalsToIssue) {
+ res = ReleaseSemaphore(m_blockQueue, signalsToIssue, 0);
ASSERT(res);
}
}
-void ThreadCondition::broadcast()
+static const long MaxSemaphoreCount = static_cast<long>(~0UL >> 1);
+
+ThreadCondition::ThreadCondition()
{
- unsigned signals = 0;
+ m_condition.m_waitersGone = 0;
+ m_condition.m_waitersBlocked = 0;
+ m_condition.m_waitersToUnblock = 0;
+ m_condition.m_blockLock = CreateSemaphore(0, 1, 1, 0);
+ m_condition.m_blockQueue = CreateSemaphore(0, 0, MaxSemaphoreCount, 0);
+ m_condition.m_unblockLock = CreateMutex(0, 0, 0);
+
+ if (!m_condition.m_blockLock || !m_condition.m_blockQueue || !m_condition.m_unblockLock) {
+ if (m_condition.m_blockLock)
+ CloseHandle(m_condition.m_blockLock);
+ if (m_condition.m_blockQueue)
+ CloseHandle(m_condition.m_blockQueue);
+ if (m_condition.m_unblockLock)
+ CloseHandle(m_condition.m_unblockLock);
+ }
+}
- DWORD res = ::WaitForSingleObject(m_condition.m_mutex, INFINITE);
- ASSERT(res == WAIT_OBJECT_0);
+ThreadCondition::~ThreadCondition()
+{
+ CloseHandle(m_condition.m_blockLock);
+ CloseHandle(m_condition.m_blockQueue);
+ CloseHandle(m_condition.m_unblockLock);
+}
- if (m_condition.m_waitingForRemoval != 0) { // the m_gate is already closed
- if (m_condition.m_blocked == 0) {
- res = ::ReleaseMutex(m_condition.m_mutex);
- ASSERT(res);
- return;
- }
+void ThreadCondition::wait(Mutex& mutex)
+{
+ m_condition.timedWait(mutex.impl(), INFINITE);
+}
- m_condition.m_waitingForRemoval += (signals = m_condition.m_blocked);
- m_condition.m_blocked = 0;
- } else {
- res = ::WaitForSingleObject(m_condition.m_gate, INFINITE);
- ASSERT(res == WAIT_OBJECT_0);
- if (m_condition.m_blocked > m_condition.m_timedOut) {
- if (m_condition.m_timedOut != 0) {
- m_condition.m_blocked -= m_condition.m_timedOut;
- m_condition.m_timedOut = 0;
- }
- signals = m_condition.m_waitingForRemoval = m_condition.m_blocked;
- m_condition.m_blocked = 0;
- } else {
- res = ::ReleaseSemaphore(m_condition.m_gate, 1, 0);
- ASSERT(res);
- }
- }
+bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
+{
+ double currentTime = WTF::currentTime();
- res = ::ReleaseMutex(m_condition.m_mutex);
- ASSERT(res);
+ // Time is in the past - return immediately.
+ if (absoluteTime < currentTime)
+ return false;
- if (signals) {
- res = ::ReleaseSemaphore(m_condition.m_queue, signals, 0);
- ASSERT(res);
- }
+ double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
+ if (intervalMilliseconds >= INT_MAX)
+ intervalMilliseconds = INT_MAX;
+
+ return m_condition.timedWait(mutex.impl(), static_cast<unsigned long>(intervalMilliseconds));
+}
+
+void ThreadCondition::signal()
+{
+ m_condition.signal(false); // Unblock only 1 thread.
+}
+
+void ThreadCondition::broadcast()
+{
+ m_condition.signal(true); // Unblock all threads.
}
} // namespace WTF
diff --git a/JavaScriptCore/wtf/Vector.h b/JavaScriptCore/wtf/Vector.h
index c0bc132..880b45d 100644
--- a/JavaScriptCore/wtf/Vector.h
+++ b/JavaScriptCore/wtf/Vector.h
@@ -37,7 +37,7 @@ namespace WTF {
using std::max;
// WTF_ALIGN_OF / WTF_ALIGNED
- #if COMPILER(GCC) || COMPILER(MINGW)
+ #if COMPILER(GCC) || COMPILER(MINGW) || COMPILER(RVCT) || COMPILER(WINSCW)
#define WTF_ALIGN_OF(type) __alignof__(type)
#define WTF_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((__aligned__(n)))
#elif COMPILER(MSVC)
@@ -279,8 +279,10 @@ namespace WTF {
void deallocateBuffer(T* bufferToDeallocate)
{
- if (m_buffer == bufferToDeallocate)
+ if (m_buffer == bufferToDeallocate) {
m_buffer = 0;
+ m_capacity = 0;
+ }
fastFree(bufferToDeallocate);
}
@@ -346,6 +348,8 @@ namespace WTF {
std::swap(m_buffer, other.m_buffer);
std::swap(m_capacity, other.m_capacity);
}
+
+ void restoreInlineBufferIfNeeded() { }
using Base::allocateBuffer;
using Base::deallocateBuffer;
@@ -393,6 +397,14 @@ namespace WTF {
return;
Base::deallocateBuffer(bufferToDeallocate);
}
+
+ void restoreInlineBufferIfNeeded()
+ {
+ if (m_buffer)
+ return;
+ m_buffer = inlineBuffer();
+ m_capacity = inlineCapacity;
+ }
using Base::buffer;
using Base::bufferSlot;
@@ -442,7 +454,7 @@ namespace WTF {
~Vector()
{
- clear();
+ if (m_size) shrink(0);
}
Vector(const Vector&);
@@ -492,8 +504,9 @@ namespace WTF {
void resize(size_t size);
void reserveCapacity(size_t newCapacity);
void shrinkCapacity(size_t newCapacity);
+ void shrinkToFit() { shrinkCapacity(size()); }
- void clear() { if (m_size) shrink(0); }
+ void clear() { shrinkCapacity(0); }
template<typename U> void append(const U*, size_t);
template<typename U> void append(const U&);
@@ -725,7 +738,8 @@ namespace WTF {
if (newCapacity >= capacity())
return;
- resize(min(m_size, newCapacity));
+ if (newCapacity < size())
+ shrink(newCapacity);
T* oldBuffer = begin();
if (newCapacity > 0) {
@@ -736,6 +750,7 @@ namespace WTF {
}
m_buffer.deallocateBuffer(oldBuffer);
+ m_buffer.restoreInlineBufferIfNeeded();
}
// Templatizing these is better than just letting the conversion happen implicitly,
diff --git a/JavaScriptCore/wtf/VectorTraits.h b/JavaScriptCore/wtf/VectorTraits.h
index 71aaec8..6efe36c 100644
--- a/JavaScriptCore/wtf/VectorTraits.h
+++ b/JavaScriptCore/wtf/VectorTraits.h
@@ -1,6 +1,5 @@
/*
- * This file is part of the KDE libraries
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 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
diff --git a/JavaScriptCore/kjs/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp
index 2dc2cff..c9e8d30 100644
--- a/JavaScriptCore/kjs/dtoa.cpp
+++ b/JavaScriptCore/wtf/dtoa.cpp
@@ -135,7 +135,11 @@
#include "config.h"
#include "dtoa.h"
+#if HAVE(ERRNO_H)
#include <errno.h>
+#else
+#define NO_ERRNO
+#endif
#include <float.h>
#include <math.h>
#include <stdint.h>
@@ -152,10 +156,7 @@
#pragma warning(disable: 4554)
#endif
-// ANDROID : || PLATFORM(MIDDLE_ENDIAN) added in #if statement below
-// for dtoa, MIDDLE_ENDIAN needs to be same as BIG_ENDIAN according to the following site
-// http://lists.debian.org/debian-arm/2003/11/msg00008.html
-#if PLATFORM(BIG_ENDIAN) || PLATFORM(MIDDLE_ENDIAN)
+#if PLATFORM(BIG_ENDIAN)
#define IEEE_MC68k
#elif PLATFORM(MIDDLE_ENDIAN)
#define IEEE_ARM
@@ -169,7 +170,7 @@
Exactly one of IEEE_8087, IEEE_ARM or IEEE_MC68k should be defined.
#endif
-namespace JSC {
+namespace WTF {
#if ENABLE(JSC_MULTIPLE_THREADS)
Mutex* s_dtoaP5Mutex;
@@ -1720,7 +1721,7 @@ retfree:
Bfree(delta);
ret:
if (se)
- *se = (char*)s;
+ *se = const_cast<char*>(s);
return sign ? -dval(rv) : dval(rv);
}
@@ -2435,4 +2436,4 @@ ret1:
return s0;
}
-} // namespace JSC
+} // namespace WTF
diff --git a/JavaScriptCore/kjs/dtoa.h b/JavaScriptCore/wtf/dtoa.h
index 690ebc8..ed858c0 100644
--- a/JavaScriptCore/kjs/dtoa.h
+++ b/JavaScriptCore/wtf/dtoa.h
@@ -18,14 +18,14 @@
*
*/
-#ifndef KJS_dtoa_h
-#define KJS_dtoa_h
+#ifndef WTF_dtoa_h
+#define WTF_dtoa_h
namespace WTF {
class Mutex;
}
-namespace JSC {
+namespace WTF {
extern WTF::Mutex* s_dtoaP5Mutex;
@@ -33,6 +33,6 @@ namespace JSC {
char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve);
void freedtoa(char* s);
-} // namespace JSC
+} // namespace WTF
-#endif /* KJS_dtoa_h */
+#endif // WTF_dtoa_h
diff --git a/JavaScriptCore/wtf/unicode/Unicode.h b/JavaScriptCore/wtf/unicode/Unicode.h
index 9cd3555..e6e8f23 100644
--- a/JavaScriptCore/wtf/unicode/Unicode.h
+++ b/JavaScriptCore/wtf/unicode/Unicode.h
@@ -1,6 +1,6 @@
/*
- * This file is part of the KDE libraries
* Copyright (C) 2006 George Staikos <staikos@kde.org>
+ * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -19,10 +19,10 @@
*
*/
-#ifndef KJS_UNICODE_H
-#define KJS_UNICODE_H
+#ifndef WTF_UNICODE_H
+#define WTF_UNICODE_H
-#include <wtf/Platform.h>
+#include <wtf/Assertions.h>
#if USE(QT4_UNICODE)
#include "qt4/UnicodeQt4.h"
@@ -32,5 +32,6 @@
#error "Unknown Unicode implementation"
#endif
-#endif
-// vim: ts=2 sw=2 et
+COMPILE_ASSERT(sizeof(UChar) == 2, UCharIsTwoBytes);
+
+#endif // WTF_UNICODE_H
diff --git a/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp b/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
index a8bcc81..79dec79 100644
--- a/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
+++ b/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
@@ -45,7 +45,7 @@ namespace WTF {
static UCollator* cachedCollator;
static Mutex& cachedCollatorMutex()
{
- AtomicallyInitializedStatic(Mutex, mutex);
+ AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
return mutex;
}
diff --git a/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h b/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
index 7cdc55c..608aea6 100644
--- a/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
+++ b/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006 George Staikos <staikos@kde.org>
* Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -20,8 +20,8 @@
*
*/
-#ifndef KJS_UNICODE_ICU_H
-#define KJS_UNICODE_ICU_H
+#ifndef WTF_UNICODE_ICU_H
+#define WTF_UNICODE_ICU_H
#include <stdlib.h>
#include <unicode/uchar.h>
@@ -216,4 +216,4 @@ inline int umemcasecmp(const UChar* a, const UChar* b, int len)
} }
-#endif
+#endif // WTF_UNICODE_ICU_H
diff --git a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
index d285a8f..d7d78ce 100644
--- a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
+++ b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 George Staikos <staikos@kde.org>
* Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -19,8 +20,8 @@
*
*/
-#ifndef KJS_UNICODE_QT4_H
-#define KJS_UNICODE_QT4_H
+#ifndef WTF_UNICODE_QT4_H
+#define WTF_UNICODE_QT4_H
#include <QChar>
#include <QString>
@@ -170,7 +171,7 @@ enum CharCategory {
Symbol_Math = U_MASK(QChar::Symbol_Math),
Symbol_Currency = U_MASK(QChar::Symbol_Currency),
Symbol_Modifier = U_MASK(QChar::Symbol_Modifier),
- Symbol_Other = U_MASK(QChar::Symbol_Other),
+ Symbol_Other = U_MASK(QChar::Symbol_Other)
};
@@ -522,4 +523,4 @@ inline CharCategory category(UChar32 c)
} }
-#endif
+#endif // WTF_UNICODE_QT4_H
diff --git a/JavaScriptCore/wtf/win/MainThreadWin.cpp b/JavaScriptCore/wtf/win/MainThreadWin.cpp
index 9f05d22..5f0163c 100644
--- a/JavaScriptCore/wtf/win/MainThreadWin.cpp
+++ b/JavaScriptCore/wtf/win/MainThreadWin.cpp
@@ -31,7 +31,9 @@
#include "Assertions.h"
#include "Threading.h"
+#if !PLATFORM(WIN_CE)
#include <windows.h>
+#endif
namespace WTF {