summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-03-16 17:30:24 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-03-16 17:30:24 (GMT)
commit1a8eaa2087fde99366da6faa11ef8c14711a75ff (patch)
tree8c35e8e93d8b43f8ed4041f3fae7b9ec39aae4d0 /src
parentb83172f8cfb4439f17c96886f0c6046a885370f6 (diff)
parentbcc8ecc91c9884d14dd4eda5fc1a4ab4ba7aab62 (diff)
downloadQt-1a8eaa2087fde99366da6faa11ef8c14711a75ff.zip
Qt-1a8eaa2087fde99366da6faa11ef8c14711a75ff.tar.gz
Qt-1a8eaa2087fde99366da6faa11ef8c14711a75ff.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1: (81 commits) Define JS_NO_EXPORT to avoid JSC C API functions being exported Don't use QScriptValueIterator to iterate over an array QtScript: Fix regression when calling newQObject() from native constructor Added note to OS X installation instructions. Keypress events ignored in listview on Cocoa (64 Bit) with Japanese IME Update only appropriate rectangles during update_sys(). Marked QTDS obsolete from Qt 4.7. QNetworkReply: Fix canReadLine() Abort waiting replies on session error. different approach to fixing "the other" aliasing issue fix aliasing issue in node_construct() detach in fewer cases, remove redundant calculation SSL: Fix memleak related to local certificate Improve keyboard layout detection on X11 Compile on ARM with -Werror -Wold-style-cast Use the vista-style native dialog for QFileDialog::getExistingDirectory Apply the stdset attribute for resource properties doc: Completed sentence about HideNameFilterDetails Doc fix in QLocale Doc for for QGestureRecognizer::create. ...
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/APICast.h22
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/APIShims.h99
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.cpp18
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.h23
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.cpp5
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.h7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.cpp3
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObject.h14
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObjectFunctions.h116
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.cpp65
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.h3
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSContextRef.cpp34
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSContextRefPrivate.h53
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.cpp64
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSStringRef.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/JSValueRef.cpp83
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/API/OpaqueJSString.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog8082
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/Info.plist4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.gypi20
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.order2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri217
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.cpp92
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.h91
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMv7Assembler.h177
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/AbstractMacroAssembler.h8
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssembler.h23
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp11
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h148
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h57
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerCodeRef.h12
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h89
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86_64.h29
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h64
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp333
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h13
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h13
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp150
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h38
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/Label.h14
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/NodesCodegen.cpp2012
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/config.h25
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp11
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.h9
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.cpp12
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.h11
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp10
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/ArrayPrototype.lut.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/DatePrototype.lut.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h1199
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.cpp542
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.h4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/JSONObject.lut.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/Lexer.lut.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/MathObject.lut.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/NumberConstructor.lut.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/RegExpConstructor.lut.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/RegExpObject.lut.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/generated/StringPrototype.lut.h9
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CachedCall.h11
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrame.h27
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp1007
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.h13
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Register.h65
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h8
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocator.h45
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp75
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorWin.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp19
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h143
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp383
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp18
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h37
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp674
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp240
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubCall.h37
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp457
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h28
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp91
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/os-win32/WinMain.cpp81
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/parser/Grammar.y6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.cpp11
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.h6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/parser/NodeConstructors.h1
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp1877
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.h16
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.h3
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/parser/SourceCode.h3
-rwxr-xr-xsrc/3rdparty/javascriptcore/JavaScriptCore/pcre/dftables1
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/pcre/pcre.pri23
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/pcre/pcre_exec.cpp4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/profiler/HeavyProfile.cpp0
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/profiler/HeavyProfile.h0
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileNode.cpp8
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.cpp22
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/profiler/TreeProfile.cpp0
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/profiler/TreeProfile.h0
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h10
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp31
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h11
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp17
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp808
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h153
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/CollectorHeapIterator.h126
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h1
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp17
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.cpp7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp28
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.cpp59
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.h19
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.cpp91
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.h42
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstanceCache.h94
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp379
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h8
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.cpp24
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp74
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h1
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp12
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h24
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp26
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp8
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.cpp72
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h66
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.cpp20
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h14
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h11
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp74
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h23
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp18
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h13
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp29
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h67
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp25
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h24
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp82
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h56
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp32
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h78
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp46
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h20
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp19
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp95
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h44
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp54
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h94
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h5
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp191
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h377
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h12
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h52
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp20
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h11
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSZombie.cpp48
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSZombie.h78
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp24
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.h4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackNone.cpp49
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackPosix.cpp28
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackSymbian.cpp48
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackWin.cpp6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp25
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.cpp4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h16
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.cpp54
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp31
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.cpp19
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h260
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.cpp8
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.cpp7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.h36
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Protect.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.cpp1
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp52
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h54
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h12
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h9
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp22
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h17
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp22
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringBuilder.h81
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.cpp14
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp18
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h13
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp171
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp220
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h49
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp17
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.h7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp8
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp1012
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h598
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.cpp82
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.h313
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakGCMap.h122
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakGCPtr.h128
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakRandom.h86
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wrec/WREC.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.cpp6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.h4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wscript4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/AlwaysInline.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.cpp10
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h112
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/CrossThreadRefCounted.h14
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.cpp12
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.h23
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp362
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.h65
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp142
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h21
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/GOwnPtr.cpp65
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/GOwnPtr.h98
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashCountedSet.h10
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashFunctions.h3
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashMap.h66
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashSet.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashTable.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListHashSet.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListRefPtr.h3
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.cpp24
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.h4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/MathExtras.h20
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/MessageQueue.h103
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/PassRefPtr.h94
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h899
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/PtrAndFlags.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.cpp10
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumberSeed.h10
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtr.h72
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/StdLibExtras.h14
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.cpp62
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.h19
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringHashFunctions.h157
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h14
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.cpp6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp97
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h77
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadSpecific.h46
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.cpp9
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h31
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingNone.cpp6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp51
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingWin.cpp14
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.cpp16
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h36
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/VMTags.h6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/Vector.h40
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/VectorTraits.h2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/android/AndroidThreading.h39
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/android/MainThreadAndroid.cpp42
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/dtoa.cpp103
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/dtoa.h12
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/qt/ThreadingQt.cpp30
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/UTF8.cpp1
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/Unicode.h4
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp1
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp6
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h5
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h136
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp1
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/wince/FastMallocWince.h1
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/wtf/wince/MemoryManager.cpp8
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexCompiler.cpp2
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.cpp8
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp31
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.h13
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexPattern.h2
-rw-r--r--src/3rdparty/javascriptcore/VERSION4
-rw-r--r--src/3rdparty/javascriptcore/WebKit.pri100
-rw-r--r--src/corelib/arch/qatomic_arm.h4
-rw-r--r--src/corelib/codecs/qtextcodec.cpp30
-rw-r--r--src/corelib/io/qfileinfo.cpp51
-rw-r--r--src/corelib/io/qfileinfo_p.h7
-rw-r--r--src/corelib/io/qfsfileengine.cpp4
-rw-r--r--src/corelib/io/qfsfileengine_p.h4
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp68
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp66
-rw-r--r--src/corelib/tools/qbytedata_p.h7
-rw-r--r--src/corelib/tools/qlist.h64
-rw-r--r--src/corelib/tools/qlocale.cpp2
-rw-r--r--src/corelib/tools/qstring.cpp100
-rw-r--r--src/corelib/tools/qstring.h6
-rw-r--r--src/declarative/qml/qdeclarativeextensionplugin.cpp3
-rw-r--r--src/declarative/qml/qdeclarativesqldatabase.cpp12
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp4
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp7
-rw-r--r--src/gui/dialogs/qfiledialog.cpp3
-rw-r--r--src/gui/dialogs/qfiledialog_win.cpp62
-rw-r--r--src/gui/dialogs/qfileinfogatherer.cpp31
-rw-r--r--src/gui/dialogs/qfileinfogatherer_p.h8
-rw-r--r--src/gui/kernel/qapplication_mac.mm9
-rw-r--r--src/gui/kernel/qapplication_x11.cpp63
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm13
-rw-r--r--src/gui/kernel/qgesturerecognizer.cpp2
-rw-r--r--src/gui/kernel/qkeymapper_mac.cpp54
-rw-r--r--src/gui/kernel/qkeymapper_p.h2
-rw-r--r--src/gui/kernel/qkeymapper_x11.cpp34
-rw-r--r--src/gui/kernel/qkeysequence.cpp1
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm4
-rw-r--r--src/gui/kernel/qt_x11_p.h6
-rw-r--r--src/gui/kernel/qwidget_mac.mm29
-rw-r--r--src/gui/painting/qdrawhelper.cpp8
-rw-r--r--src/gui/text/qtextcontrol.cpp11
-rw-r--r--src/gui/text/qtextcontrol_p.h3
-rw-r--r--src/gui/text/qzip.cpp44
-rw-r--r--src/gui/text/qzipreader_p.h5
-rw-r--r--src/gui/text/qzipwriter_p.h2
-rw-r--r--src/gui/widgets/qabstractslider.cpp8
-rw-r--r--src/gui/widgets/qlinecontrol.cpp14
-rw-r--r--src/gui/widgets/qlinecontrol_p.h2
-rw-r--r--src/imports/qimportbase.pri2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp28
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h4
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp23
-rw-r--r--src/network/access/qnetworkreplyimpl_p.h5
-rw-r--r--src/network/bearer/qbearerengine_p.h4
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp169
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.cpp218
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.h7
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp60
-rw-r--r--src/network/bearer/qnetworkconfiguration_p.h22
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp15
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h1
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp6
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h2
-rw-r--r--src/plugins/bearer/bearer.pro2
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.h13
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.mm401
-rw-r--r--src/plugins/bearer/generic/qgenericengine.cpp20
-rw-r--r--src/plugins/bearer/generic/qgenericengine.h2
-rw-r--r--src/plugins/bearer/icd/qicdengine.cpp25
-rw-r--r--src/plugins/bearer/icd/qicdengine.h2
-rw-r--r--src/plugins/bearer/icd/qnetworksession_impl.cpp221
-rw-r--r--src/plugins/bearer/nativewifi/qnativewifiengine.cpp23
-rw-r--r--src/plugins/bearer/nativewifi/qnativewifiengine.h2
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp60
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerengine.h2
-rw-r--r--src/plugins/bearer/nla/qnlaengine.cpp14
-rw-r--r--src/plugins/bearer/nla/qnlaengine.h2
-rw-r--r--src/plugins/bearer/symbian/qnetworksession_impl.cpp198
-rw-r--r--src/plugins/bearer/symbian/symbianengine.cpp56
-rw-r--r--src/plugins/bearer/symbian/symbianengine.h2
-rw-r--r--src/script/api/qscriptcontextinfo.cpp2
-rw-r--r--src/script/api/qscriptengine.cpp50
-rw-r--r--src/script/api/qscriptengine_p.h25
-rw-r--r--src/script/api/qscriptengineagent.cpp10
-rw-r--r--src/script/api/qscriptengineagent_p.h7
-rw-r--r--src/script/api/qscriptvalue.cpp14
-rw-r--r--src/script/api/qscriptvalue_p.h15
-rw-r--r--src/script/api/qscriptvalueiterator.cpp56
-rw-r--r--src/script/bridge/qscriptactivationobject.cpp18
-rw-r--r--src/script/bridge/qscriptactivationobject_p.h6
-rw-r--r--src/script/bridge/qscriptclassobject.cpp82
-rw-r--r--src/script/bridge/qscriptclassobject_p.h11
-rw-r--r--src/script/bridge/qscriptdeclarativeclass.cpp10
-rw-r--r--src/script/bridge/qscriptdeclarativeclass_p.h3
-rw-r--r--src/script/bridge/qscriptdeclarativeobject.cpp38
-rw-r--r--src/script/bridge/qscriptdeclarativeobject_p.h8
-rw-r--r--src/script/bridge/qscriptglobalobject.cpp38
-rw-r--r--src/script/bridge/qscriptglobalobject_p.h25
-rw-r--r--src/script/bridge/qscriptobject.cpp38
-rw-r--r--src/script/bridge/qscriptobject_p.h18
-rw-r--r--src/script/bridge/qscriptqobject.cpp179
-rw-r--r--src/script/bridge/qscriptqobject_p.h22
-rw-r--r--src/script/bridge/qscriptvariant.cpp7
-rw-r--r--src/script/script.pro7
433 files changed, 23875 insertions, 10296 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/APICast.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/APICast.h
index b6d1532..4284c44 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/APICast.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/APICast.h
@@ -27,6 +27,7 @@
#define APICast_h
#include "JSAPIValueWrapper.h"
+#include "JSGlobalObject.h"
#include "JSValue.h"
#include <wtf/Platform.h>
#include <wtf/UnusedParam.h>
@@ -50,16 +51,20 @@ typedef struct OpaqueJSValue* JSObjectRef;
inline JSC::ExecState* toJS(JSContextRef c)
{
+ ASSERT(c);
return reinterpret_cast<JSC::ExecState*>(const_cast<OpaqueJSContext*>(c));
}
inline JSC::ExecState* toJS(JSGlobalContextRef c)
{
+ ASSERT(c);
return reinterpret_cast<JSC::ExecState*>(c);
}
-inline JSC::JSValue toJS(JSC::ExecState*, JSValueRef v)
+inline JSC::JSValue toJS(JSC::ExecState* exec, JSValueRef v)
{
+ ASSERT_UNUSED(exec, exec);
+ ASSERT(v);
#if USE(JSVALUE32_64)
JSC::JSCell* jsCell = reinterpret_cast<JSC::JSCell*>(const_cast<OpaqueJSValue*>(v));
if (!jsCell)
@@ -72,6 +77,20 @@ inline JSC::JSValue toJS(JSC::ExecState*, JSValueRef v)
#endif
}
+inline JSC::JSValue toJSForGC(JSC::ExecState* exec, JSValueRef v)
+{
+ ASSERT_UNUSED(exec, exec);
+ ASSERT(v);
+#if USE(JSVALUE32_64)
+ JSC::JSCell* jsCell = reinterpret_cast<JSC::JSCell*>(const_cast<OpaqueJSValue*>(v));
+ if (!jsCell)
+ return JSC::JSValue();
+ return jsCell;
+#else
+ return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
+#endif
+}
+
inline JSC::JSObject* toJS(JSObjectRef o)
{
return reinterpret_cast<JSC::JSObject*>(o);
@@ -118,6 +137,7 @@ inline JSContextRef toRef(JSC::ExecState* e)
inline JSGlobalContextRef toGlobalRef(JSC::ExecState* e)
{
+ ASSERT(e == e->lexicalGlobalObject()->globalExec());
return reinterpret_cast<JSGlobalContextRef>(e);
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/APIShims.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/APIShims.h
new file mode 100644
index 0000000..f809d5d
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/APIShims.h
@@ -0,0 +1,99 @@
+/*
+ * 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 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 APIShims_h
+#define APIShims_h
+
+#include "CallFrame.h"
+#include "JSLock.h"
+
+namespace JSC {
+
+class APIEntryShimWithoutLock {
+protected:
+ APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread)
+ : m_globalData(globalData)
+ , m_entryIdentifierTable(setCurrentIdentifierTable(globalData->identifierTable))
+ {
+ if (registerThread)
+ globalData->heap.registerThread();
+ m_globalData->timeoutChecker->start();
+ }
+
+ ~APIEntryShimWithoutLock()
+ {
+ m_globalData->timeoutChecker->stop();
+ setCurrentIdentifierTable(m_entryIdentifierTable);
+ }
+
+private:
+ JSGlobalData* m_globalData;
+ IdentifierTable* m_entryIdentifierTable;
+};
+
+class APIEntryShim : public APIEntryShimWithoutLock {
+public:
+ // Normal API entry
+ APIEntryShim(ExecState* exec, bool registerThread = true)
+ : APIEntryShimWithoutLock(&exec->globalData(), registerThread)
+ , m_lock(exec)
+ {
+ }
+
+ // JSPropertyNameAccumulator only has a globalData.
+ APIEntryShim(JSGlobalData* globalData, bool registerThread = true)
+ : APIEntryShimWithoutLock(globalData, registerThread)
+ , m_lock(globalData->isSharedInstance ? LockForReal : SilenceAssertionsOnly)
+ {
+ }
+
+private:
+ JSLock m_lock;
+};
+
+class APICallbackShim {
+public:
+ APICallbackShim(ExecState* exec)
+ : m_dropAllLocks(exec)
+ , m_globalData(&exec->globalData())
+ {
+ resetCurrentIdentifierTable();
+ m_globalData->timeoutChecker->start();
+ }
+
+ ~APICallbackShim()
+ {
+ m_globalData->timeoutChecker->stop();
+ setCurrentIdentifierTable(m_globalData->identifierTable);
+ }
+
+private:
+ JSLock::DropAllLocks m_dropAllLocks;
+ JSGlobalData* m_globalData;
+};
+
+}
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.cpp
index 4a32d35..ebfeafa 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.cpp
@@ -28,6 +28,7 @@
#include "JSBasePrivate.h"
#include "APICast.h"
+#include "APIShims.h"
#include "Completion.h"
#include "OpaqueJSString.h"
#include "SourceCode.h"
@@ -43,8 +44,7 @@ using namespace JSC;
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsThisObject = toJS(thisObject);
@@ -69,8 +69,7 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), startingLineNumber);
Completion completion = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source);
@@ -94,12 +93,11 @@ void JSGarbageCollect(JSContextRef ctx)
return;
ExecState* exec = toJS(ctx);
- JSGlobalData& globalData = exec->globalData();
-
- JSLock lock(globalData.isSharedInstance ? LockForReal : SilenceAssertionsOnly);
+ APIEntryShim entryShim(exec, false);
+ JSGlobalData& globalData = exec->globalData();
if (!globalData.heap.isBusy())
- globalData.heap.collect();
+ globalData.heap.collectAllGarbage();
// FIXME: Perhaps we should trigger a second mark and sweep
// once the garbage collector is done if this is called when
@@ -109,8 +107,6 @@ void JSGarbageCollect(JSContextRef ctx)
void JSReportExtraMemoryCost(JSContextRef ctx, size_t size)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
-
+ APIEntryShim entryShim(exec);
exec->globalData().heap.reportExtraMemoryCost(size);
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.h
index 0a0dcda..2e16720 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSBase.h
@@ -64,33 +64,20 @@ typedef struct OpaqueJSValue* JSObjectRef;
/* JavaScript symbol exports */
-#if !defined(JS_EXPORT)
-#if defined(BUILDING_WX__)
+#undef JS_EXPORT
+#if defined(JS_NO_EXPORT)
#define JS_EXPORT
#elif defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC__)
#define JS_EXPORT __attribute__((visibility("default")))
-#elif defined(_WIN32_WCE)
- #if defined(JS_BUILDING_JS)
- #define JS_EXPORT __declspec(dllexport)
- #elif defined(JS_IMPORT_JS)
- #define JS_EXPORT __declspec(dllimport)
- #else
- #define JS_EXPORT
- #endif
-#elif defined(WIN32) || defined(_WIN32)
- /*
- * TODO: Export symbols with JS_EXPORT when using MSVC.
- * See http://bugs.webkit.org/show_bug.cgi?id=16227
- */
+#elif defined(WIN32) || defined(_WIN32) || defined(_WIN32_WCE)
#if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
- #define JS_EXPORT __declspec(dllexport)
+ #define JS_EXPORT __declspec(dllexport)
#else
- #define JS_EXPORT __declspec(dllimport)
+ #define JS_EXPORT __declspec(dllimport)
#endif
#else
#define JS_EXPORT
#endif
-#endif
#ifdef __cplusplus
extern "C" {
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.cpp
index 64c83cb..9c5f6d7 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "JSCallbackConstructor.h"
+#include "APIShims.h"
#include "APICast.h"
#include <runtime/JSGlobalObject.h>
#include <runtime/JSLock.h>
@@ -36,7 +37,7 @@ namespace JSC {
const ClassInfo JSCallbackConstructor::info = { "CallbackConstructor", 0, 0, 0 };
-JSCallbackConstructor::JSCallbackConstructor(PassRefPtr<Structure> structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback)
+JSCallbackConstructor::JSCallbackConstructor(NonNullPassRefPtr<Structure> structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback)
: JSObject(structure)
, m_class(jsClass)
, m_callback(callback)
@@ -66,7 +67,7 @@ static JSObject* constructJSCallback(ExecState* exec, JSObject* constructor, con
JSValueRef exception = 0;
JSObjectRef result;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
}
if (exception)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.h
index 0497aa2..c4bd7ad 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackConstructor.h
@@ -33,7 +33,7 @@ namespace JSC {
class JSCallbackConstructor : public JSObject {
public:
- JSCallbackConstructor(PassRefPtr<Structure>, JSClassRef, JSObjectCallAsConstructorCallback);
+ JSCallbackConstructor(NonNullPassRefPtr<Structure>, JSClassRef, JSObjectCallAsConstructorCallback);
virtual ~JSCallbackConstructor();
JSClassRef classRef() const { return m_class; }
JSObjectCallAsConstructorCallback callback() const { return m_callback; }
@@ -41,9 +41,12 @@ public:
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames));
+ return Structure::create(proto, TypeInfo(ObjectType, StructureFlags));
}
+protected:
+ static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
+
private:
virtual ConstructType getConstructData(ConstructData&);
virtual const ClassInfo* classInfo() const { return &info; }
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.cpp
index b7dd768..0e434d9 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.cpp
@@ -27,6 +27,7 @@
#include <wtf/Platform.h>
#include "JSCallbackFunction.h"
+#include "APIShims.h"
#include "APICast.h"
#include "CodeBlock.h"
#include "JSFunction.h"
@@ -61,7 +62,7 @@ JSValue JSCallbackFunction::call(ExecState* exec, JSObject* functionObject, JSVa
JSValueRef exception = 0;
JSValueRef result;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
result = static_cast<JSCallbackFunction*>(functionObject)->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
}
if (exception)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.h
index 3a17fa2..0cf25c4 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackFunction.h
@@ -41,7 +41,7 @@ public:
// refactor the code so this override isn't necessary
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
+ return Structure::create(proto, TypeInfo(ObjectType, StructureFlags));
}
private:
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObject.h
index e767cb5..2e25991 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObject.h
@@ -36,7 +36,7 @@ namespace JSC {
template <class Base>
class JSCallbackObject : public Base {
public:
- JSCallbackObject(ExecState*, PassRefPtr<Structure>, JSClassRef, void* data);
+ JSCallbackObject(ExecState*, NonNullPassRefPtr<Structure>, JSClassRef, void* data);
JSCallbackObject(JSClassRef);
virtual ~JSCallbackObject();
@@ -50,23 +50,27 @@ public:
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | OverridesHasInstance));
+ return Structure::create(proto, TypeInfo(ObjectType, StructureFlags));
}
+protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | Base::StructureFlags;
+
private:
virtual UString className() const;
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&);
+ virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
- virtual bool deleteProperty(ExecState*, const Identifier&, bool checkDontDelete = true);
- virtual bool deleteProperty(ExecState*, unsigned, bool checkDontDelete = true);
+ virtual bool deleteProperty(ExecState*, const Identifier&);
+ virtual bool deleteProperty(ExecState*, unsigned);
virtual bool hasInstance(ExecState* exec, JSValue value, JSValue proto);
- virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false);
+ virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObjectFunctions.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObjectFunctions.h
index c84c191..4b28a99 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "APIShims.h"
#include "APICast.h"
#include "Error.h"
#include "JSCallbackFunction.h"
@@ -47,7 +48,7 @@ inline JSCallbackObject<Base>* JSCallbackObject<Base>::asCallbackObject(JSValue
}
template <class Base>
-JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, PassRefPtr<Structure> structure, JSClassRef jsClass, void* data)
+JSCallbackObject<Base>::JSCallbackObject(ExecState* exec, NonNullPassRefPtr<Structure> structure, JSClassRef jsClass, void* data)
: Base(structure)
, m_callbackObjectData(new JSCallbackObjectData(data, jsClass))
{
@@ -79,7 +80,7 @@ void JSCallbackObject<Base>::init(ExecState* exec)
// initialize from base to derived
for (int i = static_cast<int>(initRoutines.size()) - 1; i >= 0; i--) {
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
JSObjectInitializeCallback initialize = initRoutines[i];
initialize(toRef(exec), toRef(this));
}
@@ -117,7 +118,7 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie
if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
if (!propertyNameRef)
propertyNameRef = OpaqueJSString::create(propertyName.ustring());
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
if (hasProperty(ctx, thisRef, propertyNameRef.get())) {
slot.setCustom(this, callbackGetter);
return true;
@@ -128,18 +129,18 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie
JSValueRef exception = 0;
JSValueRef value;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
}
- exec->setException(toJS(exec, exception));
- if (value) {
- slot.setValue(toJS(exec, value));
- return true;
- }
if (exception) {
+ exec->setException(toJS(exec, exception));
slot.setValue(jsUndefined());
return true;
}
+ if (value) {
+ slot.setValue(toJS(exec, value));
+ return true;
+ }
}
if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
@@ -167,6 +168,25 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, unsigned proper
}
template <class Base>
+bool JSCallbackObject<Base>::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
+{
+ PropertySlot slot;
+ if (getOwnPropertySlot(exec, propertyName, slot)) {
+ // Ideally we should return an access descriptor, but returning a value descriptor is better than nothing.
+ JSValue value = slot.getValue(exec, propertyName);
+ if (!exec->hadException())
+ descriptor.setValue(value);
+ // We don't know whether the property is configurable, but assume it is.
+ descriptor.setConfigurable(true);
+ // We don't know whether the property is enumerable (we could call getOwnPropertyNames() to find out), but assume it isn't.
+ descriptor.setEnumerable(false);
+ return true;
+ }
+
+ return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+}
+
+template <class Base>
void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
JSContextRef ctx = toRef(exec);
@@ -181,10 +201,11 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
JSValueRef exception = 0;
bool result;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
}
- exec->setException(toJS(exec, exception));
+ if (exception)
+ exec->setException(toJS(exec, exception));
if (result || exception)
return;
}
@@ -199,10 +220,11 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
JSValueRef exception = 0;
bool result;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
}
- exec->setException(toJS(exec, exception));
+ if (exception)
+ exec->setException(toJS(exec, exception));
if (result || exception)
return;
} else
@@ -224,7 +246,7 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
}
template <class Base>
-bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
JSContextRef ctx = toRef(exec);
JSObjectRef thisRef = toRef(this);
@@ -237,10 +259,11 @@ bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& p
JSValueRef exception = 0;
bool result;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
}
- exec->setException(toJS(exec, exception));
+ if (exception)
+ exec->setException(toJS(exec, exception));
if (result || exception)
return true;
}
@@ -262,13 +285,13 @@ bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& p
}
}
- return Base::deleteProperty(exec, propertyName, checkDontDelete);
+ return Base::deleteProperty(exec, propertyName);
}
template <class Base>
-bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, unsigned propertyName, bool checkDontDelete)
+bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, unsigned propertyName)
{
- return deleteProperty(exec, Identifier::from(exec, propertyName), checkDontDelete);
+ return deleteProperty(exec, Identifier::from(exec, propertyName));
}
template <class Base>
@@ -298,10 +321,11 @@ JSObject* JSCallbackObject<Base>::construct(ExecState* exec, JSObject* construct
JSValueRef exception = 0;
JSObject* result;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
}
- exec->setException(toJS(exec, exception));
+ if (exception)
+ exec->setException(toJS(exec, exception));
return result;
}
}
@@ -322,10 +346,11 @@ bool JSCallbackObject<Base>::hasInstance(ExecState* exec, JSValue value, JSValue
JSValueRef exception = 0;
bool result;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
result = hasInstance(execRef, thisRef, valueRef, &exception);
}
- exec->setException(toJS(exec, exception));
+ if (exception)
+ exec->setException(toJS(exec, exception));
return result;
}
}
@@ -360,10 +385,11 @@ JSValue JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject,
JSValueRef exception = 0;
JSValue result;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
result = toJS(exec, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
}
- exec->setException(toJS(exec, exception));
+ if (exception)
+ exec->setException(toJS(exec, exception));
return result;
}
}
@@ -373,14 +399,14 @@ JSValue JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject,
}
template <class Base>
-void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable)
+void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
JSContextRef execRef = toRef(exec);
JSObjectRef thisRef = toRef(this);
for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) {
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
getPropertyNames(execRef, thisRef, toRef(&propertyNames));
}
@@ -390,7 +416,7 @@ void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameAr
for (iterator it = staticValues->begin(); it != end; ++it) {
UString::Rep* name = it->first.get();
StaticValueEntry* entry = it->second;
- if (entry->getProperty && !(entry->attributes & kJSPropertyAttributeDontEnum))
+ if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)))
propertyNames.add(Identifier(exec, name));
}
}
@@ -401,13 +427,13 @@ void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameAr
for (iterator it = staticFunctions->begin(); it != end; ++it) {
UString::Rep* name = it->first.get();
StaticFunctionEntry* entry = it->second;
- if (!(entry->attributes & kJSPropertyAttributeDontEnum))
+ if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))
propertyNames.add(Identifier(exec, name));
}
}
}
- Base::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
+ Base::getOwnPropertyNames(exec, propertyNames, mode);
}
template <class Base>
@@ -426,7 +452,7 @@ double JSCallbackObject<Base>::toNumber(ExecState* exec) const
JSValueRef exception = 0;
JSValueRef value;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
value = convertToType(ctx, thisRef, kJSTypeNumber, &exception);
}
if (exception) {
@@ -435,7 +461,8 @@ double JSCallbackObject<Base>::toNumber(ExecState* exec) const
}
double dValue;
- return toJS(exec, value).getNumber(dValue) ? dValue : NaN;
+ if (value)
+ return toJS(exec, value).getNumber(dValue) ? dValue : NaN;
}
return Base::toNumber(exec);
@@ -452,14 +479,15 @@ UString JSCallbackObject<Base>::toString(ExecState* exec) const
JSValueRef exception = 0;
JSValueRef value;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
value = convertToType(ctx, thisRef, kJSTypeString, &exception);
}
if (exception) {
exec->setException(toJS(exec, exception));
return "";
}
- return toJS(exec, value).getString();
+ if (value)
+ return toJS(exec, value).getString(exec);
}
return Base::toString(exec);
@@ -504,16 +532,17 @@ JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identif
JSValueRef exception = 0;
JSValueRef value;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
}
- exec->setException(toJS(exec, exception));
+ if (exception) {
+ exec->setException(toJS(exec, exception));
+ return jsUndefined();
+ }
if (value)
return toJS(exec, value);
- if (exception)
- return jsUndefined();
}
-
+
return throwError(exec, ReferenceError, "Static value property defined with NULL getProperty callback.");
}
@@ -557,14 +586,15 @@ JSValue JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifier
JSValueRef exception = 0;
JSValueRef value;
{
- JSLock::DropAllLocks dropAllLocks(exec);
+ APICallbackShim callbackShim(exec);
value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
}
- exec->setException(toJS(exec, exception));
+ if (exception) {
+ exec->setException(toJS(exec, exception));
+ return jsUndefined();
+ }
if (value)
return toJS(exec, value);
- if (exception)
- return jsUndefined();
}
return throwError(exec, ReferenceError, "hasProperty callback returned true for a property that doesn't exist.");
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.cpp
index afde7ce..c6685bf 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.cpp
@@ -34,6 +34,7 @@
#include <runtime/ObjectPrototype.h>
#include <runtime/Identifier.h>
+using namespace std;
using namespace JSC;
const JSClassDefinition kJSClassDefinitionEmpty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -52,7 +53,7 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
, callAsConstructor(definition->callAsConstructor)
, hasInstance(definition->hasInstance)
, convertToType(definition->convertToType)
- , m_className(UString::Rep::createFromUTF8(definition->className))
+ , m_className(UString::createFromUTF8(definition->className).rep()->ref())
, m_staticValues(0)
, m_staticFunctions(0)
{
@@ -61,8 +62,9 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
if (const JSStaticValue* staticValue = definition->staticValues) {
m_staticValues = new OpaqueJSClassStaticValuesTable();
while (staticValue->name) {
- m_staticValues->add(UString::Rep::createFromUTF8(staticValue->name),
- new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes));
+ // Use a local variable here to sidestep an RVCT compiler bug.
+ StaticValueEntry* entry = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes);
+ m_staticValues->add(UString::createFromUTF8(staticValue->name).rep()->ref(), entry);
++staticValue;
}
}
@@ -70,8 +72,9 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
if (const JSStaticFunction* staticFunction = definition->staticFunctions) {
m_staticFunctions = new OpaqueJSClassStaticFunctionsTable();
while (staticFunction->name) {
- m_staticFunctions->add(UString::Rep::createFromUTF8(staticFunction->name),
- new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes));
+ // Use a local variable here to sidestep an RVCT compiler bug.
+ StaticFunctionEntry* entry = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes);
+ m_staticFunctions->add(UString::createFromUTF8(staticFunction->name).rep()->ref(), entry);
++staticFunction;
}
}
@@ -82,12 +85,12 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
OpaqueJSClass::~OpaqueJSClass()
{
- ASSERT(!m_className.rep()->identifierTable());
+ ASSERT(!m_className.rep()->isIdentifier());
if (m_staticValues) {
OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end();
for (OpaqueJSClassStaticValuesTable::const_iterator it = m_staticValues->begin(); it != end; ++it) {
- ASSERT(!it->first->identifierTable());
+ ASSERT(!it->first->isIdentifier());
delete it->second;
}
delete m_staticValues;
@@ -96,7 +99,7 @@ OpaqueJSClass::~OpaqueJSClass()
if (m_staticFunctions) {
OpaqueJSClassStaticFunctionsTable::const_iterator end = m_staticFunctions->end();
for (OpaqueJSClassStaticFunctionsTable::const_iterator it = m_staticFunctions->begin(); it != end; ++it) {
- ASSERT(!it->first->identifierTable());
+ ASSERT(!it->first->isIdentifier());
delete it->second;
}
delete m_staticFunctions;
@@ -118,39 +121,32 @@ static void clearReferenceToPrototype(JSObjectRef prototype)
jsClassData->cachedPrototype = 0;
}
-PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* definition)
+PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientDefinition)
{
- if (const JSStaticFunction* staticFunctions = definition->staticFunctions) {
- // copy functions into a prototype class
- JSClassDefinition protoDefinition = kJSClassDefinitionEmpty;
- protoDefinition.staticFunctions = staticFunctions;
- protoDefinition.finalize = clearReferenceToPrototype;
-
- // We are supposed to use JSClassRetain/Release but since we know that we currently have
- // the only reference to this class object we cheat and use a RefPtr instead.
- RefPtr<OpaqueJSClass> protoClass = adoptRef(new OpaqueJSClass(&protoDefinition, 0));
-
- // remove functions from the original class
- JSClassDefinition objectDefinition = *definition;
- objectDefinition.staticFunctions = 0;
-
- return adoptRef(new OpaqueJSClass(&objectDefinition, protoClass.get()));
- }
+ JSClassDefinition definition = *clientDefinition; // Avoid modifying client copy.
- return adoptRef(new OpaqueJSClass(definition, 0));
+ JSClassDefinition protoDefinition = kJSClassDefinitionEmpty;
+ protoDefinition.finalize = clearReferenceToPrototype;
+ swap(definition.staticFunctions, protoDefinition.staticFunctions); // Move static functions to the prototype.
+
+ // We are supposed to use JSClassRetain/Release but since we know that we currently have
+ // the only reference to this class object we cheat and use a RefPtr instead.
+ RefPtr<OpaqueJSClass> protoClass = adoptRef(new OpaqueJSClass(&protoDefinition, 0));
+ return adoptRef(new OpaqueJSClass(&definition, protoClass.get()));
}
OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass)
: m_class(jsClass)
- , cachedPrototype(0)
{
if (jsClass->m_staticValues) {
staticValues = new OpaqueJSClassStaticValuesTable;
OpaqueJSClassStaticValuesTable::const_iterator end = jsClass->m_staticValues->end();
for (OpaqueJSClassStaticValuesTable::const_iterator it = jsClass->m_staticValues->begin(); it != end; ++it) {
- ASSERT(!it->first->identifierTable());
- staticValues->add(UString::Rep::createCopying(it->first->data(), it->first->size()),
- new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes));
+ ASSERT(!it->first->isIdentifier());
+ // Use a local variable here to sidestep an RVCT compiler bug.
+ StaticValueEntry* entry = new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes);
+ staticValues->add(UString::Rep::create(it->first->data(), it->first->size()), entry);
+
}
} else
@@ -161,9 +157,10 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass)
staticFunctions = new OpaqueJSClassStaticFunctionsTable;
OpaqueJSClassStaticFunctionsTable::const_iterator end = jsClass->m_staticFunctions->end();
for (OpaqueJSClassStaticFunctionsTable::const_iterator it = jsClass->m_staticFunctions->begin(); it != end; ++it) {
- ASSERT(!it->first->identifierTable());
- staticFunctions->add(UString::Rep::createCopying(it->first->data(), it->first->size()),
- new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes));
+ ASSERT(!it->first->isIdentifier());
+ // Use a local variable here to sidestep an RVCT compiler bug.
+ StaticFunctionEntry* entry = new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes);
+ staticFunctions->add(UString::Rep::create(it->first->data(), it->first->size()), entry);
}
} else
@@ -240,5 +237,5 @@ JSObject* OpaqueJSClass::prototype(ExecState* exec)
jsClassData.cachedPrototype->setPrototype(prototype);
}
}
- return jsClassData.cachedPrototype;
+ return jsClassData.cachedPrototype.get();
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.h
index c4777dd..ae60aad 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSClassRef.h
@@ -31,6 +31,7 @@
#include <runtime/JSObject.h>
#include <runtime/Protect.h>
#include <runtime/UString.h>
+#include <runtime/WeakGCPtr.h>
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
@@ -76,7 +77,7 @@ struct OpaqueJSClassContextData : Noncopyable {
OpaqueJSClassStaticValuesTable* staticValues;
OpaqueJSClassStaticFunctionsTable* staticFunctions;
- JSC::JSObject* cachedPrototype;
+ JSC::WeakGCPtr<JSC::JSObject> cachedPrototype;
};
struct OpaqueJSClass : public ThreadSafeShared<OpaqueJSClass> {
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSContextRef.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSContextRef.cpp
index c358a84..6bdc3c8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSContextRef.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSContextRef.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "JSContextRef.h"
+#include "JSContextRefPrivate.h"
#include "APICast.h"
#include "InitializeThreading.h"
@@ -34,7 +35,7 @@
#include "JSObject.h"
#include <wtf/Platform.h>
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
#include <mach-o/dyld.h>
static const int32_t webkitFirstVersionWithConcurrentGlobalContexts = 0x2100500; // 528.5.0
@@ -45,7 +46,7 @@ using namespace JSC;
JSContextGroupRef JSContextGroupCreate()
{
initializeThreading();
- return toRef(JSGlobalData::create().releaseRef());
+ return toRef(JSGlobalData::createNonDefault().releaseRef());
}
JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
@@ -62,7 +63,7 @@ void JSContextGroupRelease(JSContextGroupRef group)
JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
{
initializeThreading();
-#if PLATFORM(DARWIN)
+#if OS(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)
@@ -73,7 +74,7 @@ JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
JSLock lock(LockForReal);
return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass);
}
-#endif // PLATFORM(DARWIN)
+#endif // OS(DARWIN)
return JSGlobalContextCreateInGroup(0, globalObjectClass);
}
@@ -83,8 +84,9 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
initializeThreading();
JSLock lock(LockForReal);
+ RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createNonDefault();
- RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::create();
+ APIEntryShim entryShim(globalData.get(), false);
#if ENABLE(JSC_MULTIPLE_THREADS)
globalData->makeUsableFromMultipleThreads();
@@ -107,12 +109,9 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
{
ExecState* exec = toJS(ctx);
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSGlobalData& globalData = exec->globalData();
-
- globalData.heap.registerThread();
-
gcProtect(exec->dynamicGlobalObject());
globalData.ref();
return ctx;
@@ -121,18 +120,16 @@ JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx)
void JSGlobalContextRelease(JSGlobalContextRef ctx)
{
ExecState* exec = toJS(ctx);
- JSLock lock(exec);
+ APIEntryShim entryShim(exec, false);
gcUnprotect(exec->dynamicGlobalObject());
JSGlobalData& globalData = exec->globalData();
if (globalData.refCount() == 2) { // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain().
// The last reference was released, this is our last chance to collect.
- ASSERT(!globalData.heap.protectedObjectCount());
- ASSERT(!globalData.heap.isBusy());
globalData.heap.destroy();
} else
- globalData.heap.collect();
+ globalData.heap.collectAllGarbage();
globalData.deref();
}
@@ -140,8 +137,7 @@ void JSGlobalContextRelease(JSGlobalContextRef ctx)
JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
// It is necessary to call toThisObject to get the wrapper object when used with WebCore.
return toRef(exec->lexicalGlobalObject()->toThisObject(exec));
@@ -152,3 +148,11 @@ JSContextGroupRef JSContextGetGroup(JSContextRef ctx)
ExecState* exec = toJS(ctx);
return toRef(&exec->globalData());
}
+
+JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx)
+{
+ ExecState* exec = toJS(ctx);
+ APIEntryShim entryShim(exec);
+
+ return toGlobalRef(exec->lexicalGlobalObject()->globalExec());
+}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSContextRefPrivate.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSContextRefPrivate.h
new file mode 100644
index 0000000..ff014ec
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSContextRefPrivate.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSContextRefPrivate_h
+#define JSContextRefPrivate_h
+
+#include <JavaScriptCore/JSObjectRef.h>
+#include <JavaScriptCore/JSValueRef.h>
+#include <JavaScriptCore/WebKitAvailability.h>
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+@function
+@abstract Gets the global context of a JavaScript execution context.
+@param ctx The JSContext whose global context you want to get.
+@result ctx's global context.
+*/
+JS_EXPORT JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JSContextRefPrivate_h */
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.cpp
index 06ef578..faaa4eb 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSObjectRef.cpp
@@ -76,8 +76,7 @@ void JSClassRelease(JSClassRef jsClass)
JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
if (!jsClass)
return toRef(new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure())); // slightly more efficient
@@ -92,8 +91,7 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous");
@@ -103,8 +101,7 @@ JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name,
JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsPrototype = jsClass ? jsClass->prototype(exec) : 0;
if (!jsPrototype)
@@ -118,8 +115,7 @@ JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObje
JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous");
@@ -141,8 +137,7 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* result;
if (argumentCount) {
@@ -167,8 +162,7 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; ++i)
@@ -188,8 +182,7 @@ JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSVal
JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; ++i)
@@ -209,8 +202,7 @@ JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSVa
JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; ++i)
@@ -230,8 +222,7 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV
JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
return toRef(exec, jsObject->prototype());
@@ -240,8 +231,7 @@ JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object)
void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
JSValue jsValue = toJS(exec, value);
@@ -252,8 +242,7 @@ void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
@@ -263,8 +252,7 @@ bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
@@ -280,8 +268,7 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
Identifier name(propertyName->identifier(&exec->globalData()));
@@ -304,8 +291,7 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
@@ -322,8 +308,7 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsi
void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
JSValue jsValue = toJS(exec, value);
@@ -339,8 +324,7 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
@@ -389,8 +373,7 @@ bool JSObjectIsFunction(JSContextRef, JSObjectRef object)
JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
JSObject* jsThisObject = toJS(thisObject);
@@ -427,8 +410,7 @@ bool JSObjectIsConstructor(JSContextRef, JSObjectRef object)
JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSObject* jsObject = toJS(object);
@@ -466,8 +448,7 @@ JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef o
{
JSObject* jsObject = toJS(object);
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSGlobalData* globalData = &exec->globalData();
@@ -492,7 +473,7 @@ JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array)
void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array)
{
if (--array->refCount == 0) {
- JSLock lock(array->globalData->isSharedInstance ? LockForReal : SilenceAssertionsOnly);
+ APIEntryShim entryShim(array->globalData, false);
delete array;
}
}
@@ -510,9 +491,6 @@ JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size
void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStringRef propertyName)
{
PropertyNameArray* propertyNames = toJS(array);
-
- propertyNames->globalData()->heap.registerThread();
- JSLock lock(propertyNames->globalData()->isSharedInstance ? LockForReal : SilenceAssertionsOnly);
-
+ APIEntryShim entryShim(propertyNames->globalData());
propertyNames->add(propertyName->identifier(propertyNames->globalData()));
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSStringRef.h b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSStringRef.h
index 41d8978..c58b958 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSStringRef.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSStringRef.h
@@ -37,7 +37,7 @@
extern "C" {
#endif
-#if (!defined(WIN32) && !defined(_WIN32) && !defined(__WINSCW__))
+#if !defined(WIN32) && !defined(_WIN32) && !defined(__WINSCW__)
/*!
@typedef JSChar
@abstract A Unicode character.
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSValueRef.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSValueRef.cpp
index 2207181..a12cc34 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/JSValueRef.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/JSValueRef.cpp
@@ -28,6 +28,7 @@
#include <wtf/Platform.h>
#include "APICast.h"
+#include "APIShims.h"
#include "JSCallbackObject.h"
#include <runtime/JSGlobalObject.h>
@@ -41,13 +42,14 @@
#include <algorithm> // for std::min
-JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
+using namespace JSC;
+
+::JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
{
- JSC::ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSC::JSLock lock(exec);
+ ExecState* exec = toJS(ctx);
+ APIEntryShim entryShim(exec);
- JSC::JSValue jsValue = toJS(exec, value);
+ JSValue jsValue = toJS(exec, value);
if (jsValue.isUndefined())
return kJSTypeUndefined;
@@ -63,13 +65,10 @@ JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
return kJSTypeObject;
}
-using namespace JSC; // placed here to avoid conflict between JSC::JSType and JSType, above.
-
bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
return jsValue.isUndefined();
@@ -78,8 +77,7 @@ bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
return jsValue.isNull();
@@ -88,8 +86,7 @@ bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
return jsValue.isBoolean();
@@ -98,8 +95,7 @@ bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
return jsValue.isNumber();
@@ -108,8 +104,7 @@ bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
bool JSValueIsString(JSContextRef ctx, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
return jsValue.isString();
@@ -118,8 +113,7 @@ bool JSValueIsString(JSContextRef ctx, JSValueRef value)
bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
return jsValue.isObject();
@@ -128,8 +122,7 @@ bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
@@ -145,8 +138,7 @@ bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsCla
bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsA = toJS(exec, a);
JSValue jsB = toJS(exec, b);
@@ -163,20 +155,18 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex
bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsA = toJS(exec, a);
JSValue jsB = toJS(exec, b);
- return JSValue::strictEqual(jsA, jsB);
+ return JSValue::strictEqual(exec, jsA, jsB);
}
bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
@@ -195,8 +185,7 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject
JSValueRef JSValueMakeUndefined(JSContextRef ctx)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
return toRef(exec, jsUndefined());
}
@@ -204,8 +193,7 @@ JSValueRef JSValueMakeUndefined(JSContextRef ctx)
JSValueRef JSValueMakeNull(JSContextRef ctx)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
return toRef(exec, jsNull());
}
@@ -213,8 +201,7 @@ JSValueRef JSValueMakeNull(JSContextRef ctx)
JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
return toRef(exec, jsBoolean(value));
}
@@ -222,8 +209,7 @@ JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
return toRef(exec, jsNumber(exec, value));
}
@@ -231,8 +217,7 @@ JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
return toRef(exec, jsString(exec, string->ustring()));
}
@@ -240,8 +225,7 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
return jsValue.toBoolean(exec);
@@ -250,8 +234,7 @@ bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
@@ -268,8 +251,7 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception
JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
@@ -286,8 +268,7 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef*
JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
JSValue jsValue = toJS(exec, value);
@@ -304,19 +285,17 @@ JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exce
void JSValueProtect(JSContextRef ctx, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
- JSValue jsValue = toJS(exec, value);
+ JSValue jsValue = toJSForGC(exec, value);
gcProtect(jsValue);
}
void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
{
ExecState* exec = toJS(ctx);
- exec->globalData().heap.registerThread();
- JSLock lock(exec);
+ APIEntryShim entryShim(exec);
- JSValue jsValue = toJS(exec, value);
+ JSValue jsValue = toJSForGC(exec, value);
gcUnprotect(jsValue);
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/API/OpaqueJSString.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/API/OpaqueJSString.cpp
index 7c7b1af..f740abe 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/API/OpaqueJSString.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/API/OpaqueJSString.cpp
@@ -42,7 +42,7 @@ PassRefPtr<OpaqueJSString> OpaqueJSString::create(const UString& ustring)
UString OpaqueJSString::ustring() const
{
if (this && m_characters)
- return UString(m_characters, m_length, true);
+ return UString(m_characters, m_length);
return UString::null();
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog
index 5fa56a7..35aabc9 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog
@@ -1,3 +1,7410 @@
+2010-01-27 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Oliver Hunt.
+
+ [BREWMP] Add MarkStack fastMalloc implementation for platforms without VirtualAlloc or mmap.
+ https://bugs.webkit.org/show_bug.cgi?id=33582
+
+ Use fastMalloc and fastFree to implement MarkStack::allocateStack and
+ MarkStack::releaseStack for platforms without page level allocation.
+
+ * runtime/MarkStack.h:
+ (JSC::MarkStack::MarkStackArray::shrinkAllocation):
+ * runtime/MarkStackNone.cpp: Added.
+ (JSC::MarkStack::initializePagesize):
+ (JSC::MarkStack::allocateStack):
+ (JSC::MarkStack::releaseStack):
+
+2010-01-27 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Eric Seidel.
+
+ [BREWMP] Don't use time function
+ https://bugs.webkit.org/show_bug.cgi?id=33577
+
+ Calling time(0) in BREW devices causes a crash because time
+ is not properly ported in most devices. Cast currentTime() to
+ time_t to get the same result as time(0).
+
+ * wtf/DateMath.cpp:
+ (WTF::calculateUTCOffset):
+
+2010-01-27 Alexey Proskuryakov <ap@apple.com>
+
+ Revert r53899 (HashMap<AtomicStringImpl*, Value> key checks) and subsequent build fixes,
+ because they make SVG tests crash in release builds.
+
+ * wtf/HashMap.h:
+ (WTF::::remove):
+ * wtf/HashSet.h:
+ (WTF::::remove):
+ * wtf/HashTable.h:
+ (WTF::::add):
+ (WTF::::addPassingHashCode):
+ (WTF::::removeAndInvalidate):
+ (WTF::::remove):
+ (WTF::::rehash):
+ (WTF::::checkTableConsistency):
+ (WTF::::checkTableConsistencyExceptSize):
+ * wtf/HashTraits.h:
+ (WTF::GenericHashTraits::emptyValue):
+ (WTF::):
+ * wtf/RefPtrHashMap.h:
+ (WTF::::remove):
+
+2010-01-26 Alexey Proskuryakov <ap@apple.com>
+
+ More Windows build fixing.
+
+ * wtf/HashTraits.h: _msize takes void*, remove const qualifier from type.
+
+2010-01-26 Alexey Proskuryakov <ap@apple.com>
+
+ Windows build fix.
+
+ * wtf/HashTraits.h: Include malloc.h for _msize().
+
+2010-01-26 Alexey Proskuryakov <ap@apple.com>
+
+ Build fix.
+
+ * wtf/HashTable.h: (WTF::HashTable::checkTableConsistencyExceptSize): Remove const from a
+ static (empty) version of this function.
+
+2010-01-26 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34150
+ WebKit needs a mechanism to catch stale HashMap entries
+
+ It is very difficult to catch stale pointers that are HashMap keys - since a pointer's hash
+ is just its value, it is very unlikely that any observable problem is reproducible.
+
+ This extends hash table consistency checks to check that pointers are referencing allocated
+ memory blocks, and makes it possible to invoke the checks explicitly (it is not feasible
+ to enable CHECK_HASHTABLE_CONSISTENCY by default, because that affects performance too much).
+
+ * wtf/HashMap.h: (WTF::::checkConsistency): Call through to HashTable implementation. We can
+ add similar calls to HashSet and HashCountedSet, but I haven't seen hard to debug problems
+ with those yet.
+
+ * wtf/HashSet.h: (WTF::::remove): The version of checkTableConsistency that's guarded by
+ CHECK_HASHTABLE_CONSISTENCY is now called internalCheckTableConsistency().
+
+ * wtf/HashTable.h:
+ (WTF::HashTable::internalCheckTableConsistency):
+ (WTF::HashTable::internalCheckTableConsistencyExceptSize):
+ (WTF::HashTable::checkTableConsistencyExceptSize):
+ Expose checkTableConsistency() even if CHECK_HASHTABLE_CONSISTENCY is off.
+ (WTF::::add): Updated for checkTableConsistency renaming.
+ (WTF::::addPassingHashCode): Ditto.
+ (WTF::::removeAndInvalidate): Ditto.
+ (WTF::::remove): Ditto.
+ (WTF::::rehash): Ditto.
+ (WTF::::checkTableConsistency): The assertion for !shouldExpand() was not correct - this
+ function returns true for tables with m_table == 0.
+ (WTF::::checkTableConsistencyExceptSize): Call checkValueConsistency for key. Potentially,
+ we could do the same for values.
+
+ * wtf/HashTraits.h:
+ (WTF::GenericHashTraits::checkValueConsistency): An empty function that can be overridden
+ to add checks. Currently, the only override is for pointer hashes.
+
+ * wtf/RefPtrHashMap.h: (WTF::::remove): Updated for checkTableConsistency renaming.
+
+2010-01-26 Lyon Chen <liachen@rim.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Opcode.h use const void* for Opcode cause error #1211 for RVCT compiler
+ https://bugs.webkit.org/show_bug.cgi?id=33902
+
+ * bytecode/Opcode.h:
+
+2010-01-26 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Windows build references non-existent include paths
+ https://bugs.webkit.org/show_bug.cgi?id=34175
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
+ * JavaScriptCore.vcproj/WTF/WTFCommon.vsprops:
+ * JavaScriptCore.vcproj/jsc/jscCommon.vsprops:
+ * JavaScriptCore.vcproj/testapi/testapi.vcproj:
+ * JavaScriptCore.vcproj/testapi/testapiCommon.vsprops:
+
+2010-01-26 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Using JavaScriptCore API with a webkit vended context can result in slow script dialog
+ https://bugs.webkit.org/show_bug.cgi?id=34172
+
+ Make the APIShim correctly increment and decrement the timeout
+ entry counter.
+
+ * API/APIShims.h:
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
+ (JSC::APICallbackShim::APICallbackShim):
+ (JSC::APICallbackShim::~APICallbackShim):
+
+2010-01-26 Simon Hausmann <simon.hausmann@nokia.com>
+
+ [Qt] Fix compilation of QtScript with non-gcc compilers
+
+ Variable length stack arrays are a gcc extension. Use QVarLengthArray
+ as a more portable solution that still tries to allocate on the stack
+ first.
+
+ * qt/api/qscriptvalue_p.h:
+ (QScriptValuePrivate::call):
+
+2010-01-26 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ [Qt] Fix the build on platforms without JIT support.
+
+ The JIT support should be determined at compile-time via wtf/Platform.h
+
+ * qt/api/QtScript.pro:
+
+2010-01-26 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ First steps of the QtScript API.
+
+ Two new classes were created; QScriptEngine and QScriptValue.
+ The first should encapsulate a javascript context and the second a script
+ value.
+
+ This API is still in development, so it isn't compiled by default.
+ To trigger compilation, pass --qmakearg="CONFIG+=build-qtscript" to
+ build-webkit.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32565
+
+ * qt/api/QtScript.pro: Added.
+ * qt/api/qscriptconverter_p.h: Added.
+ (QScriptConverter::toString):
+ * qt/api/qscriptengine.cpp: Added.
+ (QScriptEngine::QScriptEngine):
+ (QScriptEngine::~QScriptEngine):
+ (QScriptEngine::evaluate):
+ (QScriptEngine::collectGarbage):
+ * qt/api/qscriptengine.h: Added.
+ * qt/api/qscriptengine_p.cpp: Added.
+ (QScriptEnginePrivate::QScriptEnginePrivate):
+ (QScriptEnginePrivate::~QScriptEnginePrivate):
+ (QScriptEnginePrivate::evaluate):
+ * qt/api/qscriptengine_p.h: Added.
+ (QScriptEnginePrivate::get):
+ (QScriptEnginePrivate::collectGarbage):
+ (QScriptEnginePrivate::makeJSValue):
+ (QScriptEnginePrivate::context):
+ * qt/api/qscriptvalue.cpp: Added.
+ (QScriptValue::QScriptValue):
+ (QScriptValue::~QScriptValue):
+ (QScriptValue::isValid):
+ (QScriptValue::isBool):
+ (QScriptValue::isBoolean):
+ (QScriptValue::isNumber):
+ (QScriptValue::isNull):
+ (QScriptValue::isString):
+ (QScriptValue::isUndefined):
+ (QScriptValue::isError):
+ (QScriptValue::isObject):
+ (QScriptValue::isFunction):
+ (QScriptValue::toString):
+ (QScriptValue::toNumber):
+ (QScriptValue::toBool):
+ (QScriptValue::toBoolean):
+ (QScriptValue::toInteger):
+ (QScriptValue::toInt32):
+ (QScriptValue::toUInt32):
+ (QScriptValue::toUInt16):
+ (QScriptValue::call):
+ (QScriptValue::engine):
+ (QScriptValue::operator=):
+ (QScriptValue::equals):
+ (QScriptValue::strictlyEquals):
+ * qt/api/qscriptvalue.h: Added.
+ (QScriptValue::):
+ * qt/api/qscriptvalue_p.h: Added.
+ (QScriptValuePrivate::):
+ (QScriptValuePrivate::get):
+ (QScriptValuePrivate::QScriptValuePrivate):
+ (QScriptValuePrivate::isValid):
+ (QScriptValuePrivate::isBool):
+ (QScriptValuePrivate::isNumber):
+ (QScriptValuePrivate::isNull):
+ (QScriptValuePrivate::isString):
+ (QScriptValuePrivate::isUndefined):
+ (QScriptValuePrivate::isError):
+ (QScriptValuePrivate::isObject):
+ (QScriptValuePrivate::isFunction):
+ (QScriptValuePrivate::toString):
+ (QScriptValuePrivate::toNumber):
+ (QScriptValuePrivate::toBool):
+ (QScriptValuePrivate::toInteger):
+ (QScriptValuePrivate::toInt32):
+ (QScriptValuePrivate::toUInt32):
+ (QScriptValuePrivate::toUInt16):
+ (QScriptValuePrivate::equals):
+ (QScriptValuePrivate::strictlyEquals):
+ (QScriptValuePrivate::assignEngine):
+ (QScriptValuePrivate::call):
+ (QScriptValuePrivate::engine):
+ (QScriptValuePrivate::context):
+ (QScriptValuePrivate::value):
+ (QScriptValuePrivate::object):
+ (QScriptValuePrivate::inherits):
+ (QScriptValuePrivate::isJSBased):
+ (QScriptValuePrivate::isNumberBased):
+ (QScriptValuePrivate::isStringBased):
+ * qt/api/qtscriptglobal.h: Added.
+ * qt/tests/qscriptengine/qscriptengine.pro: Added.
+ * qt/tests/qscriptengine/tst_qscriptengine.cpp: Added.
+ (tst_QScriptEngine::tst_QScriptEngine):
+ (tst_QScriptEngine::~tst_QScriptEngine):
+ (tst_QScriptEngine::init):
+ (tst_QScriptEngine::cleanup):
+ (tst_QScriptEngine::collectGarbage):
+ (tst_QScriptEngine::evaluate):
+ * qt/tests/qscriptvalue/qscriptvalue.pro: Added.
+ * qt/tests/qscriptvalue/tst_qscriptvalue.cpp: Added.
+ (tst_QScriptValue::tst_QScriptValue):
+ (tst_QScriptValue::~tst_QScriptValue):
+ (tst_QScriptValue::init):
+ (tst_QScriptValue::cleanup):
+ (tst_QScriptValue::ctor):
+ (tst_QScriptValue::toString_data):
+ (tst_QScriptValue::toString):
+ (tst_QScriptValue::copyConstructor_data):
+ (tst_QScriptValue::copyConstructor):
+ (tst_QScriptValue::assignOperator_data):
+ (tst_QScriptValue::assignOperator):
+ (tst_QScriptValue::dataSharing):
+ (tst_QScriptValue::constructors_data):
+ (tst_QScriptValue::constructors):
+ (tst_QScriptValue::call):
+ * qt/tests/tests.pri: Added.
+ * qt/tests/tests.pro: Added.
+
+2010-01-25 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by David Levin.
+
+ Fix Chromium Linux tests: the pthread functions on Linux produce segfault if they receive 0 thread handle.
+ After r53714, we can have 0 thread handles passed to pthread_join and pthread_detach if corresponding threads
+ were already terminated and their threadMap entries cleared.
+ Add a 0 check.
+
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::waitForThreadCompletion):
+ (WTF::detachThread):
+
+2010-01-24 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Refactor JITStubs.cpp so that DEFINE_STUB_FUNCTION is only used once for each function
+ https://bugs.webkit.org/show_bug.cgi?id=33866
+
+ Place the guard USE(JSVALUE32_64) inside the body of the DEFINE_STUB_FUNCTION
+ macro for those functions that are always present.
+
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+
+2010-01-22 Kevin Watters <kevinwatters@gmail.com>
+
+ Reviewed by Kevin Ollivier.
+
+ [wx] Remove the Bakefile build system, which is no longer being used.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34022
+
+ * JavaScriptCoreSources.bkl: Removed.
+ * jscore.bkl: Removed.
+
+2010-01-22 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34025
+ Enable client-based Geolocation abstraction for Mac, Windows AppleWebKit targets.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2010-01-22 Dmitry Titov <dimich@chromium.org>
+
+ Not reviewed, attempted Snow Leopard build fix.
+
+ * wtf/ThreadingPthreads.cpp: Add a forward declaration of a function which is not 'static'.
+
+2009-01-22 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Maciej Stachowiak.
+
+ Fix the leak of ThreadIdentifiers in threadMap across threads.
+ https://bugs.webkit.org/show_bug.cgi?id=32689
+
+ Test is added to DumpRenderTree.mm.
+
+ * Android.mk: Added file ThreadIdentifierDataPthreads.(h|cpp) to build.
+ * Android.v8.wtf.mk: Ditto.
+ * GNUmakefile.am: Ditto.
+ * JavaScriptCore.gyp/JavaScriptCore.gyp: Ditto.
+ * JavaScriptCore.gypi: Ditto.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
+
+ * wtf/ThreadIdentifierDataPthreads.cpp: Added. Contains custom implementation of thread-specific data that uses custom destructor.
+ (WTF::ThreadIdentifierData::~ThreadIdentifierData): Removes the ThreadIdentifier from the threadMap.
+ (WTF::ThreadIdentifierData::identifier):
+ (WTF::ThreadIdentifierData::initialize):
+ (WTF::ThreadIdentifierData::destruct): Custom thread-specific destructor. Resets the value for the key again to cause second invoke.
+ (WTF::ThreadIdentifierData::initializeKeyOnceHelper):
+ (WTF::ThreadIdentifierData::initializeKeyOnce): Need to use pthread_once since initialization may come on any thread(s).
+ * wtf/ThreadIdentifierDataPthreads.h: Added.
+ (WTF::ThreadIdentifierData::ThreadIdentifierData):
+
+ * wtf/Threading.cpp:
+ (WTF::threadEntryPoint): Move initializeCurrentThreadInternal to after the lock to make
+ sure it is invoked when ThreadIdentifier is already established.
+
+ * wtf/Threading.h: Rename setThreadNameInternal -> initializeCurrentThreadInternal since it does more then only set the name now.
+ * wtf/ThreadingNone.cpp:
+ (WTF::initializeCurrentThreadInternal): Ditto.
+ * wtf/ThreadingWin.cpp:
+ (WTF::initializeCurrentThreadInternal): Ditto.
+ (WTF::initializeThreading): Ditto.
+ * wtf/gtk/ThreadingGtk.cpp:
+ (WTF::initializeCurrentThreadInternal): Ditto.
+ * wtf/qt/ThreadingQt.cpp:
+ (WTF::initializeCurrentThreadInternal): Ditto.
+
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::establishIdentifierForPthreadHandle):
+ (WTF::clearPthreadHandleForIdentifier): Make it not 'static' so the ~ThreadIdentifierData() in another file can call it.
+ (WTF::initializeCurrentThreadInternal): Set the thread-specific data. The ThreadIdentifier is already established by creating thread.
+ (WTF::waitForThreadCompletion): Remove call to clearPthreadHandleForIdentifier(threadID) since it is now done in ~ThreadIdentifierData().
+ (WTF::detachThread): Ditto.
+ (WTF::currentThread): Use the thread-specific data to get the ThreadIdentifier. It's many times faster then Mutex-protected iteration through the map.
+ Also, set the thread-specific data if called first time on the thread.
+
+2010-01-21 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Add ThreadSpecific for ENABLE(SINGLE_THREADED)
+ https://bugs.webkit.org/show_bug.cgi?id=33878
+
+ Implement ThreadSpecific with a simple getter/setter
+ when ENABLE(SINGLE_THREADED) is true.
+
+ Due to the change in https://bugs.webkit.org/show_bug.cgi?id=33236,
+ an implementation of ThreadSpecific must be available to build WebKit.
+ This causes a build failure for platforms without a proper
+ ThreadSpecific implementation.
+
+ * wtf/ThreadSpecific.h:
+ (WTF::::ThreadSpecific):
+ (WTF::::~ThreadSpecific):
+ (WTF::::get):
+ (WTF::::set):
+ (WTF::::destroy):
+
+2010-01-21 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Maciej Stachowiak.
+
+ Add fastStrDup to FastMalloc
+ https://bugs.webkit.org/show_bug.cgi?id=33937
+
+ The new string returned by fastStrDup is obtained with fastMalloc,
+ and can be freed with fastFree. This makes the memory management
+ more consistent because we don't need to keep strdup allocated pointers
+ and free them with free(). Instead we can use fastFree everywhere.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::fastStrDup):
+ * wtf/FastMalloc.h:
+
+2010-01-21 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ history.back() for same-document history traversals isn't synchronous as the specification states.
+ <rdar://problem/7535011> and https://bugs.webkit.org/show_bug.cgi?id=33538
+
+ * wtf/Platform.h: Add a "HISTORY_ALWAYS_ASYNC" enable and turn it on for Chromium.
+
+2010-01-21 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Always create a prototype for automatically managed classes.
+
+ This fixes some errors where prototype chains were not correctly hooked
+ up, and also ensures that API classes work correctly with features like
+ instanceof.
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClass::create): Cleaned up some of this code. Also changed it
+ to always create a prototype class.
+
+ * API/tests/testapi.c:
+ (Derived2_class):
+ (main): Fixed a null value crash in the exception checking code.
+ * API/tests/testapi.js: Added some tests for the case where a prototype
+ chain would not be hooked up correctly.
+
+2010-01-21 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Force JSC to create a prototype chain for API classes with a
+ parent class but no static functions.
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClass::create):
+
+2010-01-21 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Object.getOwnPropertyDescriptor always returns undefined for JS API objects
+ https://bugs.webkit.org/show_bug.cgi?id=33946
+
+ Ideally the getOwnPropertyDescriptor() reimplementation should return an
+ access descriptor that wraps the property getter and setter callbacks, but
+ that approach is much more involved than returning a value descriptor.
+ Keep it simple for now.
+
+ * API/JSCallbackObject.h:
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::getOwnPropertyDescriptor):
+ * API/tests/testapi.js:
+
+2010-01-20 Mark Rowe <mrowe@apple.com>
+
+ Build fix.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMalloc_PageHeap::initializeScavenger): Remove unnecessary function call.
+
+2010-01-20 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Use the inline i386 assembly for x86_64 as well rather than falling back to using pthread mutexes.
+
+ * wtf/TCSpinLock.h:
+ (TCMalloc_SpinLock::Lock):
+ (TCMalloc_SpinLock::Unlock):
+ (TCMalloc_SlowLock):
+
+2010-01-20 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/7215063> Use GCD instead of an extra thread for FastMalloc scavenging on platforms where it is supported
+
+ Abstract the background scavenging slightly so that an alternate implementation that uses GCD can be used on platforms
+ where it is supported.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMalloc_PageHeap::init):
+ (WTF::TCMalloc_PageHeap::initializeScavenger):
+ (WTF::TCMalloc_PageHeap::signalScavenger):
+ (WTF::TCMalloc_PageHeap::shouldContinueScavenging):
+ (WTF::TCMalloc_PageHeap::Delete):
+ (WTF::TCMalloc_PageHeap::periodicScavenge):
+ * wtf/Platform.h:
+
+2010-01-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/7562708> REGRESSION(53460): Heap::destroy may not run
+ all destructors
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::freeBlocks): Instead of fully marking protected objects,
+ just set their mark bits. This prevents protected objects from keeping
+ unprotected objects alive. Destructor order is not guaranteed, so it's
+ OK to destroy objects pointed to by protected objects before destroying
+ protected objects.
+
+2010-01-19 David Levin <levin@chromium.org>
+
+ Reviewed by Oliver Hunt.
+
+ CrossThreadCopier needs to support ThreadSafeShared better.
+ https://bugs.webkit.org/show_bug.cgi?id=33698
+
+ * wtf/TypeTraits.cpp: Added tests for the new type traits.
+ * wtf/TypeTraits.h:
+ (WTF::IsSubclass): Determines if a class is a derived from another class.
+ (WTF::IsSubclassOfTemplate): Determines if a class is a derived from a
+ template class (with one parameter that is unknown).
+ (WTF::RemoveTemplate): Reveals the type for a template parameter.
+
+2010-01-20 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Darin Adler and Adam Roben.
+
+ Feature defines are difficult to maintain on Windows builds
+ https://bugs.webkit.org/show_bug.cgi?id=33883
+
+ FeatureDefines.vsprops are now maintained in a way similar to
+ Configurations/FeatureDefines.xcconfig, with the added advantage
+ of having a single FeatureDefines file across all projects.
+
+ * Configurations/FeatureDefines.xcconfig: Add comments about keeping feature definitions in sync.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add FeatureDefines.vsprops inherited property sheet.
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj: Add FeatureDefines.vsprops inherited property sheet.
+
+2010-01-20 Csaba Osztrogonác <ossy@webkit.org>
+
+ [Qt] Unreviewed buildfix for r53547.
+
+ * DerivedSources.pro:
+
+2010-01-20 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Make extraCompilers for generated sources depend on their scripts
+
+ * DerivedSources.pro:
+
+2010-01-19 Brian Weinstein <bweinstein@apple.com>
+
+ Reviewed by Tim Hatcher.
+
+ When JavaScriptCore calls Debugger::Exception, have it pass a
+ hasHandler variable that represents if exception is being handled
+ in the same function (not in a parent on the call stack).
+
+ This just adds a new parameter, no behavior is changed.
+
+ * debugger/Debugger.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException):
+
+2010-01-18 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Inline functions that are hot in DOM manipulation
+ https://bugs.webkit.org/show_bug.cgi?id=33820
+
+ (3% speedup on Dromaeo DOM Core tests)
+
+ * runtime/WeakGCMap.h:
+ (JSC::::get): inline
+
+2010-01-19 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Unreviewed build fix for JIT with RVCT.
+
+ Remove IMPORT statement; cti_vm_throw is already defined in JITStubs.h.
+ Remove extra ')'.
+
+ * jit/JITStubs.cpp:
+ (JSC::ctiVMThrowTrampoline):
+
+2010-01-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ REGRESSION (52082): Crash on worker thread when reloading http://radnan.public.iastate.edu/procedural/
+ https://bugs.webkit.org/show_bug.cgi?id=33826
+
+ This bug was caused by a GC-protected object being destroyed early by
+ Heap::destroy. Clients of the GC protect APIs (reasonably) expect pointers
+ to GC-protected memory to be valid.
+
+ The solution is to do two passes of tear-down in Heap::destroy. The first
+ pass tears down all unprotected objects. The second pass ASSERTs that all
+ previously protected objects are now unprotected, and then tears down
+ all perviously protected objects. These two passes simulate the two passes
+ that would have been required to free a protected object during normal GC.
+
+ * API/JSContextRef.cpp: Removed some ASSERTs that have moved into Heap.
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::destroy): Moved ASSERTs to here.
+ (JSC::Heap::freeBlock): Tidied up the use of didShrink by moving its
+ setter to the function that does the shrinking.
+ (JSC::Heap::freeBlocks): Implemented above algorithm.
+ (JSC::Heap::shrinkBlocks): Tidied up the use of didShrink.
+
+2010-01-19 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ Reverting r53455, breaks 2 javascriptcore tests.
+
+ * API/JSContextRef.cpp:
+ * runtime/Collector.cpp:
+ (JSC::Heap::destroy):
+ (JSC::Heap::freeBlock):
+ (JSC::Heap::freeBlocks):
+ (JSC::Heap::shrinkBlocks):
+
+2010-01-18 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ Revert r53454, since it causes much sadness in this world.
+
+ * runtime/UString.cpp:
+ (JSC::UString::spliceSubstringsWithSeparators):
+ (JSC::UString::replaceRange):
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::baseSharedBuffer):
+ (JSC::UStringImpl::sharedBuffer):
+ (JSC::UStringImpl::~UStringImpl):
+ * runtime/UStringImpl.h:
+ (JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield):
+ (JSC::UntypedPtrAndBitfield::asPtr):
+ (JSC::UntypedPtrAndBitfield::operator&=):
+ (JSC::UntypedPtrAndBitfield::operator|=):
+ (JSC::UntypedPtrAndBitfield::operator&):
+ (JSC::UStringImpl::create):
+ (JSC::UStringImpl::cost):
+ (JSC::UStringImpl::isIdentifier):
+ (JSC::UStringImpl::setIsIdentifier):
+ (JSC::UStringImpl::ref):
+ (JSC::UStringImpl::deref):
+ (JSC::UStringImpl::checkConsistency):
+ (JSC::UStringImpl::UStringImpl):
+ (JSC::UStringImpl::bufferOwnerString):
+ (JSC::UStringImpl::bufferOwnership):
+ (JSC::UStringImpl::isStatic):
+ * wtf/StringHashFunctions.h:
+ (WTF::stringHash):
+
+2010-01-18 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ REGRESSION (52082): Crash on worker thread when reloading http://radnan.public.iastate.edu/procedural/
+ https://bugs.webkit.org/show_bug.cgi?id=33826
+
+ This bug was caused by a GC-protected object being destroyed early by
+ Heap::destroy. Clients of the GC protect APIs (reasonably) expect pointers
+ to GC-protected memory to be valid.
+
+ The solution is to do two passes of tear-down in Heap::destroy. The first
+ pass tears down all unprotected objects. The second pass ASSERTs that all
+ previously protected objects are now unprotected, and then tears down
+ all perviously protected objects. These two passes simulate the two passes
+ that would have been required to free a protected object during normal GC.
+
+ * API/JSContextRef.cpp: Removed some ASSERTs that have moved into Heap.
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::destroy): Moved ASSERTs to here.
+ (JSC::Heap::freeBlock): Tidied up the use of didShrink by moving its
+ setter to the function that does the shrinking.
+ (JSC::Heap::freeBlocks): Implemented above algorithm.
+ (JSC::Heap::shrinkBlocks): Tidied up the use of didShrink.
+
+2010-01-18 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33731
+ Remove UntypedPtrAndBitfield from UStringImpl (akin to PtrAndFlags).
+
+ This break the OS X Leaks tool. Instead, free up some more bits from the refCount.
+
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::sharedBuffer):
+ (JSC::UStringImpl::~UStringImpl):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::cost):
+ (JSC::UStringImpl::checkConsistency):
+ (JSC::UStringImpl::UStringImpl):
+ (JSC::UStringImpl::bufferOwnerString):
+ (JSC::UStringImpl::):
+ * wtf/StringHashFunctions.h:
+ (WTF::stringHash):
+
+2010-01-18 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ HTMLInputElement::valueAsDate setter support for type=month.
+ https://bugs.webkit.org/show_bug.cgi?id=33021
+
+ Expose the following functions to be used by WebCore:
+ - WTF::msToyear()
+ - WTF::dayInYear()
+ - WTF::monthFromDayInYear()
+ - WTF::dayInMonthFromDayInYear()
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * wtf/DateMath.cpp:
+ (WTF::msToYear): Remove "static inline".
+ (WTF::dayInYear): Remove "static inline".
+ (WTF::monthFromDayInYear): Remove "static inline".
+ (WTF::dayInMonthFromDayInYear): Remove "static inline".
+ * wtf/DateMath.h: Declare the above functions.
+
+2010-01-18 Darin Adler <darin@apple.com>
+
+ Fix build by reverting the previous change.
+
+ * runtime/UString.h: Rolled out the FastAllocBase base class.
+ It was making UString larger, and therefore JSString larger,
+ and too big for a garbage collection cell.
+
+ This raises the unpleasant possibility that many classes became
+ larger because we added the FastAllocBase base class. I am
+ worried about this, and it needs to be investigated.
+
+2010-01-18 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Allow custom memory allocation control for UString class
+ https://bugs.webkit.org/show_bug.cgi?id=27831
+
+ Inherits the following class from FastAllocBase because it is
+ instantiated by 'new' and no need to be copyable:
+
+ class name - instantiated at:
+ classs UString - JavaScriptCore/runtime/UString.cpp:160
+
+ * runtime/UString.h:
+
+2010-01-18 Evan Cheng <evan.cheng@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Add some ALWAYS_INLINE for key functions not inlined by some versions of GCC.
+ rdar://problem/7553780
+
+ * runtime/JSObject.h:
+ (JSC::JSObject::getPropertySlot): ALWAYS_INLINE both overloads.
+ * runtime/JSString.h:
+ (JSC::JSString::JSString): ALWAYS_INLINE the version that takes a UString.
+ * runtime/UString.h:
+ (JSC::operator==): ALWAYS_INLINE the version that compares two UString objects.
+
+2010-01-18 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Delete dftables-xxxxxxxx.in files automatically.
+ https://bugs.webkit.org/show_bug.cgi?id=33796
+
+ * pcre/dftables: unlink unnecessary temporary file.
+
+2010-01-18 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Force qmake to generate a single makefile for DerivedSources.pro
+
+ * DerivedSources.pro:
+
+2010-01-18 Csaba Osztrogonác <ossy@webkit.org>
+
+ Rubber-stamped by Gustavo Noronha Silva.
+
+ Rolling out r53391 and r53392 because of random crashes on buildbots.
+ https://bugs.webkit.org/show_bug.cgi?id=33731
+
+ * bytecode/CodeBlock.h:
+ (JSC::CallLinkInfo::seenOnce):
+ (JSC::CallLinkInfo::setSeen):
+ (JSC::MethodCallLinkInfo::MethodCallLinkInfo):
+ (JSC::MethodCallLinkInfo::seenOnce):
+ (JSC::MethodCallLinkInfo::setSeen):
+ * jit/JIT.cpp:
+ (JSC::JIT::unlinkCall):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::patchMethodCallProto):
+ * runtime/UString.cpp:
+ (JSC::UString::spliceSubstringsWithSeparators):
+ (JSC::UString::replaceRange):
+ * runtime/UString.h:
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::baseSharedBuffer):
+ (JSC::UStringImpl::sharedBuffer):
+ (JSC::UStringImpl::~UStringImpl):
+ * runtime/UStringImpl.h:
+ (JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield):
+ (JSC::UntypedPtrAndBitfield::asPtr):
+ (JSC::UntypedPtrAndBitfield::operator&=):
+ (JSC::UntypedPtrAndBitfield::operator|=):
+ (JSC::UntypedPtrAndBitfield::operator&):
+ (JSC::UStringImpl::create):
+ (JSC::UStringImpl::cost):
+ (JSC::UStringImpl::isIdentifier):
+ (JSC::UStringImpl::setIsIdentifier):
+ (JSC::UStringImpl::ref):
+ (JSC::UStringImpl::deref):
+ (JSC::UStringImpl::checkConsistency):
+ (JSC::UStringImpl::UStringImpl):
+ (JSC::UStringImpl::bufferOwnerString):
+ (JSC::UStringImpl::bufferOwnership):
+ (JSC::UStringImpl::isStatic):
+ * wtf/StringHashFunctions.h:
+ (WTF::stringHash):
+
+2010-01-18 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Fix the build with strict gcc and RVCT versions: It's not legal to cast a
+ pointer to a function to a void* without an intermediate cast to a non-pointer
+ type. A cast to a ptrdiff_t inbetween fixes it.
+
+ * runtime/JSString.h:
+ (JSC::Fiber::JSString):
+
+2010-01-15 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33731
+ Remove UntypedPtrAndBitfield from UStringImpl (akin to PtrAndFlags).
+
+ This break the OS X Leaks tool. Instead, free up some more bits from the refCount.
+
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::sharedBuffer):
+ (JSC::UStringImpl::~UStringImpl):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::cost):
+ (JSC::UStringImpl::checkConsistency):
+ (JSC::UStringImpl::UStringImpl):
+ (JSC::UStringImpl::bufferOwnerString):
+ (JSC::UStringImpl::):
+ * wtf/StringHashFunctions.h:
+ (WTF::stringHash):
+
+2010-01-15 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33731
+ Remove uses of PtrAndFlags from JIT data stuctures.
+
+ These break the OS X Leaks tool. Free up a bit in CallLinkInfo, and invalid
+ permutation of pointer states in MethodCallLinkInfo to represent the removed bits.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CallLinkInfo::seenOnce):
+ (JSC::CallLinkInfo::setSeen):
+ (JSC::MethodCallLinkInfo::MethodCallLinkInfo):
+ (JSC::MethodCallLinkInfo::seenOnce):
+ (JSC::MethodCallLinkInfo::setSeen):
+ * jit/JIT.cpp:
+ (JSC::JIT::unlinkCall):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::patchMethodCallProto):
+ * runtime/UString.h:
+
+2010-01-16 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Cache JS string values made from DOM strings (Dromaeo speedup)
+ https://bugs.webkit.org/show_bug.cgi?id=33768
+ <rdar://problem/7353576>
+
+ * runtime/JSString.h:
+ (JSC::jsStringWithFinalizer): Added new mechanism for a string to have an optional
+ finalizer callback, for the benefit of weak-referencing caches.
+ (JSC::):
+ (JSC::Fiber::JSString):
+ (JSC::Fiber::~JSString):
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope): Clear fibers so this doesn't look like a string with a finalizer.
+ * runtime/WeakGCMap.h: Include "Collector.h" to make this header includable by itself.
+
+2010-01-15 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Maciej Stachowiak.
+
+ Fix for <rdar://problem/7548432>
+ Add ALWAYS_INLINE to jsLess for a 1% speedup on llvm-gcc.
+
+ * runtime/Operations.h:
+ (JSC::jsLess):
+
+2010-01-14 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ REGRESISON: Google maps buttons not working properly
+ https://bugs.webkit.org/show_bug.cgi?id=31871
+
+ REGRESSION(r52948): JavaScript exceptions thrown on Google Maps when
+ getting directions for a second time
+ https://bugs.webkit.org/show_bug.cgi?id=33446
+
+ SunSpider and v8 report no change.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::tryCacheGetByID): Update our cached offset in case
+ flattening the dictionary changed any of its offsets.
+
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::tryCacheGetByID):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/Operations.h:
+ (JSC::normalizePrototypeChain): ditto
+
+2010-01-14 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33705
+ UStringImpl::create() should use internal storage
+
+ When creating a UStringImpl copying of a UChar*, we can use an internal buffer,
+ by calling UStringImpl::tryCreateUninitialized().
+
+ Also, remove duplicate of copyChars from JSString, call UStringImpl's version.
+
+ Small (max 0.5%) progression on Sunspidey.
+
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::create):
+
+2010-01-14 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Make naming & behaviour of UString[Impl] methods more consistent.
+ https://bugs.webkit.org/show_bug.cgi?id=33702
+
+ UString::create() creates a copy of the UChar* passed, but UStringImpl::create() assumes
+ that it should assume ownership of the provided buffer (with UString::createNonCopying()
+ and UStringImpl::createCopying() providing the alternate behaviours). Unify on create()
+ taking a copy of the provided buffer. For non-copying cases, use the name 'adopt', and
+ make this method take a Vector<UChar>&. For cases where non-copying construction was being
+ used, other than from a Vector<UChar>, change the code to allocate the storage along with
+ the UStringImpl using UStringImpl::createUninitialized(). (The adopt() method also more
+ closely matches that of WebCore::StringImpl).
+
+ Also, UString::createUninitialized() and UStringImpl::createUninitialized() have incompatible
+ behaviours, in that the UString form sets the provided UChar* to a null or non-null value to
+ indicate success or failure, but UStringImpl uses the returned PassRefPtr<UStringImpl> to
+ indicate when allocation has failed (potentially leaving the output Char* uninitialized).
+ This is also incompatible with WebCore::StringImpl's behaviour, in that
+ StringImpl::createUninitialized() will CRASH() if unable to allocate. Some uses of
+ createUninitialized() in JSC are unsafe, since they do not test the result for null.
+ UStringImpl's indication is preferable, since we may want a successful call to set the result
+ buffer to 0 (specifically, StringImpl returns 0 for the buffer where createUninitialized()
+ returns the empty string, which seems reasonable to catch bugs early). UString's method
+ cannot support UStringImpl's behaviour directly, since it returns an object rather than a
+ pointer.
+ - remove UString::createUninitialized(), replace with calls to UStringImpl::createUninitialized()
+ - create a UStringImpl::tryCreateUninitialized() form UStringImpl::createUninitialized(),
+ with current behaviour, make createUninitialized() crash on failure to allocate.
+ - make cases in JSC that do not check the result call createUninitialized(), and cases that do
+ check call tryCreateUninitialized().
+
+ Rename computedHash() to existingHash(), to bring this in line wih WebCore::StringImpl.
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClassContextData::OpaqueJSClassContextData):
+ * JavaScriptCore.exp:
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToString):
+ * runtime/Identifier.cpp:
+ (JSC::CStringTranslator::translate):
+ (JSC::UCharBufferTranslator::translate):
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope):
+ * runtime/Lookup.cpp:
+ (JSC::HashTable::createTable):
+ * runtime/Lookup.h:
+ (JSC::HashTable::entry):
+ * runtime/StringBuilder.h:
+ (JSC::StringBuilder::release):
+ * runtime/StringConstructor.cpp:
+ (JSC::stringFromCharCodeSlowCase):
+ * runtime/StringPrototype.cpp:
+ (JSC::substituteBackreferencesSlow):
+ (JSC::stringProtoFuncToLowerCase):
+ (JSC::stringProtoFuncToUpperCase):
+ (JSC::stringProtoFuncFontsize):
+ (JSC::stringProtoFuncLink):
+ * runtime/Structure.cpp:
+ (JSC::Structure::despecifyDictionaryFunction):
+ (JSC::Structure::get):
+ (JSC::Structure::despecifyFunction):
+ (JSC::Structure::put):
+ (JSC::Structure::remove):
+ (JSC::Structure::insertIntoPropertyMapHashTable):
+ (JSC::Structure::checkConsistency):
+ * runtime/Structure.h:
+ (JSC::Structure::get):
+ * runtime/StructureTransitionTable.h:
+ (JSC::StructureTransitionTableHash::hash):
+ * runtime/UString.cpp:
+ (JSC::createRep):
+ (JSC::UString::UString):
+ (JSC::UString::spliceSubstringsWithSeparators):
+ (JSC::UString::replaceRange):
+ (JSC::UString::operator=):
+ * runtime/UString.h:
+ (JSC::UString::adopt):
+ (JSC::IdentifierRepHash::hash):
+ (JSC::makeString):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::adopt):
+ (JSC::UStringImpl::create):
+ (JSC::UStringImpl::createUninitialized):
+ (JSC::UStringImpl::tryCreateUninitialized):
+ (JSC::UStringImpl::existingHash):
+
+2010-01-13 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Oliver Hunt.
+
+ JSON.stringify and JSON.parse needlessly process properties in the prototype chain
+ https://bugs.webkit.org/show_bug.cgi?id=33053
+
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::Holder::appendNextProperty):
+ (JSC::Walker::walk):
+
+2010-01-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (buildfix).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-01-13 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33641
+ Assertion failure in Lexer.cpp if input stream ends while in string escape
+
+ Test: fast/js/end-in-string-escape.html
+
+ * parser/Lexer.cpp: (JSC::Lexer::lex): Bail out quickly on end of stream, not giving the
+ assertion a chance to fire.
+
+2010-01-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (buildfix).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-01-13 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber stamped by Sam Weinig & Darin Adler.
+
+ Three quick fixes to UStringImpl.
+ - The destroy() method can be switched back to a normal destructor; since we've switched
+ the way we protect static strings to be using an odd ref-count the destroy() won't abort.
+ - The cost() calculation logic was wrong. If you have multiple JSStrings wrapping substrings
+ of a base string, they would each report the full cost of the base string to the heap.
+ Instead we should only be reporting once for the base string.
+ - Remove the overloaded new operator calling fastMalloc, replace this with a 'using' to pick
+ up the implementation from the parent class.
+
+ * JavaScriptCore.exp:
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::~UStringImpl):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::cost):
+ (JSC::UStringImpl::deref):
+
+2010-01-13 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Split the build process in two different .pro files.
+ This allows qmake to be run once all source files are available.
+
+ * DerivedSources.pro: Added.
+ * JavaScriptCore.pri: Moved source generation to DerivedSources.pro
+ * pcre/pcre.pri: Moved source generation to DerivedSources.pro
+
+2010-01-12 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Geoffrey Garen.
+
+ [ES5] Implement Object.getOwnPropertyNames
+ https://bugs.webkit.org/show_bug.cgi?id=32242
+
+ Add an extra argument to getPropertyNames() and getOwnPropertyNames()
+ (and all reimplementations thereof) that indicates whether non-enumerable
+ properties should be added.
+
+ * API/JSCallbackObject.h:
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::getOwnPropertyNames):
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * debugger/DebuggerActivation.cpp:
+ (JSC::DebuggerActivation::getOwnPropertyNames):
+ * debugger/DebuggerActivation.h:
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::getOwnPropertyNames):
+ * runtime/Arguments.h:
+ * runtime/CommonIdentifiers.h:
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::getOwnPropertyNames):
+ * runtime/JSArray.h:
+ * runtime/JSByteArray.cpp:
+ (JSC::JSByteArray::getOwnPropertyNames):
+ * runtime/JSByteArray.h:
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::getOwnPropertyNames):
+ * runtime/JSFunction.h:
+ * runtime/JSNotAnObject.cpp:
+ (JSC::JSNotAnObject::getOwnPropertyNames):
+ * runtime/JSNotAnObject.h:
+ * runtime/JSObject.cpp:
+ (JSC::getClassPropertyNames):
+ (JSC::JSObject::getPropertyNames):
+ (JSC::JSObject::getOwnPropertyNames):
+ * runtime/JSObject.h:
+ * runtime/JSVariableObject.cpp:
+ (JSC::JSVariableObject::getOwnPropertyNames):
+ * runtime/JSVariableObject.h:
+ * runtime/ObjectConstructor.cpp:
+ (JSC::ObjectConstructor::ObjectConstructor):
+ (JSC::objectConstructorGetOwnPropertyNames):
+ * runtime/RegExpMatchesArray.h:
+ (JSC::RegExpMatchesArray::getOwnPropertyNames):
+ * runtime/StringObject.cpp:
+ (JSC::StringObject::getOwnPropertyNames):
+ * runtime/StringObject.h:
+ * runtime/Structure.cpp: Rename getEnumerablePropertyNames() to getPropertyNames(), which takes an extra argument.
+ (JSC::Structure::getPropertyNames):
+ * runtime/Structure.h:
+ (JSC::):
+
+2010-01-12 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33540
+ Make it possible to build in debug mode with assertions disabled
+
+ * jit/JITStubs.cpp: (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/Identifier.cpp: (JSC::Identifier::checkSameIdentifierTable):
+ * wtf/FastMalloc.cpp:
+ * wtf/HashTable.h: (WTF::HashTableConstIterator::checkValidity):
+ * yarr/RegexCompiler.cpp: (JSC::Yarr::compileRegex):
+
+2009-11-23 Yong Li <yoli@rim.com>
+
+ Reviewed by Adam Treat.
+
+ Make GIF decoder support down-sampling
+ https://bugs.webkit.org/show_bug.cgi?id=31806
+
+ * platform/image-decoders/ImageDecoder.cpp:
+ (WebCore::ImageDecoder::upperBoundScaledY):
+ (WebCore::ImageDecoder::lowerBoundScaledY):
+ * platform/image-decoders/ImageDecoder.h:
+ (WebCore::RGBA32Buffer::scaledRect):
+ (WebCore::RGBA32Buffer::setScaledRect):
+ (WebCore::ImageDecoder::scaledSize):
+ * platform/image-decoders/gif/GIFImageDecoder.cpp:
+ (WebCore::GIFImageDecoder::sizeNowAvailable):
+ (WebCore::GIFImageDecoder::initFrameBuffer):
+ (WebCore::copyOnePixel):
+ (WebCore::GIFImageDecoder::haveDecodedRow):
+ (WebCore::GIFImageDecoder::frameComplete):
+
+2010-01-12 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ ecma/Date/15.9.5.12-1.js fails every night at midnight
+ https://bugs.webkit.org/show_bug.cgi?id=28041
+
+ Change the test to use a concrete time instead of "now".
+
+ * tests/mozilla/ecma/Date/15.9.5.10-1.js:
+ * tests/mozilla/ecma/Date/15.9.5.12-1.js:
+
+2010-01-11 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Ariya Hidayat.
+
+ [Qt] Enable JIT and YARR_JIT if (CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100)
+
+ * wtf/Platform.h:
+
+2010-01-11 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33481
+ Uninitialized data members in ArrayStorage
+
+ SunSpider reports no change.
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::JSArray): Initialize missing data members in the two cases
+ where we don't use fastZeroedMalloc, so it doesn't happen automatically.
+
+2010-01-11 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33480
+
+ Improve debugging reliability for WTF on Windows.
+ Store WTF static library's PDB file into a better location.
+
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+
+2010-01-11 Steve Falkenburg <sfalken@apple.com>
+
+ Windows build fix.
+ Remove extraneous entries from def file causing build warning.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-01-10 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ RegExp.prototype.toString returns "//" for empty regular expressions
+ https://bugs.webkit.org/show_bug.cgi?id=33319
+
+ "//" starts a single-line comment, hence "/(?:)/" should be used, according to ECMA.
+
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncToString):
+
+ * tests/mozilla/ecma_2/RegExp/properties-001.js:
+ (AddRegExpCases):
+ * tests/mozilla/js1_2/regexp/toString.js:
+ Update relevant Mozilla tests (Mozilla has had this behavior since November 2003).
+
+2010-01-10 Darin Adler <darin@apple.com>
+
+ * tests/mozilla/ecma/Array/15.4.1.1.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Array/15.4.1.2.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Array/15.4.2.1-1.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Array/15.4.2.2-1.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Array/15.4.2.2-2.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Array/15.4.2.3.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Array/15.4.3.2.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Array/15.4.3.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Array/15.4.4.1.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Array/15.4.4.js: Added property allow-tabs.
+ * tests/mozilla/ecma/LexicalConventions/7.7.4.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Math/15.8.2.13.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Math/15.8.2.16.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Math/15.8.2.18.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Math/15.8.2.2.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Math/15.8.2.4.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Math/15.8.2.5.js: Added property allow-tabs.
+ * tests/mozilla/ecma/Math/15.8.2.7.js: Added property allow-tabs.
+ * tests/mozilla/ecma/String/15.5.1.js: Added property allow-tabs.
+ * tests/mozilla/ecma/String/15.5.2.js: Added property allow-tabs.
+ * tests/mozilla/ecma/String/15.5.3.1-3.js: Added property allow-tabs.
+ * tests/mozilla/ecma/String/15.5.3.1-4.js: Added property allow-tabs.
+ * tests/mozilla/ecma/String/15.5.3.js: Added property allow-tabs.
+ * tests/mozilla/ecma/TypeConversion/9.5-2.js: Added property allow-tabs.
+ * tests/mozilla/ecma/jsref.js: Modified property allow-tabs.
+ * tests/mozilla/ecma/shell.js: Modified property allow-tabs.
+ * tests/mozilla/ecma_2/LexicalConventions/keywords-001.js: Added property allow-tabs.
+ * tests/mozilla/ecma_2/RegExp/exec-001.js: Added property allow-tabs.
+ * tests/mozilla/ecma_2/String/match-004.js: Added property allow-tabs.
+ * tests/mozilla/ecma_2/String/replace-001.js: Added property allow-tabs.
+ * tests/mozilla/ecma_2/String/split-002.js: Added property allow-tabs.
+ * tests/mozilla/ecma_2/jsref.js: Modified property allow-tabs.
+ * tests/mozilla/ecma_2/shell.js: Added property allow-tabs.
+ * tests/mozilla/ecma_3/Date/shell.js: Modified property allow-tabs.
+ * tests/mozilla/ecma_3/Exceptions/regress-181654.js: Added property allow-tabs.
+ * tests/mozilla/ecma_3/RegExp/regress-209067.js: Added property allow-tabs.
+ * tests/mozilla/ecma_3/RegExp/regress-85721.js: Added property allow-tabs.
+ * tests/mozilla/importList.html: Added property allow-tabs.
+ * tests/mozilla/js1_1/shell.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/Array/general1.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/Array/general2.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/Array/slice.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/Array/splice1.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/Array/splice2.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/Objects/toString-001.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/String/charCodeAt.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/String/concat.js: Modified property allow-tabs.
+ * tests/mozilla/js1_2/String/match.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/String/slice.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/function/Function_object.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/function/Number.js: Modified property allow-tabs.
+ * tests/mozilla/js1_2/function/String.js: Modified property allow-tabs.
+ * tests/mozilla/js1_2/function/nesting.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/function/regexparg-1.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/function/regexparg-2-n.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/jsref.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/operator/equality.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/operator/strictEquality.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_dollar_number.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_input.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_input_as_array.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_lastIndex.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_lastMatch.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_lastMatch_as_array.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_lastParen.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_lastParen_as_array.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_leftContext.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_leftContext_as_array.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_multiline.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_multiline_as_array.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_object.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_rightContext.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/RegExp_rightContext_as_array.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/alphanumeric.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/asterisk.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/backslash.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/backspace.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/beginLine.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/character_class.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/compile.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/control_characters.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/digit.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/dot.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/endLine.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/everything.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/exec.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/flags.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/global.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/hexadecimal.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/ignoreCase.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/interval.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/octal.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/parentheses.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/plus.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/question_mark.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/simple_form.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/source.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/special_characters.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/string_replace.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/string_search.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/string_split.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/test.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/toString.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/vertical_bar.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/whitespace.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/regexp/word_boundary.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/shell.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/statements/break.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/statements/continue.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/statements/do_while.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/statements/switch.js: Added property allow-tabs.
+ * tests/mozilla/js1_2/statements/switch2.js: Added property allow-tabs.
+ * tests/mozilla/js1_3/shell.js: Added property allow-tabs.
+ * tests/mozilla/js1_4/shell.js: Added property allow-tabs.
+ * tests/mozilla/js1_5/Regress/regress-111557.js: Added property allow-tabs.
+ * tests/mozilla/js1_5/Regress/regress-216320.js: Added property allow-tabs.
+ * tests/mozilla/menuhead.html: Added property allow-tabs.
+ * tests/mozilla/mklistpage.pl: Added property allow-tabs.
+ * tests/mozilla/runtests.pl: Added property allow-tabs.
+
+2010-01-08 Daniel Bates <dbates@webkit.org>
+
+ Reviewed by Adam Barth.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33417
+
+ Cleans up style errors exposed by the patch for bug #33198.
+ Moreover, fixes all "Weird number of spaces at line-start. Are you using a 4-space indent?"
+ errors reported by check-webkit-style.
+
+ No functionality was changed. So, no new tests.
+
+ * wtf/Platform.h:
+
+2010-01-08 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Eric Seidel.
+
+ Don't store RegExp flags string representation
+ https://bugs.webkit.org/show_bug.cgi?id=33321
+
+ It's unused; the string representation is reconstructed from flags.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ * runtime/RegExp.h:
+
+2010-01-08 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Memory use grows grows possibly unbounded in this JavaScript Array test case
+ https://bugs.webkit.org/show_bug.cgi?id=31675
+
+ This fixes one observed bug in this test case, which is that
+ arrays don't report extra cost for the sparse value maps.
+
+ SunSpider reports a small speedup.
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::putSlowCase): Report extra memory cost for
+ the sparse value map.
+ * runtime/JSArray.h:
+
+2010-01-08 Yong Li <yoli@rim.com>
+
+ Reviewed by Darin Adler.
+
+ Remove unnecessary #include from FastMalloc.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=33393
+
+ * wtf/FastMalloc.cpp:
+
+2010-01-08 Eric Seidel <eric@webkit.org>
+
+ No review, rolling out r52983.
+ http://trac.webkit.org/changeset/52983
+ https://bugs.webkit.org/show_bug.cgi?id=33321
+
+ Broke 59 JavaScriptCore tests. I don't think Kent knew about
+ run-javascriptcore-tests. Sadly neither does the commit-bot,
+ yet.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ * runtime/RegExp.h:
+ (JSC::RegExp::flags):
+
+2010-01-08 Eric Seidel <eric@webkit.org>
+
+ No review, rolling out r52981.
+ http://trac.webkit.org/changeset/52981
+ https://bugs.webkit.org/show_bug.cgi?id=33319
+
+ Caused two JS tests to start failing:
+ ecma_2/RegExp/properties-001.js and js1_2/regexp/toString.js
+
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncToString):
+
+2010-01-08 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ Don't store RegExp flags string representation
+ https://bugs.webkit.org/show_bug.cgi?id=33321
+
+ It's unused; the string representation is reconstructed from flags.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ * runtime/RegExp.h:
+
+2010-01-08 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ RegExp.prototype.toString returns "//" for empty regular expressions
+ https://bugs.webkit.org/show_bug.cgi?id=33319
+
+ "//" starts a single-line comment, hence "/(?:)/" should be used, according to ECMA.
+
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncToString):
+
+2010-01-08 Norbert Leser <norbert.leser@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ RVCT compiler with "-Otime -O3" optimization tries to optimize out
+ inline new'ed pointers that are passed as arguments.
+ Proposed patch assigns new'ed pointer explicitly outside function call.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33084
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClass::OpaqueJSClass):
+ (OpaqueJSClassContextData::OpaqueJSClassContextData):
+
+2010-01-08 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Remove an unnecessary cacheFlush from ARM_TRADITIONAL JIT
+ https://bugs.webkit.org/show_bug.cgi?id=33203
+
+ * assembler/ARMAssembler.cpp: Remove obsolete linkBranch function.
+ (JSC::ARMAssembler::executableCopy): Inline a clean linkBranch code.
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::getLdrImmAddress): Use inline function.
+ (JSC::ARMAssembler::getLdrImmAddressOnPool): Ditto.
+ (JSC::ARMAssembler::patchPointerInternal): Remove an unnecessary cacheFlush.
+ (JSC::ARMAssembler::linkJump): Use patchPointerInternal instead of linkBranch.
+ (JSC::ARMAssembler::linkCall): Ditto.
+ (JSC::ARMAssembler::relinkCall): Ditto.
+
+2010-01-07 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Build fix for JSVALUE32 when ENABLE_JIT_OPTIMIZE* are disabled
+ https://bugs.webkit.org/show_bug.cgi?id=33311
+
+ Move compileGetDirectOffset function to common part of JSVALUE32
+
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetDirectOffset):
+
+2010-01-07 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Allow call sites to determine if ASSERT_* and LOG_* macros are operational
+ https://bugs.webkit.org/show_bug.cgi?id=33020
+
+ * wtf/Assertions.h: Set ASSERT_MSG_DISABLED, FATAL_DISABLED,
+ ERROR_DISABLED, LOG_DISABLED to 1 if the compiler does not support
+ variadic macros. Refactor for better readibility.
+
+2010-01-07 Daniel Bates <dbates@rim.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32987
+
+ Added ENABLE_XHTMLMP flag. Disabled by default.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2010-01-07 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Gavin Barraclough.
+
+ [Symbian] Port ARM traditional JIT Trampolines to RVCT
+ https://bugs.webkit.org/show_bug.cgi?id=30552
+
+ Take the GCC implementation and mechanically convert
+ it to RVCT syntax.
+
+ Use 'bx rX' instead of 'mov pc, rX' when it is available.
+
+ Developed in cooperation with Iain Campbell and Gabor Loki.
+
+ * JavaScriptCore.pri: Extra step to generate RVCT stubs. The
+ script generation intentionally executed all the time not just
+ for RVCT targets.
+
+ * create_rvct_stubs: Added. Perl script to expand precompiler macros
+ for RVCT assembler - the template is defined in JITStubs.cpp.
+
+ * jit/JITStubs.cpp:
+ (JSC::ctiTrampoline):
+ (JSC::ctiVMThrowTrampoline):
+ (JSC::ctiOpThrowNotCaught):
+
+2010-01-07 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix a crash seen on the buildbots.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init): Disable specific function tracking here,
+ instead of in WebCore, to ensure that the disabling happens before a
+ specific function can be registered.
+
+2010-01-07 Alexey Proskuryakov <ap@apple.com>
+
+ Mac build fix.
+
+ * JavaScriptCore.exp: Export new JSGlobalData static data members.
+
+2010-01-07 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33057
+ REGRESSION(r49365): typeof(xhr.responseText) != "string" in Windows
+
+ <rdar://problem/7296920> REGRESSION: WebKit fails to start PeaceKeeper benchmark
+
+ Test: fast/js/webcore-string-comparison.html
+
+ In r49365, some code was moved from JSString.cpp to JSString.h, and as a result, WebCore
+ got a way to directly instantiate JSStrings over DLL borders. Since vftable for JSString was
+ not exported, objects created from WebCore got a different vptr, and JavaScriptCore
+ optimizations that relied on vptr of all JSString objects being equal failed.
+
+ * config.h: Added a JS_EXPORTCLASS macro for exporting classes. It's currently the same as
+ JS_EXPORTDATA, but it clearly needed a new name.
+
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::storeVPtrs):
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::createNonDefault):
+ (JSC::JSGlobalData::create):
+ (JSC::JSGlobalData::sharedInstance):
+ * runtime/JSGlobalData.h:
+ Store vptrs just once, no need to repeatedly pick and copy them. This makes it possible to
+ assert vptr correctness in object destructors (which don't have access to JSGlobalData,
+ and even Heap::heap(this) will fail for fake objects created from storeVPtrs()).
+
+ * runtime/JSArray.cpp: (JSC::JSArray::~JSArray): Assert that vptr is what we expect it to be.
+ It's important to assert in destructor, because MSVC changes the vptr after constructor
+ is invoked.
+ * runtime/JSByteArray.cpp: (JSC::JSByteArray::~JSByteArray): Ditto.
+ * runtime/JSByteArray.h: Ditto.
+ * runtime/JSFunction.h: Ditto.
+ * runtime/JSFunction.cpp: (JSC::JSFunction::~JSFunction): Ditto.
+
+ * runtime/JSCell.h: (JSC::JSCell::setVPtr): Added a method to substitute vptr for another
+ one.
+
+ * runtime/JSString.h: Export JSString class together with its vftable, and tell other
+ libraries tp import it. This is needed on platforms that have a separate JavaScriptCore
+ dynamic library - and on Mac, we already did the export via JavaScriptCore.exp.
+ (JSC::JSString::~JSString): Assert tha vptr is what we expect it to be.
+ (JSC::fixupVPtr): Store a previously saved primary vftable pointer (do nothing if building
+ JavaScriptCore itself).
+ (JSC::jsSingleCharacterString): Call fixupVPtr in case this is call across DLL boundary.
+ (JSC::jsSingleCharacterSubstring): Ditto.
+ (JSC::jsNontrivialString): Ditto.
+ (JSC::jsString): Ditto.
+ (JSC::jsSubstring): Ditto.
+ (JSC::jsOwnedString): Ditto.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Export the new static
+ JSGlobalData members that are used in WebCore via inline functions.
+
+2010-01-07 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Safari memory usage skyrockets using new Google AdWords interface
+ https://bugs.webkit.org/show_bug.cgi?id=33343
+
+ The memory use was caused by the global object creating too many structures
+ as it thrashed between different specific functions.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::addAnonymousSlotsTransition):
+ (JSC::Structure::getterSetterTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::addPropertyWithoutTransition):
+ (JSC::Structure::despecifyAllFunctions):
+ * runtime/Structure.h:
+ (JSC::Structure::disableSpecificFunctionTracking): Track a thrash count
+ for specific functions. Disable specific function tracking once the
+ thrash count has been hit.
+
+2010-01-07 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Enable JIT in debug mode on win32 after r51141 fixed the crashes.
+
+ * JavaScriptCore.pri:
+
+2010-01-07 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Holger Freyther.
+
+ [Mac] Build fix when FAST_MALLOC_MATCH_VALIDATION=1
+ https://bugs.webkit.org/show_bug.cgi?id=33312
+
+ Using of operator += cause compile error on Mac, so it is changed to
+ "= static_cast<AllocAlignmentInteger*>(old_ptr) + 1".
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMallocStats::realloc):
+
+2010-01-07 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Holger Freyther.
+
+ [Qt] Build fix when FAST_MALLOC_MATCH_VALIDATION=1
+ https://bugs.webkit.org/show_bug.cgi?id=33312
+
+ Remove pByte (committed in r42344 from #20422), because pByte doesn't
+ exist and it is unnecessary.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMallocStats::realloc):
+
+2010-01-06 Gavin Barraclough <barraclough@apple.com>
+
+ QT build fix.
+
+ * runtime/Identifier.cpp:
+ (JSC::createIdentifierTableSpecific):
+
+2010-01-06 Gavin Barraclough <barraclough@apple.com>
+
+ Windows build fix part I.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-01-06 Dan Bernstein <mitz@apple.com>
+
+ Build fix
+
+ * runtime/Identifier.cpp:
+ (JSC::createIdentifierTableSpecificCallback):
+
+2010-01-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33236
+ Remove m_identifierTable pointer from UString
+
+ Currently every string holds a pointer so that during destruction,
+ if a string has been used as an identifier, it can remove itself
+ from the table. By instead accessing the identifierTable via a
+ thread specific tracking the table associated with the current
+ globaldata, we can save the memory cost of this pointer.
+
+ * API/APIShims.h:
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
+ (JSC::APICallbackShim::APICallbackShim):
+ (JSC::APICallbackShim::~APICallbackShim):
+
+ - change the API shims to track the identifierTable of the current JSGlobalData.
+
+ * API/JSContextRef.cpp:
+ (JSContextGroupCreate):
+
+ - update creation of JSGlobalData for API usage to use new create method.
+ - fix shim instanciation bug in JSGlobalContextCreateInGroup.
+
+ * JavaScriptCore.exp:
+ * runtime/Completion.cpp:
+ (JSC::checkSyntax):
+ (JSC::evaluate):
+
+ - add asserts to check the identifierTable is being tracked correctly.
+
+ * runtime/Identifier.cpp:
+ (JSC::IdentifierTable::~IdentifierTable):
+ (JSC::IdentifierTable::add):
+ (JSC::Identifier::remove):
+ (JSC::Identifier::checkSameIdentifierTable):
+ (JSC::createIdentifierTableSpecificCallback):
+ (JSC::createIdentifierTableSpecific):
+ (JSC::createDefaultDataSpecific):
+
+ - Use currentIdentifierTable() instead of UStringImpl::m_identifierTable.
+ - Define methods to access the thread specific identifier tables.
+
+ * runtime/Identifier.h:
+ (JSC::ThreadIdentifierTableData::ThreadIdentifierTableData):
+ (JSC::defaultIdentifierTable):
+ (JSC::setDefaultIdentifierTable):
+ (JSC::currentIdentifierTable):
+ (JSC::setCurrentIdentifierTable):
+ (JSC::resetCurrentIdentifierTable):
+
+ - Declare methods to access the thread specific identifier tables.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::createNonDefault):
+ (JSC::JSGlobalData::create):
+ (JSC::JSGlobalData::sharedInstance):
+
+ - creation of JSGlobalData objects, other than for API usage, associate themselves with the current thread.
+
+ * runtime/JSGlobalData.h:
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::destroy):
+
+ - destroy() method should be using isIdentifier().
+
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::isIdentifier):
+ (JSC::UStringImpl::setIsIdentifier):
+ (JSC::UStringImpl::checkConsistency):
+ (JSC::UStringImpl::UStringImpl):
+
+ - replace m_identifierTable with a single m_isIdentifier bit.
+
+ * wtf/StringHashFunctions.h:
+ (WTF::stringHash):
+
+ - change string hash result from 32-bit to 31-bit, to free a bit in UStringImpl for m_isIdentifier.
+
+2009-12-25 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Eric Seidel.
+
+ Buildfix for WinCE + style fixes.
+ https://bugs.webkit.org/show_bug.cgi?id=32939
+
+ * jsc.cpp:
+ (functionPrint):
+ (functionQuit):
+ (parseArguments):
+ (fillBufferWithContentsOfFile):
+
+2010-01-05 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Eric Seidel.
+
+ WinCE buildfix after r52791 (renamed PLATFORM(WINCE) to OS(WINCE)).
+ https://bugs.webkit.org/show_bug.cgi?id=33205
+
+ * jit/ExecutableAllocator.h:
+
+2010-01-05 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Darin Adler.
+
+ Added compiler error for unsupported platforms.
+ https://bugs.webkit.org/show_bug.cgi?id=33112
+
+ * jit/JITStubs.cpp:
+
+2010-01-05 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Maciej Stachowiak.
+
+ Follow r52729 in ARMAssembler.
+ https://bugs.webkit.org/show_bug.cgi?id=33208
+
+ Use WTF_ARM_ARCH_AT_LEAST instead of ARM_ARCH_VERSION
+
+ * assembler/ARMAssembler.cpp:
+ (JSC::ARMAssembler::encodeComplexImm): Move tmp declaration to ARMv7
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::):
+ (JSC::ARMAssembler::bkpt):
+
+2010-01-05 Maciej Stachowiak <mjs@apple.com>
+
+ Unreviewed build fix for Gtk+
+
+ Don't use // comments in Platform.h, at least some of them seem to make the version of GCC
+ used on the Gtk buildbot unhappy.
+
+ * wtf/Platform.h:
+
+2010-01-04 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Darin Fisher.
+
+ Reorganize, document and rename OS() platform macros.
+ https://bugs.webkit.org/show_bug.cgi?id=33198
+
+ * wtf/Platform.h: Rename, reorganize and document OS() macros.
+
+ Adapt to name changes. Also fixed a few incorrect OS checks.
+
+ * API/JSContextRef.cpp:
+ * assembler/MacroAssemblerARM.cpp:
+ (JSC::isVFPPresent):
+ * assembler/MacroAssemblerX86Common.h:
+ * bytecode/SamplingTool.cpp:
+ * config.h:
+ * interpreter/RegisterFile.cpp:
+ (JSC::RegisterFile::~RegisterFile):
+ * interpreter/RegisterFile.h:
+ (JSC::RegisterFile::RegisterFile):
+ (JSC::RegisterFile::grow):
+ * jit/ExecutableAllocator.h:
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ * jit/ExecutableAllocatorPosix.cpp:
+ * jit/ExecutableAllocatorSymbian.cpp:
+ * jit/ExecutableAllocatorWin.cpp:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JITStubs.cpp:
+ * jsc.cpp:
+ (main):
+ * parser/Grammar.y:
+ * profiler/ProfileNode.cpp:
+ (JSC::getCount):
+ * runtime/Collector.cpp:
+ (JSC::Heap::Heap):
+ (JSC::Heap::allocateBlock):
+ (JSC::Heap::freeBlockPtr):
+ (JSC::currentThreadStackBase):
+ (JSC::getCurrentPlatformThread):
+ (JSC::suspendThread):
+ (JSC::resumeThread):
+ (JSC::getPlatformThreadRegisters):
+ (JSC::otherThreadStackPointer):
+ * runtime/Collector.h:
+ * runtime/DateConstructor.cpp:
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreading):
+ * runtime/MarkStack.h:
+ (JSC::MarkStack::MarkStackArray::shrinkAllocation):
+ * runtime/MarkStackPosix.cpp:
+ * runtime/MarkStackSymbian.cpp:
+ * runtime/MarkStackWin.cpp:
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncLastIndexOf):
+ * runtime/TimeoutChecker.cpp:
+ (JSC::getCPUTime):
+ * runtime/UString.cpp:
+ (JSC::UString::from):
+ * wtf/Assertions.cpp:
+ * wtf/Assertions.h:
+ * wtf/CurrentTime.cpp:
+ (WTF::lowResUTCTime):
+ * wtf/CurrentTime.h:
+ (WTF::getLocalTime):
+ * wtf/DateMath.cpp:
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMalloc_ThreadCache::InitModule):
+ (WTF::TCMallocStats::):
+ * wtf/FastMalloc.h:
+ * wtf/MathExtras.h:
+ * wtf/RandomNumber.cpp:
+ (WTF::randomNumber):
+ * wtf/RandomNumberSeed.h:
+ (WTF::initializeRandomNumberGenerator):
+ * wtf/StringExtras.h:
+ * wtf/TCSpinLock.h:
+ (TCMalloc_SpinLock::Unlock):
+ (TCMalloc_SlowLock):
+ * wtf/TCSystemAlloc.cpp:
+ * wtf/ThreadSpecific.h:
+ (WTF::::destroy):
+ * wtf/Threading.h:
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::initializeThreading):
+ (WTF::isMainThread):
+ * wtf/ThreadingWin.cpp:
+ (WTF::wtfThreadEntryPoint):
+ (WTF::createThreadInternal):
+ * wtf/VMTags.h:
+ * wtf/unicode/icu/CollatorICU.cpp:
+ (WTF::Collator::userDefault):
+ * wtf/win/MainThreadWin.cpp:
+ (WTF::initializeMainThreadPlatform):
+
+2010-01-04 Gustavo Noronha Silva <gns@gnome.org>
+
+ Add missing files to the build system - make distcheck build fix.
+
+ * GNUmakefile.am:
+
+2010-01-04 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig, additional coding by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33163
+ Add string hashing functions to WTF.
+ Use WTF's string hashing functions from UStringImpl.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/UStringImpl.cpp:
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::computeHash):
+ * wtf/HashFunctions.h:
+ * wtf/StringHashFunctions.h: Added.
+ (WTF::stringHash):
+
+2010-01-04 Dmitry Titov <dimich@chromium.org>
+
+ Not reviewed, attempt to fix ARM bulid.
+
+ * wtf/Platform.h:
+
+2010-01-04 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber stamped by Geoff Garen.
+
+ Add an 'isIdentifier' to UStringImpl, use this where appropriate
+ (where previously 'identifierTable' was being tested).
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClass::~OpaqueJSClass):
+ (OpaqueJSClassContextData::OpaqueJSClassContextData):
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::addSlowCase):
+ * runtime/Identifier.h:
+ (JSC::Identifier::add):
+ * runtime/PropertyNameArray.cpp:
+ (JSC::PropertyNameArray::add):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::isIdentifier):
+
+2010-01-04 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam "Shimmey Shimmey" Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=33158
+ Refactor JSC API entry/exit to use RAII instead of copy/pasting code.
+ Make it easier to change set of actions taken when passing across the API boundary.
+
+ * API/APIShims.h: Added.
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
+ (JSC::APIEntryShim::APIEntryShim):
+ (JSC::APICallbackShim::APICallbackShim):
+ (JSC::APICallbackShim::~APICallbackShim):
+ * API/JSBase.cpp:
+ (JSEvaluateScript):
+ (JSCheckScriptSyntax):
+ (JSGarbageCollect):
+ (JSReportExtraMemoryCost):
+ * API/JSCallbackConstructor.cpp:
+ (JSC::constructJSCallback):
+ * API/JSCallbackFunction.cpp:
+ (JSC::JSCallbackFunction::call):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::init):
+ (JSC::::getOwnPropertySlot):
+ (JSC::::put):
+ (JSC::::deleteProperty):
+ (JSC::::construct):
+ (JSC::::hasInstance):
+ (JSC::::call):
+ (JSC::::getOwnPropertyNames):
+ (JSC::::toNumber):
+ (JSC::::toString):
+ (JSC::::staticValueGetter):
+ (JSC::::callbackGetter):
+ * API/JSContextRef.cpp:
+ * API/JSObjectRef.cpp:
+ (JSObjectMake):
+ (JSObjectMakeFunctionWithCallback):
+ (JSObjectMakeConstructor):
+ (JSObjectMakeFunction):
+ (JSObjectMakeArray):
+ (JSObjectMakeDate):
+ (JSObjectMakeError):
+ (JSObjectMakeRegExp):
+ (JSObjectGetPrototype):
+ (JSObjectSetPrototype):
+ (JSObjectHasProperty):
+ (JSObjectGetProperty):
+ (JSObjectSetProperty):
+ (JSObjectGetPropertyAtIndex):
+ (JSObjectSetPropertyAtIndex):
+ (JSObjectDeleteProperty):
+ (JSObjectCallAsFunction):
+ (JSObjectCallAsConstructor):
+ (JSObjectCopyPropertyNames):
+ (JSPropertyNameArrayRelease):
+ (JSPropertyNameAccumulatorAddName):
+ * API/JSValueRef.cpp:
+ (JSValueGetType):
+ (JSValueIsUndefined):
+ (JSValueIsNull):
+ (JSValueIsBoolean):
+ (JSValueIsNumber):
+ (JSValueIsString):
+ (JSValueIsObject):
+ (JSValueIsObjectOfClass):
+ (JSValueIsEqual):
+ (JSValueIsStrictEqual):
+ (JSValueIsInstanceOfConstructor):
+ (JSValueMakeUndefined):
+ (JSValueMakeNull):
+ (JSValueMakeBoolean):
+ (JSValueMakeNumber):
+ (JSValueMakeString):
+ (JSValueToBoolean):
+ (JSValueToNumber):
+ (JSValueToStringCopy):
+ (JSValueToObject):
+ (JSValueProtect):
+ (JSValueUnprotect):
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2010-01-04 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Ada Chan and Mark Rowe.
+
+ Updated copyright string
+
+ * Info.plist:
+ * JavaScriptCore.vcproj/JavaScriptCore.resources/Info.plist:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc:
+
+2010-01-04 Adam Roben <aroben@apple.com>
+
+ No review, rolling out r52741.
+ http://trac.webkit.org/changeset/52741
+ https://bugs.webkit.org/show_bug.cgi?id=33056
+
+ * wtf/AlwaysInline.h:
+
+2010-01-04 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Darin Adler.
+
+ Add cacheFlush support for WinCE
+ https://bugs.webkit.org/show_bug.cgi?id=33110
+
+ * jit/ExecutableAllocator.h:
+ (JSC::ExecutableAllocator::cacheFlush):
+
+2010-01-04 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Adam Roben.
+
+ Implement NO_RETURN for COMPILER(MSVC).
+ https://bugs.webkit.org/show_bug.cgi?id=33056
+
+ * wtf/AlwaysInline.h:
+
+2010-01-04 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix some PLATFORM(*_ENDIAN) uses to CPU()
+ https://bugs.webkit.org/show_bug.cgi?id=33148
+
+ * runtime/JSCell.cpp:
+ (JSC::):
+ * runtime/JSValue.h:
+ (JSC::JSValue::):
+
+2010-01-04 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Document CPU() macros in comments.
+ https://bugs.webkit.org/show_bug.cgi?id=33147
+
+ * wtf/Platform.h:
+
+2010-01-04 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Reorganize, document and rename CPU() platform macros.
+ https://bugs.webkit.org/show_bug.cgi?id=33145
+ ExecutableAllocatorSymbian appears to have buggy ARM version check
+ https://bugs.webkit.org/show_bug.cgi?id=33138
+
+ * wtf/Platform.h:
+ Rename all macros related to detection of particular CPUs or
+ classes of CPUs to CPU(), reorganize and document them.
+
+ All remaining changes are adapting to the renames, plus fixing the
+ second bug cited above.
+
+ * assembler/ARMAssembler.cpp:
+ * assembler/ARMAssembler.h:
+ * assembler/ARMv7Assembler.h:
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::Imm32::Imm32):
+ * assembler/MacroAssembler.h:
+ * assembler/MacroAssemblerARM.cpp:
+ * assembler/MacroAssemblerARM.h:
+ * assembler/MacroAssemblerCodeRef.h:
+ (JSC::MacroAssemblerCodePtr::MacroAssemblerCodePtr):
+ * assembler/MacroAssemblerX86.h:
+ * assembler/MacroAssemblerX86Common.h:
+ * assembler/MacroAssemblerX86_64.h:
+ * assembler/X86Assembler.h:
+ (JSC::X86Registers::):
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::movl_mEAX):
+ (JSC::X86Assembler::movl_EAXm):
+ (JSC::X86Assembler::repatchLoadPtrToLEA):
+ (JSC::X86Assembler::X86InstructionFormatter::memoryModRM):
+ * jit/ExecutableAllocator.h:
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ * jit/ExecutableAllocatorPosix.cpp:
+ * jit/ExecutableAllocatorSymbian.cpp:
+ (JSC::ExecutableAllocator::intializePageSize):
+ * jit/JIT.cpp:
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::beginUninterruptedSequence):
+ (JSC::JIT::restoreArgumentReferenceForTrampoline):
+ (JSC::JIT::emitCount):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::JITThunks):
+ * jit/JITStubs.h:
+ * runtime/Collector.cpp:
+ (JSC::currentThreadStackBase):
+ (JSC::getPlatformThreadRegisters):
+ (JSC::otherThreadStackPointer):
+ * wrec/WREC.h:
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateEnter):
+ (JSC::WREC::Generator::generateReturnSuccess):
+ (JSC::WREC::Generator::generateReturnFailure):
+ * wrec/WRECGenerator.h:
+ * wtf/FastMalloc.cpp:
+ * wtf/TCSpinLock.h:
+ (TCMalloc_SpinLock::Lock):
+ (TCMalloc_SpinLock::Unlock):
+ (TCMalloc_SlowLock):
+ * wtf/Threading.h:
+ * wtf/dtoa.cpp:
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::generateEnter):
+ (JSC::Yarr::RegexGenerator::generateReturn):
+ * yarr/RegexJIT.h:
+
+2010-01-04 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Adam Barth.
+
+ Clean up COMPILER macros and remove unused ones.
+ https://bugs.webkit.org/show_bug.cgi?id=33132
+
+ Removed values are COMPILER(BORLAND) and COMPILER(CYGWIN) - they were
+ not used anywhere.
+
+ * wtf/Platform.h:
+
+2010-01-03 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Eric Seidel.
+
+ Update wtf/Platform.h to document the new system for porting macros.
+ https://bugs.webkit.org/show_bug.cgi?id=33130
+
+ * wtf/Platform.h:
+
+2009-12-29 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ PLATFORM(CAIRO) should be defined by WIN_CAIRO define
+ https://bugs.webkit.org/show_bug.cgi?id=22250
+
+ * wtf/Platform.h: Define WTF_PLATFORM_CAIRO for GTK port only
+ For the WinCairo port WTF_PLATFORM_CAIRO is already defined in config.h
+
+2009-12-28 Shu Chang <Chang.Shu@nokia.com>
+
+ Reviewed by Laszlo Gombos.
+
+ [Qt] Delete ThreadPrivate instance after it is finished.
+ https://bugs.webkit.org/show_bug.cgi?id=32614
+
+ * wtf/qt/ThreadingQt.cpp:
+ (WTF::ThreadMonitor::instance):
+ (WTF::ThreadMonitor::threadFinished):
+ (WTF::createThreadInternal):
+ (WTF::detachThread):
+
+2009-12-28 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Cleanup of #define JS_EXPORT.
+
+ * API/JSBase.h:
+
+2009-12-27 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Adam Barth.
+
+ WinCE buildfix (HWND_MESSAGE isn't supported there)
+
+ * wtf/win/MainThreadWin.cpp:
+ (WTF::initializeMainThreadPlatform):
+
+2009-12-27 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Adam Barth.
+
+ Added a file with WinMain function to link agains in WinCE.
+
+ * os-win32/WinMain.cpp: Added.
+ (convertToUtf8):
+ (WinMain):
+
+2009-12-24 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Unreviewed; revert of r52550.
+
+ The change regressed the following LayoutTests for QtWebKit.
+
+ fast/workers/worker-call.html -> crashed
+ fast/workers/worker-close.html -> crashed
+
+ * wtf/qt/ThreadingQt.cpp:
+ (WTF::waitForThreadCompletion):
+ (WTF::detachThread):
+
+2009-12-24 Shu Chang <Chang.Shu@nokia.com>
+
+ Reviewed by Laszlo Gombos.
+
+ [Qt] Fix memory leak by deleting instance of ThreadPrivate
+ in function waitForThreadCompletion(), synchronously, or in
+ detachThread(), asynchronously.
+ https://bugs.webkit.org/show_bug.cgi?id=32614
+
+ * wtf/qt/ThreadingQt.cpp:
+ (WTF::waitForThreadCompletion):
+ (WTF::detachThread):
+
+2009-12-23 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Laszlo Gombos.
+
+ Include stddef.h for ptrdiff_t
+ https://bugs.webkit.org/show_bug.cgi?id=32891
+
+ ptrdiff_t is typedef-ed in stddef.h.
+ Include stddef.h in jit/ExecutableAllocator.h.
+
+ * jit/ExecutableAllocator.h:
+
+2009-12-23 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Eric Seidel.
+
+ Buildfix after r47092.
+
+ * wtf/wince/MemoryManager.cpp:
+ (WTF::tryFastMalloc):
+ (WTF::tryFastZeroedMalloc):
+ (WTF::tryFastCalloc):
+ (WTF::tryFastRealloc):
+
+2009-12-23 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ HTMLInputElement::valueAsDate getter support.
+ https://bugs.webkit.org/show_bug.cgi?id=32876
+
+ Expose dateToDaysFrom1970().
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * wtf/DateMath.cpp:
+ (WTF::dateToDaysFrom1970):
+ * wtf/DateMath.h:
+
+2009-12-22 Darin Adler <darin@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Turn off datagrid by default, at least for all platforms Apple ships.
+ The datagrid implementation isn't ready for general web use yet.
+
+ * Configurations/FeatureDefines.xcconfig: Turn off datagrid by default.
+
+2009-12-22 Steve Block <steveblock@google.com>
+
+ Reviewed by David Levin.
+
+ Updates Android's scheduleDispatchFunctionsOnMainThread() to use new
+ AndroidThreading class, rather than using JavaSharedClient directly.
+ This fixes the current layering violation.
+ https://bugs.webkit.org/show_bug.cgi?id=32651
+
+ The pattern is copied from Chromium, which uses the ChromiumThreading
+ class. This patch also fixes the style in ChromiumThreading.h.
+
+ * wtf/android/AndroidThreading.h: Added. Declares AndroidThreading.
+ * wtf/android/MainThreadAndroid.cpp: Modified
+ (WTF::scheduleDispatchFunctionsOnMainThread): Uses AndroidThreading.
+ * wtf/chromium/ChromiumThreading.h: Modified. Fixes style.
+
+2009-12-22 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix a couple of problems with UntypedPtrAndBitfield.
+
+ Add a m_leaksPtr to reduce false positives from leaks in debug builds
+ (this isn't perfect because we'd like a solution for release builds,
+ but this is now at least as good as a PtrAndFlags would be).
+
+ Switch SmallStringsto use a regular string for the base, rather than
+ a static one. UntypedPtrAndBitfield assumes all strings are at least
+ 8 byte aligned; this migt not be true of static strings. Shared buffers
+ are heap allocated, as are all UStringImpls other than static strings.
+ Static strings cannot end up being the owner string of substrings,
+ since the only static strings are length 0.
+
+ * runtime/SmallStrings.cpp:
+ (JSC::SmallStringsStorage::SmallStringsStorage):
+ * runtime/UStringImpl.h:
+ (JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield):
+ (JSC::UStringImpl::UStringImpl):
+
+2009-12-22 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Darin Adler.
+
+ RVCT (__ARMCC_VERSION < 400000) does not provide strcasecmp and strncasecmp
+ https://bugs.webkit.org/show_bug.cgi?id=32857
+
+ Add implementation of strcasecmp and strncasecmp for RVCT < 4.0
+ because earlier versions of RVCT 4.0 does not provide these functions.
+
+ * wtf/StringExtras.cpp: Added.
+ (strcasecmp):
+ (strncasecmp):
+ * wtf/StringExtras.h:
+
+2009-12-22 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Darin Adler.
+
+ Define ALWAYS_INLINE and WTF_PRIVATE_INLINE to __forceinline for RVCT
+ https://bugs.webkit.org/show_bug.cgi?id=32853
+
+ Use __forceinline forces RVCT to compile a C or C++ function
+ inline. The compiler attempts to inline the function, regardless of
+ the characteristics of the function.
+
+ * wtf/AlwaysInline.h:
+ * wtf/FastMalloc.h:
+
+2009-12-21 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Prospective GTK build fix: Add UStringImpl.cpp/h to the build.
+
+ * GNUmakefile.am:
+
+2009-12-21 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Fix the Qt build, add UStringImpl.cpp to the build.
+
+ * JavaScriptCore.pri:
+
+2009-12-21 Gavin Barraclough <barraclough@apple.com>
+
+ Windows Build fix part 5.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2009-12-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (build fix).
+ Fix breakage of world introduced in build fix to r52463.
+
+ * runtime/UStringImpl.h:
+
+2009-12-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32831
+ Replace UString::Rep implementation, following introduction of ropes to JSC.
+
+ * Remove redundant overcapacity mechanisms.
+ * Reduce memory cost of Rep's.
+ * Add an inline storage mechanism akin to that in WebCore's StringImpl.
+
+ ~1% Sunspider progression.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope):
+ * runtime/SmallStrings.cpp:
+ (JSC::SmallStringsStorage::SmallStringsStorage):
+ * runtime/UString.cpp:
+ (JSC::initializeUString):
+ (JSC::createRep):
+ (JSC::UString::createFromUTF8):
+ (JSC::UString::createUninitialized):
+ (JSC::UString::spliceSubstringsWithSeparators):
+ (JSC::UString::replaceRange):
+ (JSC::UString::ascii):
+ (JSC::UString::operator=):
+ (JSC::UString::toStrictUInt32):
+ (JSC::equal):
+ * runtime/UString.h:
+ (JSC::UString::isEmpty):
+ (JSC::UString::cost):
+ (JSC::makeString):
+ * runtime/UStringImpl.cpp: Added.
+ (JSC::UStringImpl::baseSharedBuffer):
+ (JSC::UStringImpl::sharedBuffer):
+ (JSC::UStringImpl::destroy):
+ (JSC::UStringImpl::computeHash):
+ * runtime/UStringImpl.h: Added.
+ (JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield):
+ (JSC::UntypedPtrAndBitfield::asPtr):
+ (JSC::UntypedPtrAndBitfield::operator&=):
+ (JSC::UntypedPtrAndBitfield::operator|=):
+ (JSC::UntypedPtrAndBitfield::operator&):
+ (JSC::UStringImpl::create):
+ (JSC::UStringImpl::createCopying):
+ (JSC::UStringImpl::createUninitialized):
+ (JSC::UStringImpl::data):
+ (JSC::UStringImpl::size):
+ (JSC::UStringImpl::cost):
+ (JSC::UStringImpl::hash):
+ (JSC::UStringImpl::computedHash):
+ (JSC::UStringImpl::setHash):
+ (JSC::UStringImpl::identifierTable):
+ (JSC::UStringImpl::setIdentifierTable):
+ (JSC::UStringImpl::ref):
+ (JSC::UStringImpl::deref):
+ (JSC::UStringImpl::allocChars):
+ (JSC::UStringImpl::copyChars):
+ (JSC::UStringImpl::computeHash):
+ (JSC::UStringImpl::null):
+ (JSC::UStringImpl::empty):
+ (JSC::UStringImpl::checkConsistency):
+ (JSC::UStringImpl::):
+ (JSC::UStringImpl::UStringImpl):
+ (JSC::UStringImpl::operator new):
+ (JSC::UStringImpl::bufferOwnerString):
+ (JSC::UStringImpl::bufferOwnership):
+ (JSC::UStringImpl::isStatic):
+
+2009-12-18 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Move some build decisions from Qt build system into source files
+ https://bugs.webkit.org/show_bug.cgi?id=31956
+
+ * JavaScriptCore.pri: Compile files unconditionally
+ * jit/ExecutableAllocatorPosix.cpp: Guard with PLATFORM(UNIX) && !PLATFORM(SYMBIAN)
+ * jit/ExecutableAllocatorWin.cpp: Guard with PLATFORM(WIN_OS)
+ * runtime/MarkStackPosix.cpp: Guard with PLATFORM(UNIX) && !PLATFORM(SYMBIAN)
+ * runtime/MarkStackSymbian.cpp: Guard with PLATFORM(SYMBIAN)
+ * runtime/MarkStackWin.cpp: Guard with PLATFORM(WIN_OS)
+ * wtf/Platform.h: Guard ENABLE_JSC_MULTIPLE_THREADS with ENABLE_SINGLE_THREADED for the Qt port
+ * wtf/ThreadingNone.cpp: Guard with ENABLE(SINGLE_THREADED)
+ * wtf/qt/ThreadingQt.cpp: Guard with !ENABLE(SINGLE_THREADED)
+
+2009-12-18 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Add createNonCopying method to UString to make replace constructor passed bool,
+ to make behaviour more explicit. Add createFromUTF8 to UString (wrapping method
+ on UString::Rep), since other cases of transliteration (e.g. from ascii) are
+ performed in UString constructors. Add/use setHash & size() accessors on Rep,
+ rather than accessing _hash/len directly.
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClass::OpaqueJSClass):
+ * API/OpaqueJSString.cpp:
+ (OpaqueJSString::ustring):
+ * JavaScriptCore.exp:
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToString):
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::equal):
+ (JSC::CStringTranslator::translate):
+ (JSC::UCharBufferTranslator::translate):
+ (JSC::Identifier::addSlowCase):
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope):
+ * runtime/JSString.h:
+ (JSC::JSString::Rope::Fiber::refAndGetLength):
+ (JSC::JSString::Rope::append):
+ * runtime/StringBuilder.h:
+ (JSC::StringBuilder::release):
+ * runtime/StringConstructor.cpp:
+ (JSC::stringFromCharCodeSlowCase):
+ * runtime/StringPrototype.cpp:
+ (JSC::substituteBackreferencesSlow):
+ (JSC::stringProtoFuncToLowerCase):
+ (JSC::stringProtoFuncToUpperCase):
+ (JSC::stringProtoFuncFontsize):
+ (JSC::stringProtoFuncLink):
+ * runtime/UString.cpp:
+ (JSC::UString::UString):
+ (JSC::UString::createNonCopying):
+ (JSC::UString::createFromUTF8):
+ * runtime/UString.h:
+ (JSC::UString::Rep::setHash):
+ (JSC::UString::~UString):
+ (JSC::makeString):
+
+2009-12-18 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Cameron Zwarich and Gavin Barraclough.
+
+ Changed Register constructors to assignment operators, to streamline
+ moving values into registers. (In theory, there's no difference between
+ the two, since the constructor should just inline away, but there seems
+ to be a big difference in the addled mind of the GCC optimizer.)
+
+ In the interpreter, this is a 3.5% SunSpider speedup and a 1K-2K
+ reduction in stack usage per privateExecute stack frame.
+
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::setCalleeArguments):
+ (JSC::ExecState::setCallerFrame):
+ (JSC::ExecState::setScopeChain):
+ (JSC::ExecState::init):
+ (JSC::ExecState::setArgumentCount):
+ (JSC::ExecState::setCallee):
+ (JSC::ExecState::setCodeBlock): Added a little bit of casting so these
+ functions could use the new Register assignment operators.
+
+ * interpreter/Register.h:
+ (JSC::Register::withInt):
+ (JSC::Register::Register):
+ (JSC::Register::operator=): Swapped in assignment operators for constructors.
+
+2009-12-18 Yongjun Zhang <yongjun.zhang@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32713
+ [Qt] make wtf/Assertions.h compile in winscw compiler.
+
+ Add string arg before ellipsis to help winscw compiler resolve variadic
+ macro definitions in wtf/Assertions.h.
+
+ * wtf/Assertions.h:
+
+2009-12-18 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Adam Roben.
+
+ Fixed intermittent failure seen on Windows buildbot, and in other JSC
+ API clients.
+
+ Added a WeakGCPtr class and changed OpaqueJSClass::cachedPrototype to
+ use it, to avoid vending a stale object as a prototype.
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClassContextData::OpaqueJSClassContextData):
+ (OpaqueJSClass::prototype):
+ * API/JSClassRef.h: Use WeakGCPtr.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/WeakGCPtr.h: Added.
+ (JSC::WeakGCPtr::WeakGCPtr):
+ (JSC::WeakGCPtr::get):
+ (JSC::WeakGCPtr::clear):
+ (JSC::WeakGCPtr::operator*):
+ (JSC::WeakGCPtr::operator->):
+ (JSC::WeakGCPtr::operator!):
+ (JSC::WeakGCPtr::operator bool):
+ (JSC::WeakGCPtr::operator UnspecifiedBoolType):
+ (JSC::WeakGCPtr::assign):
+ (JSC::::operator):
+ (JSC::operator==):
+ (JSC::operator!=):
+ (JSC::static_pointer_cast):
+ (JSC::const_pointer_cast):
+ (JSC::getPtr): Added WeakGCPtr to the project.
+
+2009-12-18 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32720
+
+ * JavaScriptCore.exp:
+ - Remove exports for UString::append
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ - Make StringBuilder a private header (was project).
+
+2009-12-18 Martin Robinson <martin.james.robinson@gmail.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] GRefPtr does not take a reference when assigned a raw pointer
+ https://bugs.webkit.org/show_bug.cgi?id=32709
+
+ Ensure that when assigning a raw pointer to a GRefPtr, the reference
+ count is incremented. Also remove the GRefPtr conversion overload as
+ GRefPtr types have necessarily incompatible reference counting.
+
+ * wtf/gtk/GRefPtr.h:
+ (WTF::GRefPtr::operator=):
+
+2009-12-18 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ [Qt] Clean up the qmake build system to distinguish between trunk builds and package builds
+
+ https://bugs.webkit.org/show_bug.cgi?id=32716
+
+ * pcre/pcre.pri: Use standalone_package instead of QTDIR_build
+
+2009-12-18 Martin Robinson <martin.james.robinson@gmail.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] Compile warning from line 29 of GRefPtr.cpp
+ https://bugs.webkit.org/show_bug.cgi?id=32703
+
+ Fix memory leak and compiler warning in GRefPtr GHashTable template
+ specialization.
+
+ * wtf/gtk/GRefPtr.cpp:
+ (WTF::refGPtr):
+
+2009-12-17 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ Add BUILDING_ON_SNOW_LEOPARD and TARGETING_SNOW_LEOPARD #defines.
+
+ * wtf/Platform.h:
+
+2009-12-17 Adam Roben <aroben@apple.com>
+
+ Sync JavaScriptCore.vcproj with JavaScriptCore.xcodeproj and the
+ source tree
+
+ Fixes <http://webkit.org/b/32665>.
+
+ Reviewed by Ada Chan.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Moved
+ around files and filters so that the structure matches
+ JavaScriptCore.xcodeproj and the source tree. A few headers that were
+ previously omitted have been added, as well as JSZombie.{cpp,h}.
+
+2009-12-17 Adam Roben <aroben@apple.com>
+
+ Remove HeavyProfile and TreeProfile completely
+
+ These were mostly removed in r42808, but the empty files were left in
+ place.
+
+ Fixes <http://webkit.org/b/32664>.
+
+ Reviewed by John Sullivan.
+
+ * Android.mk:
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCoreSources.bkl:
+ Removed HeavyProfile/TreeProfile source files.
+
+ * profiler/HeavyProfile.cpp: Removed.
+ * profiler/HeavyProfile.h: Removed.
+ * profiler/TreeProfile.cpp: Removed.
+ * profiler/TreeProfile.h: Removed.
+
+2009-12-17 Martin Robinson <martin.james.robinson@gmail.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ [GTK] WebKit GTK needs a wrapper for ref counted glib/gobject structs
+ https://bugs.webkit.org/show_bug.cgi?id=21599
+
+ Implement GRefPtr, a smart pointer for reference counted GObject types.
+
+ * GNUmakefile.am:
+ * wtf/gtk/GOwnPtr.cpp:
+ (WTF::GDir):
+ * wtf/gtk/GRefPtr.h: Added.
+ (WTF::):
+ (WTF::GRefPtr::GRefPtr):
+ (WTF::GRefPtr::~GRefPtr):
+ (WTF::GRefPtr::clear):
+ (WTF::GRefPtr::get):
+ (WTF::GRefPtr::operator*):
+ (WTF::GRefPtr::operator->):
+ (WTF::GRefPtr::operator!):
+ (WTF::GRefPtr::operator UnspecifiedBoolType):
+ (WTF::GRefPtr::hashTableDeletedValue):
+ (WTF::::operator):
+ (WTF::::swap):
+ (WTF::swap):
+ (WTF::operator==):
+ (WTF::operator!=):
+ (WTF::static_pointer_cast):
+ (WTF::const_pointer_cast):
+ (WTF::getPtr):
+ (WTF::adoptGRef):
+ (WTF::refGPtr):
+ (WTF::derefGPtr):
+
+2009-12-17 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
+
+ Unreviewed. Build fixes for make distcheck.
+
+ * GNUmakefile.am:
+
+2009-12-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fixed <rdar://problem/7355025> Interpreter::privateExecute macro generates
+ bloated code
+
+ This patch cuts Interpreter stack use by about a third.
+
+ * bytecode/Opcode.h: Changed Opcode to const void* to work with the
+ const static initiliazation we want to do in Interpreter::privateExecute.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::Interpreter): Moved hashtable initialization here to
+ avoid polluting Interpreter::privateExecute's stack, and changed it from a
+ series of add() calls to one add() call in a loop, to cut down on code size.
+
+ (JSC::Interpreter::privateExecute): Changed a series of label computations
+ to a copy of a compile-time constant array to cut down on code size.
+
+2009-12-16 Mark Rowe <mrowe@apple.com>
+
+ Build fix. Disable debug variants of WebKit frameworks.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2009-12-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam "r=me" Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32498
+ <rdar://problem/7471495>
+ REGRESSION(r51978-r52039): AJAX "Mark This Forum Read" function no longer
+ works
+
+ Fixed a tyop.
+
+ * runtime/Operations.h:
+ (JSC::jsAdd): Use the '&&' operator, not the ',' operator.
+
+2009-12-15 Geoffrey Garen <ggaren@apple.com>
+
+ Try to fix the windows build: don't export this inlined function.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2009-12-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Beth Dakin.
+
+ Inlined JSCell's operator new.
+
+ 3.7% speedup on bench-allocate-nonretained.js.
+
+ * JavaScriptCore.exp:
+ * runtime/JSCell.cpp:
+ * runtime/JSCell.h:
+ (JSC::JSCell::operator new):
+
+2009-12-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Removed the number heap, replacing it with a one-item free list for
+ numbers, taking advantage of the fact that two number cells fit inside
+ the space for one regular cell, and number cells don't require destruction.
+
+ SunSpider says 1.6% faster in JSVALUE32 mode (the only mode that
+ heap-allocates numbers).
+
+ SunSpider says 1.1% faster in JSVALUE32_64 mode. v8 says 0.8% faster
+ in JSVALUE32_64 mode. 10% speedup on bench-alloc-nonretained.js. 6%
+ speedup on bench-alloc-retained.js.
+
+ There's a lot of formulaic change in this patch, but not much substance.
+
+ * JavaScriptCore.exp:
+ * debugger/Debugger.cpp:
+ (JSC::Debugger::recompileAllJSFunctions):
+ * runtime/Collector.cpp:
+ (JSC::Heap::Heap):
+ (JSC::Heap::destroy):
+ (JSC::Heap::allocateBlock):
+ (JSC::Heap::freeBlock):
+ (JSC::Heap::freeBlockPtr):
+ (JSC::Heap::freeBlocks):
+ (JSC::Heap::recordExtraCost):
+ (JSC::Heap::allocate):
+ (JSC::Heap::resizeBlocks):
+ (JSC::Heap::growBlocks):
+ (JSC::Heap::shrinkBlocks):
+ (JSC::Heap::markConservatively):
+ (JSC::Heap::clearMarkBits):
+ (JSC::Heap::markedCells):
+ (JSC::Heap::sweep):
+ (JSC::Heap::markRoots):
+ (JSC::Heap::objectCount):
+ (JSC::Heap::addToStatistics):
+ (JSC::Heap::statistics):
+ (JSC::Heap::isBusy):
+ (JSC::Heap::reset):
+ (JSC::Heap::collectAllGarbage):
+ (JSC::Heap::primaryHeapBegin):
+ (JSC::Heap::primaryHeapEnd):
+ * runtime/Collector.h:
+ (JSC::): Removed all code pertaining to the number heap, and changed all
+ heap template functions and classes to non-template functions and classes.
+
+ (JSC::Heap::allocateNumber): A new optimization to replace the number
+ heap: allocate half-sized number cells in pairs, returning the first
+ cell and caching the second cell for the next allocation.
+
+ * runtime/CollectorHeapIterator.h:
+ (JSC::LiveObjectIterator::LiveObjectIterator):
+ (JSC::LiveObjectIterator::operator++):
+ (JSC::DeadObjectIterator::DeadObjectIterator):
+ (JSC::DeadObjectIterator::operator++):
+ (JSC::ObjectIterator::ObjectIterator):
+ (JSC::ObjectIterator::operator++):
+ * runtime/JSCell.h:
+ (JSC::JSCell::isNumber): Removed all code pertaining to the number heap,
+ and changed all heap template functions and classes to non-template functions
+ and classes.
+
+2009-12-15 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Allow custom memory allocation control for WeakGCMap class
+ https://bugs.webkit.org/show_bug.cgi?id=32547
+
+ Inherits WeakGCMap from FastAllocBase because it is instantiated by
+ 'new' at: WebCore/dom/Document.cpp:512.
+
+ * runtime/WeakGCMap.h:
+
+2009-12-15 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Allow custom memory allocation control for dtoa's P5Node struct
+ https://bugs.webkit.org/show_bug.cgi?id=32544
+
+ Inherits P5Node struct from Noncopyable because it is instantiated by
+ 'new' at wtf/dtoa.cpp:588 and don't need to be copyable.
+
+ * wtf/dtoa.cpp:
+
+2009-12-14 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32524
+ REGRESSION(52084): fast/dom/prototypes.html failing two CSS tests
+
+ * wtf/StdLibExtras.h:
+ (WTF::bitCount): The original patch put the parentheses in the wrong
+ place, completely changing the calculation and making it almost always
+ wrong. Moved the parentheses around the '+' operation, like the original
+ compiler warning suggested.
+
+2009-12-14 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Unreviewed trivial buildfix.
+
+ Fix crosses initialization of usedPrimaryBlocks for JSValue32
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::markConservatively):
+
+2009-12-14 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Simon Hausmann.
+
+ GCC 4.3.x warning fixed. Suggested parantheses added.
+ warning: ../../../JavaScriptCore/wtf/StdLibExtras.h:77: warning: suggest parentheses around + or - in operand of &
+
+ * wtf/StdLibExtras.h:
+ (WTF::bitCount):
+
+2009-12-13 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Changed GC from mark-sweep to mark-allocate.
+
+ Added WeakGCMap to keep WebCore blissfully ignorant about objects that
+ have become garbage but haven't run their destructors yet.
+
+ 1% SunSpider speedup.
+ 7.6% v8 speedup (37% splay speedup).
+ 17% speedup on bench-alloc-nonretained.js.
+ 18% speedup on bench-alloc-retained.js.
+
+ * API/JSBase.cpp:
+ (JSGarbageCollect):
+ * API/JSContextRef.cpp:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj: Updated for renames and new
+ files.
+
+ * debugger/Debugger.cpp:
+ (JSC::Debugger::recompileAllJSFunctions): Updated to use the Collector
+ iterator abstraction.
+
+ * jsc.cpp:
+ (functionGC): Updated for rename.
+
+ * runtime/Collector.cpp: Slightly reduced the number of allocations per
+ collection, so that small workloads only allocate on collector block,
+ rather than two.
+
+ (JSC::Heap::Heap): Updated to use the new allocateBlock function.
+
+ (JSC::Heap::destroy): Updated to use the new freeBlocks function.
+
+ (JSC::Heap::allocateBlock): New function to initialize a block when
+ allocating it.
+
+ (JSC::Heap::freeBlock): Consolidated the responsibility for running
+ destructors into this function.
+
+ (JSC::Heap::freeBlocks): Updated to use freeBlock.
+
+ (JSC::Heap::recordExtraCost): Sweep the heap in this reporting function,
+ so that allocation, which is more common, doesn't have to check extraCost.
+
+ (JSC::Heap::heapAllocate): Run destructors right before recycling a
+ garbage cell. This has better cache utilization than a separate sweep phase.
+
+ (JSC::Heap::resizeBlocks):
+ (JSC::Heap::growBlocks):
+ (JSC::Heap::shrinkBlocks): New set of functions for managing the size of
+ the heap, now that the heap doesn't maintain any information about its
+ size.
+
+ (JSC::isPointerAligned):
+ (JSC::isHalfCellAligned):
+ (JSC::isPossibleCell):
+ (JSC::isCellAligned):
+ (JSC::Heap::markConservatively): Cleaned up this code a bit.
+
+ (JSC::Heap::clearMarkBits):
+ (JSC::Heap::markedCells): Some helper functions for examining the the mark
+ bitmap.
+
+ (JSC::Heap::sweep): Simplified this function by using a DeadObjectIterator.
+
+ (JSC::Heap::markRoots): Reordered some operations for clarity.
+
+ (JSC::Heap::objectCount):
+ (JSC::Heap::addToStatistics):
+ (JSC::Heap::statistics): Rewrote these functions to calculate an object
+ count on demand, since the heap doesn't maintain this information by
+ itself.
+
+ (JSC::Heap::reset): New function for resetting the heap once we've
+ exhausted heap space.
+
+ (JSC::Heap::collectAllGarbage): This function matches the old collect()
+ behavior, but it's now an uncommon function used only by API.
+
+ * runtime/Collector.h:
+ (JSC::CollectorBitmap::count):
+ (JSC::CollectorBitmap::isEmpty): Added some helper functions for managing
+ the collector mark bitmap.
+
+ (JSC::Heap::reportExtraMemoryCost): Changed reporting from cell equivalents
+ to bytes, so it's easier to understand.
+
+ * runtime/CollectorHeapIterator.h:
+ (JSC::CollectorHeapIterator::CollectorHeapIterator):
+ (JSC::CollectorHeapIterator::operator!=):
+ (JSC::CollectorHeapIterator::operator*):
+ (JSC::CollectorHeapIterator::advance):
+ (JSC::::LiveObjectIterator):
+ (JSC::::operator):
+ (JSC::::DeadObjectIterator):
+ (JSC::::ObjectIterator): New iterators for encapsulating details about
+ heap layout, and what's live and dead on the heap.
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::putSlowCase):
+ (JSC::JSArray::increaseVectorLength): Delay reporting extra cost until
+ we're fully constructed, so the heap mark phase won't visit us in an
+ invalid state.
+
+ * runtime/JSCell.h:
+ (JSC::JSCell::):
+ (JSC::JSCell::createDummyStructure):
+ (JSC::JSCell::JSCell):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h: Added a dummy cell to simplify allocation logic.
+
+ * runtime/JSString.h:
+ (JSC::jsSubstring): Don't report extra cost for substrings, since they
+ share a buffer that's already reported extra cost.
+
+ * runtime/Tracing.d:
+ * runtime/Tracing.h: Changed these dtrace hooks not to report object
+ counts, since they're no longer cheap to compute.
+
+ * runtime/UString.h: Updated for renames.
+
+ * runtime/WeakGCMap.h: Added.
+ (JSC::WeakGCMap::isEmpty):
+ (JSC::WeakGCMap::uncheckedGet):
+ (JSC::WeakGCMap::uncheckedBegin):
+ (JSC::WeakGCMap::uncheckedEnd):
+ (JSC::::get):
+ (JSC::::take):
+ (JSC::::set):
+ (JSC::::uncheckedRemove): Mentioned above.
+
+ * wtf/StdLibExtras.h:
+ (WTF::bitCount): Added a bit population count function, so the heap can
+ count live objects to fulfill statistics questions.
+
+The very last cell in the block is not allocated -- should not be marked.
+
+2009-12-13 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: Export some new symbols.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2009-12-13 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: Removed some old exports.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2009-12-13 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: Use unsigned instead of uint32_t to avoid dependencies.
+
+ * wtf/StdLibExtras.h:
+ (WTF::bitCount):
+
+2009-12-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (speculative Windows build fix).
+
+ * runtime/JSGlobalObjectFunctions.cpp:
+
+2009-12-13 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32496
+ Switch remaining cases of string construction to use StringBuilder.
+ Builds strings using a vector rather than using string append / addition.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::paramString):
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::encode):
+ (JSC::decode):
+ (JSC::globalFuncEscape):
+ (JSC::globalFuncUnescape):
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::stringify):
+ (JSC::Stringifier::indent):
+ * runtime/JSString.h:
+ * runtime/LiteralParser.cpp:
+ (JSC::LiteralParser::Lexer::lexString):
+ * runtime/NumberPrototype.cpp:
+ (JSC::integerPartNoExp):
+ (JSC::numberProtoFuncToFixed):
+ (JSC::numberProtoFuncToPrecision):
+ * runtime/Operations.h:
+ (JSC::jsString):
+ * runtime/StringPrototype.cpp:
+ (JSC::substituteBackreferencesSlow):
+ (JSC::substituteBackreferences):
+ (JSC::stringProtoFuncConcat):
+
+2009-12-08 Jeremy Moskovich <jeremy@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Add code to allow toggling ATSUI/Core Text rendering at runtime in ComplexTextController.
+ https://bugs.webkit.org/show_bug.cgi?id=31802
+
+ The goal here is to allow for a zero runtime hit for ports that decide to select
+ the API at compile time.
+ When both USE(ATSUI) and USE(CORE_TEXT) are true, the API is toggled
+ at runtime. Core Text is used for OS Versions >= 10.6.
+
+ * wtf/Platform.h: #define USE_CORE_TEXT and USE_ATSUI on Chrome/Mac.
+
+2009-12-11 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Unify codegen for forward and backward variants of branches
+ https://bugs.webkit.org/show_bug.cgi?id=32463
+
+ * jit/JIT.h:
+ (JSC::JIT::emit_op_loop): Implemented in terms of forward variant.
+ (JSC::JIT::emit_op_loop_if_true): ditto
+ (JSC::JIT::emitSlow_op_loop_if_true): ditto
+ (JSC::JIT::emit_op_loop_if_false): ditto
+ (JSC::JIT::emitSlow_op_loop_if_false): ditto
+ (JSC::JIT::emit_op_loop_if_less): ditto
+ (JSC::JIT::emitSlow_op_loop_if_less): ditto
+ * jit/JITOpcodes.cpp:
+
+2009-12-11 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Anders Carlsson.
+
+ Allow WTFs concept of the main thread to differ from pthreads when necessary.
+
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::initializeThreading):
+ (WTF::isMainThread):
+ * wtf/mac/MainThreadMac.mm:
+ (WTF::initializeMainThreadPlatform):
+ (WTF::scheduleDispatchFunctionsOnMainThread):
+
+2009-12-11 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32454
+ Refactor construction of simple strings to avoid string concatenation.
+
+ Building strings through concatenation has a memory and performance cost -
+ a memory cost since we must over-allocate the buffer to leave space to append
+ into, and performance in that the string may still require reallocation (and
+ thus copying during construction). Instead move the full construction to
+ within a single function call (makeString), so that the arguments' lengths
+ can be calculated and an appropriate sized buffer allocated before copying
+ any characters.
+
+ ~No performance change (~2% progression on date tests).
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::escapeQuotes):
+ (JSC::valueToSourceString):
+ (JSC::constantName):
+ (JSC::idName):
+ (JSC::CodeBlock::registerName):
+ (JSC::regexpToSourceString):
+ (JSC::regexpName):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::substitute):
+ * profiler/Profiler.cpp:
+ (JSC::Profiler::createCallIdentifier):
+ * runtime/DateConstructor.cpp:
+ (JSC::callDate):
+ * runtime/DateConversion.cpp:
+ (JSC::formatDate):
+ (JSC::formatDateUTCVariant):
+ (JSC::formatTime):
+ (JSC::formatTimeUTC):
+ * runtime/DateConversion.h:
+ (JSC::):
+ * runtime/DatePrototype.cpp:
+ (JSC::dateProtoFuncToString):
+ (JSC::dateProtoFuncToUTCString):
+ (JSC::dateProtoFuncToDateString):
+ (JSC::dateProtoFuncToTimeString):
+ (JSC::dateProtoFuncToGMTString):
+ * runtime/ErrorPrototype.cpp:
+ (JSC::errorProtoFuncToString):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createUndefinedVariableError):
+ (JSC::createErrorMessage):
+ (JSC::createInvalidParamError):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::insertSemicolonIfNeeded):
+ (JSC::functionProtoFuncToString):
+ * runtime/ObjectPrototype.cpp:
+ (JSC::objectProtoFuncToString):
+ * runtime/RegExpConstructor.cpp:
+ (JSC::constructRegExp):
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::match):
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncCompile):
+ (JSC::regExpProtoFuncToString):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncBig):
+ (JSC::stringProtoFuncSmall):
+ (JSC::stringProtoFuncBlink):
+ (JSC::stringProtoFuncBold):
+ (JSC::stringProtoFuncFixed):
+ (JSC::stringProtoFuncItalics):
+ (JSC::stringProtoFuncStrike):
+ (JSC::stringProtoFuncSub):
+ (JSC::stringProtoFuncSup):
+ (JSC::stringProtoFuncFontcolor):
+ (JSC::stringProtoFuncFontsize):
+ (JSC::stringProtoFuncAnchor):
+ * runtime/UString.h:
+ (JSC::):
+ (JSC::makeString):
+
+2009-12-10 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32400
+ Switch remaining cases of string addition to use ropes.
+
+ Re-landing r51975 - added toPrimitiveString method,
+ performs toPrimitive then subsequent toString operations.
+
+ ~1% progression on Sunspidey.
+
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/JSString.h:
+ (JSC::JSString::JSString):
+ (JSC::JSString::appendStringInConstruct):
+ * runtime/Operations.cpp:
+ (JSC::jsAddSlowCase):
+ * runtime/Operations.h:
+ (JSC::jsString):
+ (JSC::jsAdd):
+
+2009-12-11 Adam Roben <aroben@apple.com>
+
+ Windows build fix
+
+ * JavaScriptCore.vcproj/jsc/jscCommon.vsprops: Added
+ $(WebKitOutputDir)/include/private to the include path.
+
+2009-12-11 Adam Roben <aroben@apple.com>
+
+ Move QuartzCorePresent.h to include/private
+
+ This fixes other projects that use wtf/Platform.h
+
+ Rubber-stamped by Steve Falkenburg.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Let VS do its thang.
+ * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh: Write
+ QuartzCorePresent.h to $(WebKitOutputDir)/include/private.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
+ * JavaScriptCore.vcproj/WTF/WTFCommon.vsprops:
+ Added $(WebKitOutputDir)/include/private to the include path.
+
+2009-12-11 Adam Roben <aroben@apple.com>
+
+ Fix clean builds and everything rebuilding on every build
+
+ Reviewed by Sam Weinig.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh: Don't
+ write out QuartzCorePresent.h if it exists but is older than
+ QuartzCore.h. Also, create the directory we write QuartzCorePresent.h
+ into first.
+
+2009-12-11 Adam Roben <aroben@apple.com>
+
+ Windows build fix for systems with spaces in their paths
+
+ * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh: Quote some paths.
+
+2009-12-11 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Adam Roben.
+
+ Add check for presence of QuartzCore headers
+ https://bugs.webkit.org/show_bug.cgi?id=31856
+
+ The script now checks for the presence of QuartzCore.h. If present
+ it will turn on ACCELERATED_COMPOSITING and 3D_RENDERING to enable
+ HW compositing on Windows. The script writes QuartzCorePresent.h to
+ the build directory which has a define telling whether QuartzCore is
+ present.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh:
+ * wtf/Platform.h:
+
+2009-12-11 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Fix a problem that JSC::gregorianDateTimeToMS() returns a negative
+ value for a huge year value.
+ https://bugs.webkit.org/show_bug.cgi?id=32304
+
+ * wtf/DateMath.cpp:
+ (WTF::dateToDaysFrom1970): Renamed from dateToDayInYear, and changed the return type to double.
+ (WTF::calculateDSTOffset): Follow the dateToDaysFrom1970() change.
+ (WTF::timeClip): Use maxECMAScriptTime.
+ (JSC::gregorianDateTimeToMS): Follow the dateToDaysFrom1970() change.
+
+2009-12-10 Adam Barth <abarth@webkit.org>
+
+ No review, rolling out r51975.
+ http://trac.webkit.org/changeset/51975
+
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/JSString.h:
+ (JSC::JSString::JSString):
+ (JSC::JSString::appendStringInConstruct):
+ * runtime/Operations.cpp:
+ (JSC::jsAddSlowCase):
+ * runtime/Operations.h:
+ (JSC::jsString):
+ (JSC::jsAdd):
+
+2009-12-10 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Incorrect caching of prototype lookup with dictionary base
+ https://bugs.webkit.org/show_bug.cgi?id=32402
+
+ Make sure we don't add cached prototype lookup to the proto_list
+ lookup chain if the top level object is a dictionary.
+
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::tryCacheGetByID):
+
+2009-12-10 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32400
+ Switch remaining cases of string addition to use ropes.
+
+ ~1% progression on Sunspidey.
+
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/JSString.h:
+ (JSC::JSString::JSString):
+ (JSC::JSString::appendStringInConstruct):
+ * runtime/Operations.cpp:
+ (JSC::jsAddSlowCase):
+ * runtime/Operations.h:
+ (JSC::jsString):
+ (JSC::jsAdd):
+
+2009-12-10 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Remove JSObject::getPropertyAttributes() and all usage of it.
+ https://bugs.webkit.org/show_bug.cgi?id=31933
+
+ getOwnPropertyDescriptor() should be used instead.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.order:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * debugger/DebuggerActivation.cpp:
+ (JSC::DebuggerActivation::getOwnPropertyDescriptor):
+ * debugger/DebuggerActivation.h:
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::propertyIsEnumerable):
+ * runtime/JSObject.h:
+ * runtime/JSVariableObject.cpp:
+ * runtime/JSVariableObject.h:
+
+2009-12-10 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt & Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32367
+ Add support for short Ropes (up to 3 entries) inline within JSString.
+ (rather than externally allocating an object to hold the rope).
+ Switch jsAdd of (JSString* + JSString*) to now make use of Ropes.
+
+ ~1% progression on Sunspidey.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope):
+ (JSC::JSString::toBoolean):
+ (JSC::JSString::getStringPropertyDescriptor):
+ * runtime/JSString.h:
+ (JSC::JSString::Rope::Fiber::deref):
+ (JSC::JSString::Rope::Fiber::ref):
+ (JSC::JSString::Rope::Fiber::refAndGetLength):
+ (JSC::JSString::Rope::append):
+ (JSC::JSString::JSString):
+ (JSC::JSString::~JSString):
+ (JSC::JSString::value):
+ (JSC::JSString::tryGetValue):
+ (JSC::JSString::length):
+ (JSC::JSString::canGetIndex):
+ (JSC::JSString::appendStringInConstruct):
+ (JSC::JSString::appendValueInConstructAndIncrementLength):
+ (JSC::JSString::isRope):
+ (JSC::JSString::string):
+ (JSC::JSString::ropeLength):
+ (JSC::JSString::getStringPropertySlot):
+ * runtime/Operations.h:
+ (JSC::jsString):
+ (JSC::jsAdd):
+ (JSC::resolveBase):
+
+2009-12-09 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Fix three more things found by compiling with clang++.
+
+ * runtime/Structure.h:
+ (JSC::StructureTransitionTable::reifySingleTransition):
+ Add the 'std' qualifier to the call to make_pair.
+
+ * wtf/DateMath.cpp:
+ (WTF::initializeDates):
+ Incrementing a bool is deprecated according to the C++ specification.
+
+ * wtf/PtrAndFlags.h:
+ (WTF::PtrAndFlags::PtrAndFlags):
+ Name lookup should not be done in dependent bases, so explicitly qualify the call to set.
+
+2009-12-09 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Google reader gets stuck in the "Loading..." state and does not complete
+ https://bugs.webkit.org/show_bug.cgi?id=32256
+ <rdar://problem/7456388>
+
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emitSlow_op_jless): Fix some backward branches.
+
+2009-12-09 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32228
+ Make destruction of ropes non-recursive to prevent stack exhaustion.
+ Also, pass a UString& into initializeFiber rather than a Ustring::Rep*,
+ since the Rep is not being ref counted this could result in usage of a
+ Rep with refcount zero (where the Rep comes from a temporary UString
+ returned from a function).
+
+ * runtime/JSString.cpp:
+ (JSC::JSString::Rope::destructNonRecursive):
+ (JSC::JSString::Rope::~Rope):
+ * runtime/JSString.h:
+ (JSC::JSString::Rope::initializeFiber):
+ * runtime/Operations.h:
+ (JSC::concatenateStrings):
+
+2009-12-09 Zoltan Herczeg <zherczeg@inf.u-szeged.hu>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31930
+
+ Update to r51457. ASSERTs changed to COMPILE_ASSERTs.
+ The speedup is 25%.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::VPtrSet::VPtrSet):
+
+2009-12-09 Steve Block <steveblock@google.com>
+
+ Reviewed by Adam Barth.
+
+ Updates Android Makefiles with latest additions.
+ https://bugs.webkit.org/show_bug.cgi?id=32278
+
+ * Android.mk: Modified.
+ * Android.v8.wtf.mk: Modified.
+
+2009-12-09 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Fix a bug found while trying to compile JavaScriptCore with clang++.
+
+ * yarr/RegexPattern.h:
+ (JSC::Yarr::PatternTerm::PatternTerm): Don't self assign here. Use false instead.
+
+2009-12-09 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Attempt to fix the Windows build.
+
+ * wtf/FastMalloc.h:
+
+2009-12-09 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix some things found while trying to compile JavaScriptCore with clang++.
+
+ * wtf/FastMalloc.h:
+ Add correct exception specifications for the allocation/deallocation operators.
+
+ * wtf/Vector.h:
+ * wtf/VectorTraits.h:
+ Fix a bunch of struct/class mismatches.
+
+2009-12-08 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Darin Adler.
+
+ move code generation portions of Nodes.cpp to bytecompiler directory
+ https://bugs.webkit.org/show_bug.cgi?id=32284
+
+ * bytecompiler/NodesCodegen.cpp: Copied from parser/Nodes.cpp. Removed parts that
+ are not about codegen.
+ * parser/Nodes.cpp: Removed everything that is about codegen.
+
+ Update build systems:
+
+ * Android.mk:
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+
+2009-12-08 Kevin Watters <kevinwatters@gmail.com>
+
+ Reviewed by Kevin Ollivier.
+
+ [wx] Mac plugins support.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32236
+
+ * wtf/Platform.h:
+
+2009-12-08 Dmitry Titov <dimich@chromium.org>
+
+ Rubber-stamped by David Levin.
+
+ Revert and reopen "Add asserts to RefCounted to make sure ref/deref happens on the right thread."
+ It may have caused massive increase of reported leaks on the bots.
+ https://bugs.webkit.org/show_bug.cgi?id=31639
+
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure):
+ * wtf/RefCounted.h:
+ (WTF::RefCountedBase::ref):
+ (WTF::RefCountedBase::hasOneRef):
+ (WTF::RefCountedBase::refCount):
+ (WTF::RefCountedBase::derefBase):
+ * wtf/ThreadVerifier.h: Removed.
+
+2009-12-08 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
+
+ Reviewed by Darin Adler.
+
+ Make WebKit build correctly on FreeBSD, IA64, and Alpha.
+ Based on work by Petr Salinger <Petr.Salinger@seznam.cz>,
+ and Colin Watson <cjwatson@ubuntu.com>.
+
+ * wtf/Platform.h:
+
+2009-12-08 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Add asserts to RefCounted to make sure ref/deref happens on the right thread.
+ https://bugs.webkit.org/show_bug.cgi?id=31639
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure): Disable thread verification on this class since it uses addressOfCount().
+ * wtf/RefCounted.h:
+ (WTF::RefCountedBase::ref): Add ASSERT.
+ (WTF::RefCountedBase::hasOneRef): Ditto.
+ (WTF::RefCountedBase::refCount): Ditto.
+ (WTF::RefCountedBase::derefBase): Ditto.
+ (WTF::RefCountedBase::disableThreadVerification): delegate to ThreadVerifier method.
+ * wtf/ThreadVerifier.h: Added.
+ (WTF::ThreadVerifier::ThreadVerifier): New Debug-only class to verify that ref/deref of RefCounted is done on the same thread.
+ (WTF::ThreadVerifier::activate): Activates checks. Called when ref count becomes above 2.
+ (WTF::ThreadVerifier::deactivate): Deactivates checks. Called when ref count drops below 2.
+ (WTF::ThreadVerifier::disableThreadVerification): used on objects that should not be checked (StringImpl etc)
+ (WTF::ThreadVerifier::verifyThread):
+ * GNUmakefile.am: Add ThreadVerifier.h to the build file.
+ * JavaScriptCore.gypi: Ditto.
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj: Ditto.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
+
+2009-12-08 Steve Block <steveblock@google.com>
+
+ Reviewed by Adam Barth.
+
+ [Android] Adds Makefiles for Android port.
+ https://bugs.webkit.org/show_bug.cgi?id=31325
+
+ * Android.mk: Added.
+ * Android.v8.wtf.mk: Added.
+
+2009-12-07 Dmitry Titov <dimich@chromium.org>
+
+ Rubber-stamped by Darin Adler.
+
+ Remove ENABLE_SHARED_SCRIPT flags
+ https://bugs.webkit.org/show_bug.cgi?id=32245
+ This patch was obtained by "git revert" command and then un-reverting of ChangeLog files.
+
+ * Configurations/FeatureDefines.xcconfig:
+ * wtf/Platform.h:
+
+2009-12-07 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (Windows build fixage part I).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2009-12-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32184
+ Handle out-of-memory conditions with JSC Ropes with a JS exception, rather than crashing.
+ Switch from using fastMalloc to tryFastMalloc, pass an ExecState to record the exception on.
+
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::toString):
+ * API/JSValueRef.cpp:
+ (JSValueIsStrictEqual):
+ * JavaScriptCore.exp:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitEqualityOp):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::functionName):
+ (JSC::DebuggerCallFrame::calculatedFunctionName):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::callEval):
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * profiler/ProfileGenerator.cpp:
+ (JSC::ProfileGenerator::addParentForConsoleStart):
+ * profiler/Profiler.cpp:
+ (JSC::Profiler::willExecute):
+ (JSC::Profiler::didExecute):
+ (JSC::Profiler::createCallIdentifier):
+ (JSC::createCallIdentifierFromFunctionImp):
+ * profiler/Profiler.h:
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncIndexOf):
+ (JSC::arrayProtoFuncLastIndexOf):
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncToString):
+ * runtime/InternalFunction.cpp:
+ (JSC::InternalFunction::name):
+ (JSC::InternalFunction::displayName):
+ (JSC::InternalFunction::calculatedDisplayName):
+ * runtime/InternalFunction.h:
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::getString):
+ * runtime/JSCell.h:
+ (JSC::JSValue::getString):
+ * runtime/JSONObject.cpp:
+ (JSC::gap):
+ (JSC::Stringifier::Stringifier):
+ (JSC::Stringifier::appendStringifiedValue):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::putDirectFunction):
+ (JSC::JSObject::putDirectFunctionWithoutTransition):
+ (JSC::JSObject::defineOwnProperty):
+ * runtime/JSObject.h:
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::get):
+ * runtime/JSString.cpp:
+ (JSC::JSString::Rope::~Rope):
+ (JSC::JSString::resolveRope):
+ (JSC::JSString::getPrimitiveNumber):
+ (JSC::JSString::toNumber):
+ (JSC::JSString::toString):
+ (JSC::JSString::toThisString):
+ (JSC::JSString::getStringPropertyDescriptor):
+ * runtime/JSString.h:
+ (JSC::JSString::Rope::createOrNull):
+ (JSC::JSString::Rope::operator new):
+ (JSC::JSString::value):
+ (JSC::JSString::tryGetValue):
+ (JSC::JSString::getIndex):
+ (JSC::JSString::getStringPropertySlot):
+ (JSC::JSValue::toString):
+ * runtime/JSValue.h:
+ * runtime/NativeErrorConstructor.cpp:
+ (JSC::NativeErrorConstructor::NativeErrorConstructor):
+ * runtime/Operations.cpp:
+ (JSC::JSValue::strictEqualSlowCase):
+ * runtime/Operations.h:
+ (JSC::JSValue::equalSlowCaseInline):
+ (JSC::JSValue::strictEqualSlowCaseInline):
+ (JSC::JSValue::strictEqual):
+ (JSC::jsLess):
+ (JSC::jsLessEq):
+ (JSC::jsAdd):
+ (JSC::concatenateStrings):
+ * runtime/PropertyDescriptor.cpp:
+ (JSC::PropertyDescriptor::equalTo):
+ * runtime/PropertyDescriptor.h:
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncReplace):
+ (JSC::stringProtoFuncToLowerCase):
+ (JSC::stringProtoFuncToUpperCase):
+
+2009-12-07 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Reviewed by Holger Freyther.
+
+ Turn on (SVG) Filters support, by default.
+ https://bugs.webkit.org/show_bug.cgi?id=32224
+
+ * Configurations/FeatureDefines.xcconfig: Enable FILTERS build flag.
+
+2009-12-07 Steve Falkenburg <sfalken@apple.com>
+
+ Build fix. Be flexible about which version of ICU is used on Windows.
+
+ * JavaScriptCore.vcproj/jsc/jscCommon.vsprops: Add optional xcopy commands to copy ICU 4.2.
+
+2009-12-07 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ op_loop_if_less JIT codegen is broken for 64-bit
+ https://bugs.webkit.org/show_bug.cgi?id=32221
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_loop_if_false): Fix codegen in this version - test was backwards.
+
+2009-12-07 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Object.create fails if properties on the descriptor are getters
+ https://bugs.webkit.org/show_bug.cgi?id=32219
+
+ Correctly initialise the PropertySlots with the descriptor object.
+
+ * runtime/ObjectConstructor.cpp:
+ (JSC::toPropertyDescriptor):
+
+2009-12-06 Maciej Stachowiak <mjs@apple.com>
+
+ Not reviewed, build fix.
+
+ Actually tested 64-bit *and* 32-bit build this time.
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_loop_if_false):
+
+2009-12-06 Maciej Stachowiak <mjs@apple.com>
+
+ Not reviewed, build fix.
+
+ Really really fix 64-bit build for prior patch (actually tested this time).
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_loop_if_false):
+ (JSC::JIT::emitSlow_op_loop_if_false):
+
+2009-12-06 Maciej Stachowiak <mjs@apple.com>
+
+ Not reviewed, build fix.
+
+ Really fix 64-bit build for prior patch.
+
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emitSlow_op_jless):
+
+2009-12-06 Maciej Stachowiak <mjs@apple.com>
+
+ Not reviewed, build fix.
+
+ Fix 64-bit build for prior patch.
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emitSlow_op_loop_if_less):
+
+2009-12-05 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ conway benchmark spends half it's time in op_less (jump fusion fails)
+ https://bugs.webkit.org/show_bug.cgi?id=32190
+
+ <1% speedup on SunSpider and V8
+ 2x speedup on "conway" benchmark
+
+ Two optimizations:
+ 1) Improve codegen for logical operators &&, || and ! in a condition context
+
+ When generating code for combinations of &&, || and !, in a
+ condition context (i.e. in an if statement or loop condition), we
+ used to produce a value, and then separately jump based on its
+ truthiness. Now we pass the false and true targets in, and let the
+ logical operators generate jumps directly. This helps in four
+ ways:
+
+ a) Individual clauses of a short-circuit logical operator can now
+ jump directly to the then or else clause of an if statement (or to
+ the top or exit of a loop) instead of jumping to a jump.
+
+ b) It used to be that jump fusion with the condition of the first
+ clause of a logical operator was inhibited, because the register
+ was ref'd to be used later, in the actual condition jump; this no
+ longer happens since a jump straight to the final target is
+ generated directly.
+
+ c) It used to be that jump fusion with the condition of the second
+ clause of a logical operator was inhibited, because there was a
+ jump target right after the second clause and before the actual
+ condition jump. But now it's no longer necessary for the first
+ clause to jump there so jump fusion is not blocked.
+
+ d) We avoid generating excess mov statements in some cases.
+
+ As a concrete example this source:
+
+ if (!((x < q && y < q) || (t < q && z < q))) {
+ // ...
+ }
+
+ Used to generate this bytecode:
+
+ [ 34] less r1, r-15, r-19
+ [ 38] jfalse r1, 7(->45)
+ [ 41] less r1, r-16, r-19
+ [ 45] jtrue r1, 14(->59)
+ [ 48] less r1, r-17, r-19
+ [ 52] jfalse r1, 7(->59)
+ [ 55] less r1, r-18, r-19
+ [ 59] jtrue r1, 17(->76)
+
+ And now generates this bytecode (also taking advantage of the second optimization below):
+
+ [ 34] jnless r-15, r-19, 8(->42)
+ [ 38] jless r-16, r-19, 26(->64)
+ [ 42] jnless r-17, r-19, 8(->50)
+ [ 46] jless r-18, r-19, 18(->64)
+
+ Note the jump fusion and the fact that there's less jump
+ indirection - three of the four jumps go straight to the target
+ clause instead of indirecting through another jump.
+
+ 2) Implement jless opcode to take advantage of the above, since we'll now often generate
+ a less followed by a jtrue where fusion is not forbidden.
+
+ * parser/Nodes.h:
+ (JSC::ExpressionNode::hasConditionContextCodegen): Helper function to determine
+ whether a node supports special conditional codegen. Return false as this is the default.
+ (JSC::ExpressionNode::emitBytecodeInConditionContext): Assert not reached - only really
+ defined for nodes that do have conditional codegen.
+ (JSC::UnaryOpNode::expr): Add const version.
+ (JSC::LogicalNotNode::hasConditionContextCodegen): Returne true only if subexpression
+ supports it.
+ (JSC::LogicalOpNode::hasConditionContextCodegen): Return true.
+ * parser/Nodes.cpp:
+ (JSC::LogicalNotNode::emitBytecodeInConditionContext): Implemented - just swap
+ the true and false targets for the child node.
+ (JSC::LogicalOpNode::emitBytecodeInConditionContext): Implemented - handle jumps
+ directly, improving codegen quality. Also handles further nested conditional codegen.
+ (JSC::ConditionalNode::emitBytecode): Use condition context codegen when available.
+ (JSC::IfNode::emitBytecode): ditto
+ (JSC::IfElseNode::emitBytecode): ditto
+ (JSC::DoWhileNode::emitBytecode): ditto
+ (JSC::WhileNode::emitBytecode): ditto
+ (JSC::ForNode::emitBytecode): ditto
+
+ * bytecode/Opcode.h:
+ - Added loop_if_false opcode - needed now that falsey jumps can be backwards.
+ - Added jless opcode to take advantage of new fusion opportunities.
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump): Handle above.
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitJumpIfTrue): Add peephole for less + jtrue ==> jless.
+ (JSC::BytecodeGenerator::emitJumpIfFalse): Add handling of backwrds falsey jumps.
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::emitNodeInConditionContext): Wrapper to handle tracking of
+ overly deep expressions etc.
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute): Implement the two new opcodes (loop_if_false, jless).
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass): Implement JIT support for the two new opcodes.
+ (JSC::JIT::privateCompileSlowCases): ditto
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_jless):
+ (JSC::JIT::emitSlow_op_jless): ditto
+ (JSC::JIT::emitBinaryDoubleOp): ditto
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emitSlow_op_loop_if_less): ditto
+ (JSC::JIT::emit_op_loop_if_false): ditto
+ (JSC::JIT::emitSlow_op_loop_if_false): ditto
+ * jit/JITStubs.cpp:
+ * jit/JITStubs.h:
+ (JSC::):
+
+2009-12-04 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ JavaScript delete operator should return false for string properties
+ https://bugs.webkit.org/show_bug.cgi?id=32012
+
+ * runtime/StringObject.cpp:
+ (JSC::StringObject::deleteProperty):
+
+2009-12-03 Drew Wilson <atwilson@chromium.org>
+
+ Rolled back r51633 because it causes a perf regression in Chromium.
+
+ * wtf/Platform.h:
+
+2009-12-03 Gavin Barraclough <barraclough@apple.com>
+
+ Try and fix the Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Export a symbol that should be exported.
+
+2009-12-03 Mark Rowe <mrowe@apple.com>
+
+ Try and fix the Mac build.
+
+ * JavaScriptCore.exp: Export a symbol that should be exported.
+
+2009-12-03 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ REGRESSION(4.0.3-48777): Crash in JSC::ExecState::propertyNames() (Debug-only?)
+ https://bugs.webkit.org/show_bug.cgi?id=32133
+
+ Work around odd GCC-ism and correct the scopechain for use by
+ calls made while a cachedcall is active on the callstack.
+
+ * interpreter/CachedCall.h:
+ (JSC::CachedCall::newCallFrame):
+ * runtime/JSArray.cpp:
+ (JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncReplace):
+
+2009-12-03 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver "Brraaaaiiiinnnnnzzzzzzzz" Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32136
+ Add a rope representation to JSString. Presently JSString always holds its data in UString form.
+ Instead, allow the result of a string concatenation to be represented in a tree form - with a
+ variable sized, reference-counted rope node retaining a set of UString::Reps (or other rope nopes).
+
+ Strings must still currently be resolved down to a flat UString representation before being used,
+ but by holding the string in a rope representation during construction we can avoid copying data
+ until we know the final size of the string.
+
+ ~2% progression on SunSpider (~25% on date-format-xparb, ~20% on string-validate-input).
+
+ * JavaScriptCore.exp:
+
+ - Update exports.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+ - Make use of new JSString::length() method to avoid prematurely resolving ropes.
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+
+ - Switch the string length trampoline to read the length directly from JSString::m_length,
+ rather than from the JSString's UString::Rep's 'len' property.
+
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+
+ - Modify op_add such that addition of two strings, where either or both strings are already
+ in rope representation, produces a rope as a result.
+
+ * runtime/JSString.cpp:
+ (JSC::JSString::Rope::~Rope):
+ (JSC::copyChars):
+ (JSC::JSString::resolveRope):
+ (JSC::JSString::getPrimitiveNumber):
+ (JSC::JSString::toBoolean):
+ (JSC::JSString::toNumber):
+ (JSC::JSString::toString):
+ (JSC::JSString::toThisString):
+ (JSC::JSString::getStringPropertyDescriptor):
+ * runtime/JSString.h:
+ (JSC::JSString::Rope::Fiber::Fiber):
+ (JSC::JSString::Rope::Fiber::destroy):
+ (JSC::JSString::Rope::Fiber::isRope):
+ (JSC::JSString::Rope::Fiber::rope):
+ (JSC::JSString::Rope::Fiber::string):
+ (JSC::JSString::Rope::create):
+ (JSC::JSString::Rope::initializeFiber):
+ (JSC::JSString::Rope::ropeLength):
+ (JSC::JSString::Rope::stringLength):
+ (JSC::JSString::Rope::fibers):
+ (JSC::JSString::Rope::Rope):
+ (JSC::JSString::Rope::operator new):
+ (JSC::JSString::JSString):
+ (JSC::JSString::value):
+ (JSC::JSString::length):
+ (JSC::JSString::isRope):
+ (JSC::JSString::rope):
+ (JSC::JSString::string):
+ (JSC::JSString::canGetIndex):
+ (JSC::jsSingleCharacterSubstring):
+ (JSC::JSString::getIndex):
+ (JSC::jsSubstring):
+ (JSC::JSString::getStringPropertySlot):
+
+ - Add rope form.
+
+ * runtime/Operations.h:
+ (JSC::jsAdd):
+ (JSC::concatenateStrings):
+
+ - Update string concatenation, and addition of ropes, to produce ropes.
+
+ * runtime/StringObject.cpp:
+ (JSC::StringObject::getOwnPropertyNames):
+
+ - Make use of new JSString::length() method to avoid prematurely resolving ropes.
+
+2009-11-23 Jeremy Moskovich <jeremy@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Switch Chrome/Mac to use Core Text APIs rather than ATSUI APIs.
+ https://bugs.webkit.org/show_bug.cgi?id=31802
+
+ No test since this is already covered by existing pixel tests.
+
+ * wtf/Platform.h: #define USE_CORE_TEXT for Chrome/Mac.
+
+2009-12-02 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Add files missed in prior patch.
+
+ * runtime/JSZombie.cpp:
+ (JSC::):
+ (JSC::JSZombie::leakedZombieStructure):
+ * runtime/JSZombie.h: Added.
+ (JSC::JSZombie::JSZombie):
+ (JSC::JSZombie::isZombie):
+ (JSC::JSZombie::classInfo):
+ (JSC::JSZombie::isGetterSetter):
+ (JSC::JSZombie::isAPIValueWrapper):
+ (JSC::JSZombie::isPropertyNameIterator):
+ (JSC::JSZombie::getCallData):
+ (JSC::JSZombie::getConstructData):
+ (JSC::JSZombie::getUInt32):
+ (JSC::JSZombie::toPrimitive):
+ (JSC::JSZombie::getPrimitiveNumber):
+ (JSC::JSZombie::toBoolean):
+ (JSC::JSZombie::toNumber):
+ (JSC::JSZombie::toString):
+ (JSC::JSZombie::toObject):
+ (JSC::JSZombie::markChildren):
+ (JSC::JSZombie::put):
+ (JSC::JSZombie::deleteProperty):
+ (JSC::JSZombie::toThisObject):
+ (JSC::JSZombie::toThisString):
+ (JSC::JSZombie::toThisJSString):
+ (JSC::JSZombie::getJSNumber):
+ (JSC::JSZombie::getOwnPropertySlot):
+
+2009-12-02 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Add zombies to JSC
+ https://bugs.webkit.org/show_bug.cgi?id=32103
+
+ Add a compile time flag to make the JSC collector replace "unreachable"
+ objects with zombie objects. The zombie object is a JSCell subclass that
+ ASSERTs on any attempt to use the JSCell methods. In addition there are
+ a number of additional assertions in bottleneck code to catch zombie usage
+ as quickly as possible.
+
+ Grrr. Argh. Brains.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * interpreter/Register.h:
+ (JSC::Register::Register):
+ * runtime/ArgList.h:
+ (JSC::MarkedArgumentBuffer::append):
+ (JSC::ArgList::ArgList):
+ * runtime/Collector.cpp:
+ (JSC::Heap::destroy):
+ (JSC::Heap::sweep):
+ * runtime/Collector.h:
+ * runtime/JSCell.h:
+ (JSC::JSCell::isZombie):
+ (JSC::JSValue::isZombie):
+ * runtime/JSValue.h:
+ (JSC::JSValue::decode):
+ (JSC::JSValue::JSValue):
+ * wtf/Platform.h:
+
+2009-12-01 Jens Alfke <snej@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Added variants of find/contains/add that allow a foreign key type to be used.
+ This will allow AtomicString-keyed maps to be queried by C string without
+ having to create a temporary AtomicString (see HTTPHeaderMap.)
+ The code for this is adapted from the equivalent in HashSet.h.
+
+ * wtf/HashMap.h:
+ (WTF::HashMap::find):
+ (WTF::HashMap::contains):
+ (WTF::HashMap::add):
+ * wtf/HashSet.h: Changed "method" to "function member" in a comment.
+
+2009-12-01 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
+
+ Revert 51551 because it broke GTK+.
+
+ * wtf/Platform.h:
+
+2009-11-30 Gavin Barraclough <barraclough@apple.com>
+
+ Windows Build fix. Reviewed by NOBODY.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2009-11-24 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 31859 - Make world selection for JSC IsolatedWorlds automagical.
+
+ WebCore presently has to explicitly specify the world before entering into JSC,
+ which is a little fragile (particularly since property access via a
+ getter/setter might invoke execution). Instead derive the current world from
+ the lexical global object.
+
+ Remove the temporary duct tape of willExecute/didExecute virtual hooks on the JSGlobalData::ClientData - these are no longer necessary.
+
+ * API/JSBase.cpp:
+ (JSEvaluateScript):
+ * API/JSObjectRef.cpp:
+ (JSObjectCallAsFunction):
+ * JavaScriptCore.exp:
+ * runtime/JSGlobalData.cpp:
+ * runtime/JSGlobalData.h:
+
+2009-11-30 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Remove obsolete PLATFORM(KDE) code
+ https://bugs.webkit.org/show_bug.cgi?id=31958
+
+ KDE is now using unpatched QtWebKit.
+
+ * parser/Lexer.cpp: Remove obsolete KDE_USE_FINAL guard
+ * wtf/Platform.h: Remove PLATFORM(KDE) definition and code
+ section that is guarded with it.
+
+2009-11-30 Jan-Arve Sæther <jan-arve.saether@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Fix compilation with win32-icc
+
+ The Intel compiler does not support the __has_trivial_constructor type
+ trait. The Intel Compiler can report itself as _MSC_VER >= 1400. The
+ reason for that is that the Intel Compiler depends on the Microsoft
+ Platform SDK, and in order to try to be "fully" MS compatible it will
+ "pretend" to be the same MS compiler as was shipped with the MS PSDK.
+ (Thus, compiling with win32-icc with VC8 SDK will make the source code
+ "think" the compiler at hand supports this type trait).
+
+ * wtf/TypeTraits.h:
+
+2009-11-29 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Eric Seidel.
+
+ [Qt] Mac build has JIT disabled
+ https://bugs.webkit.org/show_bug.cgi?id=31828
+
+ * wtf/Platform.h: Enable JIT for Qt Mac builds
+
+2009-11-28 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Eric Seidel.
+
+ Apply workaround for the limitation of VirtualFree with MEM_RELEASE to all ports running on Windows
+ https://bugs.webkit.org/show_bug.cgi?id=31943
+
+ * runtime/MarkStack.h:
+ (JSC::MarkStack::MarkStackArray::shrinkAllocation):
+
+2009-11-28 Zoltan Herczeg <zherczeg@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31930
+
+ Seems a typo. We don't need ~270k memory to determine the vptrs.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::VPtrSet::VPtrSet):
+
+2009-11-27 Shinichiro Hamaji <hamaji@chromium.org>
+
+ Unreviewed.
+
+ Move GOwnPtr* from wtf to wtf/gtk
+ https://bugs.webkit.org/show_bug.cgi?id=31793
+
+ Build fix for chromium after r51423.
+ Exclude gtk directory from chromium build.
+
+ * JavaScriptCore.gyp/JavaScriptCore.gyp:
+
+2009-11-25 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Incorrect behaviour of jneq_null in the interpreter
+ https://bugs.webkit.org/show_bug.cgi?id=31901
+
+ Correct the logic of jneq_null. This is already covered by existing tests.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2009-11-26 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Oliver Hunt.
+
+ Move GOwnPtr* from wtf to wtf/gtk
+ https://bugs.webkit.org/show_bug.cgi?id=31793
+
+ * GNUmakefile.am: Change the path for GOwnPtr.*.
+ * JavaScriptCore.gyp/JavaScriptCore.gyp: Remove
+ GOwnPtr.cpp from the exclude list.
+ * JavaScriptCore.gypi: Change the path for GOwnPtr.*.
+ * wscript: Remove GOwnPtr.cpp from the exclude list.
+ * wtf/GOwnPtr.cpp: Removed.
+ * wtf/GOwnPtr.h: Removed.
+ * wtf/Threading.h: Change the path for GOwnPtr.h.
+ * wtf/gtk/GOwnPtr.cpp: Copied from JavaScriptCore/wtf/GOwnPtr.cpp.
+ * wtf/gtk/GOwnPtr.h: Copied from JavaScriptCore/wtf/GOwnPtr.h.
+ * wtf/unicode/glib/UnicodeGLib.h: Change the path for GOwnPtr.h.
+
+2009-11-24 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Add ENABLE_SHARED_SCRIPT feature define and flag for build-webkit
+ https://bugs.webkit.org/show_bug.cgi?id=31444
+
+ * Configurations/FeatureDefines.xcconfig:
+ * wtf/Platform.h:
+
+2009-11-24 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ Add ability to enable ACCELERATED_COMPOSITING on Windows (currently disabled)
+ https://bugs.webkit.org/show_bug.cgi?id=27314
+
+ * wtf/Platform.h:
+
+2009-11-24 Jason Smith <dark.panda@gmail.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ RegExp#exec's returned Array-like object behaves differently from
+ regular Arrays
+ https://bugs.webkit.org/show_bug.cgi?id=31689
+
+ * JavaScriptCore/runtime/RegExpConstructor.cpp: ensure that undefined
+ values are added to the returned RegExpMatchesArray
+
+2009-11-24 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ JSON.stringify performance on undefined is very poor
+ https://bugs.webkit.org/show_bug.cgi?id=31839
+
+ Switch from a UString to a Vector<UChar> when building
+ the JSON string, allowing us to safely remove the substr-copy
+ we otherwise did when unwinding an undefined property.
+
+ Also turns out to be a ~5% speedup on stringification.
+
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::StringBuilder::append):
+ (JSC::Stringifier::stringify):
+ (JSC::Stringifier::Holder::appendNextProperty):
+
+2009-11-24 Mark Rowe <mrowe@apple.com>
+
+ Fix production builds where the source tree may be read-only.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2009-11-23 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Include "config.h" to meet Coding Style Guidelines
+ https://bugs.webkit.org/show_bug.cgi?id=31792
+
+ * wtf/unicode/UTF8.cpp:
+ * wtf/unicode/glib/UnicodeGLib.cpp:
+ * wtf/unicode/wince/UnicodeWince.cpp:
+
+2009-11-23 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Streamlined some Math functions where we expect or know the result not
+ to be representable as an int.
+
+ SunSpider says 0.6% faster.
+
+ * runtime/JSNumberCell.h:
+ (JSC::JSValue::JSValue):
+ * runtime/JSValue.h:
+ (JSC::JSValue::):
+ (JSC::jsDoubleNumber):
+ (JSC::JSValue::JSValue): Added a function for making a numeric JSValue
+ and skipping the "can I encode this as an int?" check, avoiding the
+ overhead of int <-> double roundtripping and double <-> double comparison
+ and branching.
+
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncACos):
+ (JSC::mathProtoFuncASin):
+ (JSC::mathProtoFuncATan):
+ (JSC::mathProtoFuncATan2):
+ (JSC::mathProtoFuncCos):
+ (JSC::mathProtoFuncExp):
+ (JSC::mathProtoFuncLog):
+ (JSC::mathProtoFuncRandom):
+ (JSC::mathProtoFuncSin):
+ (JSC::mathProtoFuncSqrt):
+ (JSC::mathProtoFuncTan): For these functions, which we expect or know
+ to produce results not representable as ints, call jsDoubleNumber instead
+ of jsNumber.
+
+2009-11-23 Mark Rowe <mrowe@apple.com>
+
+ Unreviewed. Unbreak the regression tests after r51329.
+
+ * API/JSBase.cpp:
+ (JSEvaluateScript): Null-check clientData before dereferencing it.
+ * API/JSObjectRef.cpp:
+ (JSObjectCallAsFunction): Ditto.
+
+2009-11-23 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Part 1/3 of <rdar://problem/7377477> REGRESSION: Many web pages fail to render after interesting script runs in isolated world
+
+ Some clients of the JavaScriptCore API expect to be able to make callbacks over the JSC API,
+ and for this to automagically cause execution to take place in the world associated with the
+ global object associated with the ExecState (JSContextRef) passed. However this is not how
+ things work - the world must be explicitly set within WebCore.
+
+ Making this work just for API calls to evaluate & call will be a far from perfect solution,
+ since direct (non-API) use of JSC still relies on WebCore setting the current world correctly.
+ A better solution would be to make this all work automagically all throughout WebCore, but this
+ will require more refactoring.
+
+ Since the API is in JSC but worlds only exist in WebCore, add callbacks on the JSGlobalData::ClientData
+ to allow it to update the current world on entry/exit via the JSC API. This is temporary duck
+ tape, and should be removed once the current world no longer needs to be explicitly tracked.
+
+ * API/JSBase.cpp:
+ (JSEvaluateScript):
+ * API/JSObjectRef.cpp:
+ (JSObjectCallAsFunction):
+ * JavaScriptCore.exp:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::ClientData::beginningExecution):
+ (JSC::JSGlobalData::ClientData::completedExecution):
+ * runtime/JSGlobalData.h:
+
+2009-11-23 Steve Block <steveblock@google.com>
+
+ Reviewed by Dmitry Titov.
+
+ Adds MainThreadAndroid.cpp with Android-specific WTF threading functions.
+ https://bugs.webkit.org/show_bug.cgi?id=31807
+
+ * wtf/android: Added.
+ * wtf/android/MainThreadAndroid.cpp: Added.
+ (WTF::timeoutFired):
+ (WTF::initializeMainThreadPlatform):
+ (WTF::scheduleDispatchFunctionsOnMainThread):
+
+2009-11-23 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Brady Eidson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31748
+ Make WebSocketHandleCFNet respect proxy auto-configuration files via CFProxySupport
+
+ * JavaScriptCore.exp: Export callOnMainThreadAndWait.
+
+2009-11-23 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Symbian] Fix lastIndexOf() for Symbian
+ https://bugs.webkit.org/show_bug.cgi?id=31773
+
+ Symbian soft floating point library has problems with operators
+ comparing NaN to numbers. Without a workaround lastIndexOf()
+ function does not work.
+
+ Patch developed by David Leong.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncLastIndexOf):Add an extra test
+ to check for NaN for Symbian.
+
+2009-11-23 Steve Block <steveblock@google.com>
+
+ Reviewed by Eric Seidel.
+
+ Android port lacks implementation of atomicIncrement and atomicDecrement.
+ https://bugs.webkit.org/show_bug.cgi?id=31715
+
+ * wtf/Threading.h: Modified.
+ (WTF::atomicIncrement): Added Android implementation.
+ (WTF::atomicDecrement): Added Android implementation.
+
+2009-11-22 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Unreviewed.
+
+ [Qt] Sort source lists and remove obsolete comments
+ from the build system.
+
+ * JavaScriptCore.pri:
+
+2009-11-21 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Eric Seidel.
+
+ [Qt][Mac] Turn on multiple JavaScript threads for QtWebkit on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=31753
+
+ * wtf/Platform.h:
+
+2009-11-19 Steve Block <steveblock@google.com>
+
+ Android port lacks configuration in Platform.h and config.h.
+ https://bugs.webkit.org/show_bug.cgi?id=31671
+
+ * wtf/Platform.h: Modified. Added Android-specific configuration.
+
+2009-11-19 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31690
+ Make SocketStreamHandleCFNet work on Windows
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * wtf/MainThread.cpp:
+ (WTF::FunctionWithContext::FunctionWithContext):
+ (WTF::dispatchFunctionsFromMainThread):
+ (WTF::callOnMainThreadAndWait):
+ * wtf/MainThread.h:
+ Re-add callOnMainThreadAndWait(), which was removed in bug 23926.
+
+2009-11-19 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by David Levin.
+
+ isMainThread() on Chromium (Mac and Linux) is so slow it timeouts LayoutTests..
+ https://bugs.webkit.org/show_bug.cgi?id=31693
+
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::initializeThreading): grab and use the pthread_t of the main thread instead of ThreadIdentifier.
+ (WTF::isMainThread): Ditto.
+
+2009-11-19 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ Remove HAVE(STRING_H) guard from JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=31668
+
+ * config.h:
+ * runtime/UString.cpp:
+
+2009-11-19 Dumitru Daniliuc <dumi@chromium.org>
+
+ Reviewed by Dmitry Titov.
+
+ Fixing a bug in MessageQueue::removeIf() that leads to an
+ assertion failure.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31657
+
+ * wtf/MessageQueue.h:
+ (WTF::MessageQueue::removeIf):
+
+2009-11-19 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ Remove HAVE(FLOAT_H) guard
+ https://bugs.webkit.org/show_bug.cgi?id=31661
+
+ JavaScriptCore has a dependency on float.h, there is
+ no need to guard float.h.
+
+ * runtime/DatePrototype.cpp: Remove include directive
+ for float.h as it is included in MathExtras.h already.
+ * runtime/Operations.cpp: Ditto.
+ * runtime/UString.cpp: Ditto.
+ * wtf/dtoa.cpp: Ditto.
+ * wtf/MathExtras.h: Remove HAVE(FLOAT_H) guard.
+ * wtf/Platform.h: Ditto.
+
+2009-11-19 Thiago Macieira <thiago.macieira@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Build fix for 32-bit Sparc machines: these machines are big-endian.
+
+ * wtf/Platform.h:
+
+2009-11-18 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Remove support for Qt v4.3 or older versions
+ https://bugs.webkit.org/show_bug.cgi?id=29469
+
+ * JavaScriptCore.pro:
+ * jsc.pro:
+ * wtf/unicode/qt4/UnicodeQt4.h:
+
+2009-11-18 Kent Tamura <tkent@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Move UString::from(double) implementation to new
+ WTF::doubleToStringInJavaScriptFormat(), and expose it because WebCore
+ code will use it.
+ https://bugs.webkit.org/show_bug.cgi?id=31330
+
+ - Introduce new function createRep(const char*, unsigned) and
+ UString::UString(const char*, unsigned) to reduce 2 calls to strlen().
+ - Fix a bug that dtoa() doesn't update *rve if the input value is NaN
+ or Infinity.
+
+ No new tests because this doesn't change the behavior.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * runtime/UString.cpp:
+ (JSC::createRep):
+ (JSC::UString::UString):
+ (JSC::UString::from): Move the code to doubleToStringInJavaScriptFormat().
+ * runtime/UString.h:
+ * wtf/dtoa.cpp:
+ (WTF::dtoa): Fix a bug about rve.
+ (WTF::append): A helper for doubleToStringInJavaScriptFormat().
+ (WTF::doubleToStringInJavaScriptFormat): Move the code from UString::from(double).
+ * wtf/dtoa.h:
+
+2009-11-18 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Remove WTF_USE_JAVASCRIPTCORE_BINDINGS as it is no longer used
+ https://bugs.webkit.org/show_bug.cgi?id=31643
+
+ * JavaScriptCore.pro:
+
+2009-11-18 Nate Chapin <japhet@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Remove Chromium's unnecessary dependency on wtf's tcmalloc files.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31648
+
+ * JavaScriptCore.gyp/JavaScriptCore.gyp:
+
+2009-11-18 Thiago Macieira <thiago.macieira@nokia.com>
+
+ Reviewed by Gavin Barraclough.
+
+ [Qt] Implement symbol hiding for JSC's JIT functions.
+
+ These functions are implemented directly in assembly, so they need the
+ proper directives to enable/disable visibility. On ELF systems, it's
+ .hidden, whereas on Mach-O systems (Mac) it's .private_extern. On
+ Windows, it's not necessary since you have to explicitly export. I
+ also implemented the AIX idiom, though it's unlikely anyone will
+ implement AIX/POWER JIT.
+ https://bugs.webkit.org/show_bug.cgi?id=30864
+
+ * jit/JITStubs.cpp:
+
+2009-11-18 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Interpreter may do an out of range access when throwing an exception in the profiler.
+ https://bugs.webkit.org/show_bug.cgi?id=31635
+
+ Add bounds check.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException):
+
+2009-11-18 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Darin Adler.
+
+ Fix the clobber list of cacheFlush for ARM and Thumb2 on Linux
+ https://bugs.webkit.org/show_bug.cgi?id=31631
+
+ * jit/ExecutableAllocator.h:
+ (JSC::ExecutableAllocator::cacheFlush):
+
+2009-11-18 Harald Fernengel <harald.fernengel@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Fix detection of linux-g++
+
+ Never use "linux-g++*" to check for linux-g++, since this will break embedded
+ builds which use linux-arm-g++ and friends. Use 'linux*-g++*' to check for any
+ g++ on linux mkspec.
+
+ * JavaScriptCore.pri:
+
+2009-11-17 Jon Honeycutt <jhoneycutt@apple.com>
+
+ Add JSContextRefPrivate.h to list of copied files.
+
+ Reviewed by Mark Rowe.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
+
+2009-11-17 Martin Robinson <martin.james.robinson@gmail.com>
+
+ Reviewed by Adam Barth.
+
+ [GTK] Style cleanup for GOwnPtr
+ https://bugs.webkit.org/show_bug.cgi?id=31506
+
+ Remove forward declaration in GOwnPtr and do some style cleanup.
+
+ * wtf/GOwnPtr.cpp:
+ * wtf/GOwnPtr.h:
+ (WTF::GOwnPtr::GOwnPtr):
+ (WTF::GOwnPtr::~GOwnPtr):
+ (WTF::GOwnPtr::get):
+ (WTF::GOwnPtr::release):
+ (WTF::GOwnPtr::outPtr):
+ (WTF::GOwnPtr::set):
+ (WTF::GOwnPtr::clear):
+ (WTF::GOwnPtr::operator*):
+ (WTF::GOwnPtr::operator->):
+ (WTF::GOwnPtr::operator!):
+ (WTF::GOwnPtr::operator UnspecifiedBoolType):
+ (WTF::GOwnPtr::swap):
+ (WTF::swap):
+ (WTF::operator==):
+ (WTF::operator!=):
+ (WTF::getPtr):
+ (WTF::freeOwnedGPtr):
+
+2009-11-17 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Incorrect use of JavaScriptCore API in DumpRenderTree
+ https://bugs.webkit.org/show_bug.cgi?id=31577
+
+ Add assertions to the 'toJS' functions to catch mistakes like
+ this early. Restructure existing code which blindly passed potentially
+ null values to toJS when forwarding exceptions so that a null check is
+ performed first.
+
+ * API/APICast.h:
+ (toJS):
+ (toJSForGC):
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::getOwnPropertySlot):
+ (JSC::::put):
+ (JSC::::deleteProperty):
+ (JSC::::construct):
+ (JSC::::hasInstance):
+ (JSC::::call):
+ (JSC::::toNumber):
+ (JSC::::toString):
+ (JSC::::staticValueGetter):
+ (JSC::::callbackGetter):
+ * API/tests/testapi.c: Fix errors in the API tester.
+ (MyObject_getProperty):
+ (MyObject_convertToType):
+ (EvilExceptionObject_convertToType):
+
+2009-11-16 Zoltan Herczeg <zherczeg@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31050
+
+ Minor fixes for JSVALUE32_64: branchConvertDoubleToInt32
+ failed on a CortexA8 CPU, but not on a simulator; and
+ JITCall.cpp modifications was somehow not committed to mainline.
+
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::fmrs_r):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::branchConvertDoubleToInt32):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+
+2009-11-16 Joerg Bornemann <joerg.bornemann@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix Qt build on Windows CE 6.
+
+ * JavaScriptCore.pri: Add missing include path.
+ * wtf/Platform.h: Include ce_time.h for Windows CE 6.
+
+2009-11-13 Zoltan Herczeg <zherczeg@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31050
+
+ Adding optimization support for mode JSVALUE32_64
+ on ARM systems.
+
+ * jit/JIT.h:
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_method_check):
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::emit_op_put_by_id):
+
+2009-11-14 Zoltan Herczeg <zherczeg@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31050
+
+ Adding JSVALUE32_64 support for ARM (but not turning it
+ on by default). All optimizations must be disabled, since
+ this patch is only the first of a series of patches.
+
+ During the work, a lot of x86 specific code revealed and
+ made platform independent.
+ See revisions: 50531 50541 50593 50594 50595
+
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::):
+ (JSC::ARMAssembler::fdivd_r):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::lshift32):
+ (JSC::MacroAssemblerARM::neg32):
+ (JSC::MacroAssemblerARM::rshift32):
+ (JSC::MacroAssemblerARM::branchOr32):
+ (JSC::MacroAssemblerARM::set8):
+ (JSC::MacroAssemblerARM::setTest8):
+ (JSC::MacroAssemblerARM::loadDouble):
+ (JSC::MacroAssemblerARM::divDouble):
+ (JSC::MacroAssemblerARM::convertInt32ToDouble):
+ (JSC::MacroAssemblerARM::zeroDouble):
+ * jit/JIT.cpp:
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JITStubs.cpp:
+ * wtf/StdLibExtras.h:
+
+2009-11-13 Dominik Röttsches <dominik.roettsches@access-company.com>
+
+ Reviewed by Eric Seidel.
+
+ Unify TextBoundaries implementations by only relying on WTF Unicode abstractions
+ https://bugs.webkit.org/show_bug.cgi?id=31468
+
+ Adding isAlphanumeric abstraction, required
+ by TextBoundaries.cpp.
+
+ * wtf/unicode/glib/UnicodeGLib.h:
+ (WTF::Unicode::isAlphanumeric):
+ * wtf/unicode/icu/UnicodeIcu.h:
+ (WTF::Unicode::isAlphanumeric):
+
+2009-11-13 Norbert Leser <norbert.leser&nokia.com>
+
+ Reviewed by Eric Seidel.
+
+ Added macros for USERINCLUDE paths within symbian blocks
+ to guarantee inclusion of respective header files from local path
+ first (to avoid clashes with same names of header files in system include path).
+
+ * JavaScriptCore.pri:
+
+2009-11-13 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ JSValueProtect and JSValueUnprotect don't protect API wrapper values
+ https://bugs.webkit.org/show_bug.cgi?id=31485
+
+ Make JSValueProtect/Unprotect use a new 'toJS' function, 'toJSForGC' that
+ does not attempt to to strip out API wrapper objects.
+
+ * API/APICast.h:
+ (toJSForGC):
+ * API/JSValueRef.cpp:
+ (JSValueProtect):
+ (JSValueUnprotect):
+ * API/tests/testapi.c:
+ (makeGlobalNumberValue):
+ (main):
+
+2009-11-13 İsmail Dönmez <ismail@namtrac.org>
+
+ Reviewed by Antti Koivisto.
+
+ Fix typo, ce_time.cpp should be ce_time.c
+
+ * JavaScriptCore.pri:
+
+2009-11-12 Steve VanDeBogart <vandebo@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Calculate the time offset only if we were able to parse
+ the date string. This saves an IPC in Chromium for
+ invalid date strings.
+ https://bugs.webkit.org/show_bug.cgi?id=31416
+
+ * wtf/DateMath.cpp:
+ (WTF::parseDateFromNullTerminatedCharacters):
+ (JSC::parseDateFromNullTerminatedCharacters):
+
+2009-11-12 Oliver Hunt <oliver@apple.com>
+
+ Rollout r50896 until i can work out why it causes failures.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitReturn):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ * parser/Nodes.cpp:
+ (JSC::EvalNode::emitBytecode):
+
+2009-11-12 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Stephanie Lewis.
+
+ Remove LIBRARY directive from def file to fix Debug_All target.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2009-11-12 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
+
+ Rubber-stamped by Holger Freyther.
+
+ Revert r50204, since it makes DRT crash on 32 bits release builds
+ for GTK+.
+
+ * wtf/FastMalloc.h:
+
+2009-11-12 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Start unifying entry logic for function and eval code.
+
+ Eval now uses a ret instruction to end execution, and sets up
+ a callframe more in line with what we do for function entry.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitReturn):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ * parser/Nodes.cpp:
+ (JSC::EvalNode::emitBytecode):
+
+2009-11-12 Richard Moe Gustavsen <richard.gustavsen@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Disable pthread_setname_np.
+
+ This allows Qt builds on Mac from 10.6 to run on earlier version
+ where this symbol is not present.
+ https://bugs.webkit.org/show_bug.cgi?id=31403
+
+ * wtf/Platform.h:
+
+2009-11-12 Thiago Macieira <thiago.macieira@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] Fix linking on Linux 32-bit.
+
+ It was missing the ".text" directive at the top of the file,
+ indicating that code would follow. Without it, the assembler created
+ "NOTYPE" symbols, which would result in linker errors.
+ https://bugs.webkit.org/show_bug.cgi?id=30863
+
+ * jit/JITStubs.cpp:
+
+2009-11-11 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Refactor multiple JavaScriptCore threads
+ https://bugs.webkit.org/show_bug.cgi?id=31328
+
+ Remove the id field from the PlatformThread structure
+ as it is not used.
+
+ * runtime/Collector.cpp:
+ (JSC::getCurrentPlatformThread):
+ (JSC::suspendThread):
+ (JSC::resumeThread):
+ (JSC::getPlatformThreadRegisters):
+
+2009-11-10 Geoffrey Garen <ggaren@apple.com>
+
+ Linux build fix: Added an #include for UINT_MAX.
+
+ * runtime/WeakRandom.h:
+
+2009-11-10 Geoffrey Garen <ggaren@apple.com>
+
+ JavaScriptGlue build fix: Marked a file 'private' instead of 'project'.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2009-11-10 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Gavin "avGni arBalroguch" Barraclough.
+
+ Faster Math.random, based on GameRand.
+
+ SunSpider says 1.4% faster.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj: Added the header to the project.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h: Use an object to track random number generation
+ state, initialized to the current time.
+
+ * runtime/MathObject.cpp:
+ (JSC::MathObject::MathObject):
+ (JSC::mathProtoFuncRandom): Use the new hotness.
+
+ * runtime/WeakRandom.h: Added.
+ (JSC::WeakRandom::WeakRandom):
+ (JSC::WeakRandom::get):
+ (JSC::WeakRandom::advance): The new hotness.
+
+2009-11-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Imported the v8 DST cache.
+
+ SunSpider says 1.5% faster.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::resetDateCache): Reset the DST cache when resetting
+ other date data.
+
+ * runtime/JSGlobalData.h:
+ (JSC::DSTOffsetCache::DSTOffsetCache):
+ (JSC::DSTOffsetCache::reset): Added a struct for the DST cache.
+
+ * wtf/DateMath.cpp:
+ (WTF::calculateDSTOffsetSimple):
+ (WTF::calculateDSTOffset):
+ (WTF::parseDateFromNullTerminatedCharacters):
+ (JSC::getDSTOffset):
+ (JSC::gregorianDateTimeToMS):
+ (JSC::msToGregorianDateTime):
+ (JSC::parseDateFromNullTerminatedCharacters):
+ * wtf/DateMath.h: The imported code for probing and updating the cache.
+
+2009-11-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fixed an edge case that could cause the engine not to notice a timezone
+ change.
+
+ No test because this case would require manual intervention to change
+ the timezone during the test.
+
+ SunSpider reports no change.
+
+ * runtime/DateInstanceCache.h:
+ (JSC::DateInstanceCache::DateInstanceCache):
+ (JSC::DateInstanceCache::reset): Added a helper function for resetting
+ this cache. Also, shrank the cache, since we'll be resetting it often.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::resetDateCache): Include resetting the DateInstanceCache
+ in resetting Date data. (Otherwise, a cache hit could bypass a necessary
+ timezone update check.)
+
+2009-11-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Some manual inlining and constant propogation in Date code.
+
+ SunSpider reports a 0.4% speedup on date-*, no overall speedup. Shark
+ says some previously evident stalls are now gone.
+
+ * runtime/DateConstructor.cpp:
+ (JSC::callDate):
+ * runtime/DateConversion.cpp:
+ (JSC::formatTime):
+ (JSC::formatTimeUTC): Split formatTime into UTC and non-UTC variants.
+
+ * runtime/DateConversion.h:
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::calculateGregorianDateTime):
+ (JSC::DateInstance::calculateGregorianDateTimeUTC):
+ * runtime/DateInstance.h:
+ (JSC::DateInstance::gregorianDateTime):
+ (JSC::DateInstance::gregorianDateTimeUTC): Split gregorianDateTime into
+ a UTC and non-UTC variant, and split each variant into a fast inline
+ case and a slow out-of-line case.
+
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+ (JSC::dateProtoFuncToString):
+ (JSC::dateProtoFuncToUTCString):
+ (JSC::dateProtoFuncToISOString):
+ (JSC::dateProtoFuncToDateString):
+ (JSC::dateProtoFuncToTimeString):
+ (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::dateProtoFuncGetTimezoneOffset):
+ (JSC::setNewValueFromTimeArgs):
+ (JSC::setNewValueFromDateArgs):
+ (JSC::dateProtoFuncSetYear):
+ (JSC::dateProtoFuncGetYear): Updated for the gregorianDateTime change above.
+
+2009-11-09 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix: export a new symbol.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2009-11-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam "Home Wrecker" Weinig.
+
+ Added a tiny cache for Date parsing.
+
+ SunSpider says 1.2% faster.
+
+ * runtime/DateConversion.cpp:
+ (JSC::parseDate): Try to reuse the last parsed Date, if present.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::resetDateCache):
+ * runtime/JSGlobalData.h: Added storage for last parsed Date. Refactored
+ this code to make resetting the date cache easier.
+
+ * runtime/JSGlobalObject.h:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): Updated for
+ refactoring.
+
+ * wtf/DateMath.cpp:
+ (JSC::parseDateFromNullTerminatedCharacters):
+ * wtf/DateMath.h: Changed ExecState to be first parameter, as is the JSC custom.
+
+2009-11-09 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Can cache prototype lookups on uncacheable dictionaries.
+ https://bugs.webkit.org/show_bug.cgi?id=31198
+
+ Replace fromDictionaryTransition with flattenDictionaryObject and
+ flattenDictionaryStructure. This change is necessary as we need to
+ guarantee that our attempt to convert away from a dictionary structure
+ will definitely succeed, and in some cases this requires mutating the
+ object storage itself.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::tryCacheGetByID):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::tryCacheGetByID):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/BatchedTransitionOptimizer.h:
+ (JSC::BatchedTransitionOptimizer::~BatchedTransitionOptimizer):
+ * runtime/JSObject.h:
+ (JSC::JSObject::flattenDictionaryObject):
+ * runtime/Operations.h:
+ (JSC::normalizePrototypeChain):
+ * runtime/Structure.cpp:
+ (JSC::Structure::flattenDictionaryStructure):
+ (JSC::comparePropertyMapEntryIndices):
+ * runtime/Structure.h:
+
+2009-11-09 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Not reviewed, build fix.
+
+ Remove extra character from r50701.
+
+ * JavaScriptCore.pri:
+
+2009-11-09 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Not reviewed, build fix.
+
+ Revert r50695 because it broke QtWebKit (clean builds).
+
+ * JavaScriptCore.pri:
+
+2009-11-09 Norbert Leser <norbert.leser@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Prepended $$PWD to GENERATED_SOURCES_DIR to avoid potential ambiguities when included from WebCore.pro.
+ Some preprocessors consider this GENERATED_SOURCES_DIR relative to current invoking dir (e.g., ./WebCore),
+ and not the working dir of JavaCriptCore.pri (i.e., ../JavaScriptCore/).
+
+ * JavaScriptCore.pri:
+
+2009-11-09 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Use explicit parentheses to silence gcc 4.4 -Wparentheses warnings
+ https://bugs.webkit.org/show_bug.cgi?id=31040
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2009-11-08 David Levin <levin@chromium.org>
+
+ Reviewed by NOBODY (speculative snow leopard and windows build fixes).
+
+ * wtf/DateMath.cpp:
+ (WTF::parseDateFromNullTerminatedCharacters):
+ (JSC::gregorianDateTimeToMS):
+ (JSC::msToGregorianDateTime):
+ (JSC::parseDateFromNullTerminatedCharacters):
+ * wtf/DateMath.h:
+ (JSC::GregorianDateTime::GregorianDateTime):
+
+2009-11-08 David Levin <levin@chromium.org>
+
+ Reviewed by NOBODY (chromium build fix).
+
+ Hopefully, the last build fix.
+
+ Create better separation in DateMath about the JSC
+ and non-JSC portions. Also, only expose the non-JSC
+ version in the exports.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * wtf/DateMath.cpp:
+ (WTF::parseDateFromNullTerminatedCharacters):
+ (JSC::getUTCOffset):
+ (JSC::gregorianDateTimeToMS):
+ (JSC::msToGregorianDateTime):
+ (JSC::parseDateFromNullTerminatedCharacters):
+ * wtf/DateMath.h:
+ (JSC::gmtoffset):
+
+2009-11-08 David Levin <levin@chromium.org>
+
+ Reviewed by NOBODY (chromium build fix).
+
+ For the change in DateMath.
+
+ * config.h:
+ * wtf/DateMath.cpp:
+
+2009-11-06 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: export some symbols.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2009-11-06 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix: updated export file.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2009-11-06 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix: added some #includes.
+
+ * wtf/CurrentTime.h:
+ * wtf/DateMath.h:
+
+2009-11-06 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31197
+ Implemented a timezone cache not based on Mac OS X's notify_check API.
+
+ If the VM calculates the local timezone offset from UTC, it caches the
+ result until the end of the current VM invocation. (We don't want to cache
+ forever, because the user's timezone may change over time.)
+
+ This removes notify_* overhead on Mac, and, more significantly, removes
+ OS time and date call overhead on non-Mac platforms.
+
+ ~8% speedup on Date microbenchmark on Mac. SunSpider reports maybe a tiny
+ speedup on Mac. (Speedup on non-Mac platforms should be even more noticeable.)
+
+ * JavaScriptCore.exp:
+
+ * interpreter/CachedCall.h:
+ (JSC::CachedCall::CachedCall):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ * runtime/JSGlobalObject.h:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): Made the
+ DynamicGlobalObjectScope constructor responsible for checking whether a
+ dynamicGlobalObject has already been set. This eliminated some duplicate
+ client code, and allowed me to avoid adding even more duplicate client
+ code. Made DynamicGlobalObjectScope responsible for resetting the
+ local timezone cache upon first entry to the VM.
+
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+ (JSC::callDate):
+ (JSC::dateParse):
+ (JSC::dateUTC):
+ * runtime/DateConversion.cpp:
+ (JSC::parseDate):
+ * runtime/DateConversion.h:
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::gregorianDateTime):
+ * runtime/DateInstance.h:
+ * runtime/DateInstanceCache.h:
+ * runtime/DatePrototype.cpp:
+ (JSC::setNewValueFromTimeArgs):
+ (JSC::setNewValueFromDateArgs):
+ (JSC::dateProtoFuncSetYear):
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * wtf/DateMath.cpp:
+ (WTF::getCurrentUTCTime):
+ (WTF::getCurrentUTCTimeWithMicroseconds):
+ (WTF::getLocalTime):
+ (JSC::getUTCOffset): Use the new cache. Also, see below.
+ (JSC::gregorianDateTimeToMS):
+ (JSC::msToGregorianDateTime):
+ (JSC::initializeDates):
+ (JSC::parseDateFromNullTerminatedCharacters): Simplified the way this function
+ accounts for the local timezone offset, to accomodate our new caching API,
+ and a (possibly misguided) caller in WebCore. Also, see below.
+ * wtf/DateMath.h:
+ (JSC::GregorianDateTime::GregorianDateTime): Moved most of the code in
+ DateMath.* into the JSC namespace. The code needed to move so it could
+ naturally interact with ExecState and JSGlobalData to support caching.
+ Logically, it seemed right to move it, too, since this code is not really
+ as low-level as the WTF namespace might imply -- it implements a set of
+ date parsing and conversion quirks that are finely tuned to the JavaScript
+ language. Also removed the Mac OS X notify_* infrastructure.
+
+ * wtf/CurrentTime.h:
+ (WTF::currentTimeMS):
+ (WTF::getLocalTime): Moved the rest of the DateMath code here, and renamed
+ it to make it consistent with WTF's currentTime function.
+
+2009-11-06 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Unreviewed trivial buildfix after r50595.
+
+ Rename the remaining rshiftPtr calls to rshift32
+
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_rshift):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitFastArithImmToInt):
+
+2009-11-06 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Tidy up the shift methods on the macro-assembler interface.
+
+ Currently behaviour of shifts of a magnitude > 0x1f is undefined.
+ Instead defined that all shifts are masked to this range. This makes a lot of
+ practical sense, both since having undefined behaviour is not particularly
+ desirable, and because this behaviour is commonly required (particularly since
+ it is required bt ECMA-262 for shifts).
+
+ Update the ARM assemblers to provide this behaviour. Remove (now) redundant
+ masks from JITArithmetic, and remove rshiftPtr (this was used in case that
+ could be rewritten in a simpler form using rshift32, only optimized JSVALUE32
+ on x86-64, which uses JSVALUE64!)
+
+ * assembler/MacroAssembler.h:
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::lshift32):
+ (JSC::MacroAssemblerARM::rshift32):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::lshift32):
+ (JSC::MacroAssemblerARMv7::rshift32):
+ * assembler/MacroAssemblerX86_64.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_lshift):
+ (JSC::JIT::emit_op_rshift):
+
+2009-11-05 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber Stamped by Oliver Hunt.
+
+ Remove a magic number (1) from the JIT, instead compute the value with OBJECT_OFFSET.
+
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitPutJITStubArg):
+ (JSC::JIT::emitPutJITStubArgConstant):
+ (JSC::JIT::emitGetJITStubArg):
+ (JSC::JIT::emitPutJITStubArgFromVirtualRegister):
+ * jit/JITStubCall.h:
+ (JSC::JITStubCall::JITStubCall):
+ (JSC::JITStubCall::getArgument):
+ * jit/JITStubs.h:
+
+2009-11-05 Zoltan Herczeg <zherczeg@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31159
+ Fix branchDouble behaviour on ARM THUMB2 JIT.
+
+ The x86 branchDouble behaviour is reworked, and all JIT
+ ports should follow the x86 port. See bug 31104 and 31151
+
+ This patch contains a fix for the traditional ARM port
+
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::):
+ (JSC::ARMAssembler::fmrs_r):
+ (JSC::ARMAssembler::ftosid_r):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::):
+ (JSC::MacroAssemblerARM::branchDouble):
+ (JSC::MacroAssemblerARM::branchConvertDoubleToInt32):
+
+2009-11-05 Chris Jerdonek <chris.jerdonek@gmail.com>
+
+ Reviewed by Eric Seidel.
+
+ Removed the "this is part of the KDE project" comments from
+ all *.h, *.cpp, *.idl, and *.pm files.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31167
+
+ The maintenance and architecture page in the project wiki lists
+ this as a task.
+
+ This change includes no changes or additions to test cases
+ since the change affects only comments.
+
+ * wtf/wince/FastMallocWince.h:
+
+2009-11-05 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ Use ARMv7 specific encoding for immediate constants on ARMv7 target
+ https://bugs.webkit.org/show_bug.cgi?id=31060
+
+ * assembler/ARMAssembler.cpp:
+ (JSC::ARMAssembler::getOp2): Use INVALID_IMM
+ (JSC::ARMAssembler::getImm): Use encodeComplexImm for complex immediate
+ (JSC::ARMAssembler::moveImm): Ditto.
+ (JSC::ARMAssembler::encodeComplexImm): Encode a constant by one or two
+ instructions or a PC relative load.
+ * assembler/ARMAssembler.h: Use INVALID_IMM if a constant cannot be
+ encoded as an immediate constant.
+ (JSC::ARMAssembler::):
+ (JSC::ARMAssembler::movw_r): 16-bit immediate load
+ (JSC::ARMAssembler::movt_r): High halfword 16-bit immediate load
+ (JSC::ARMAssembler::getImm16Op2): Encode immediate constant for
+ movw_r and mowt_r
+
+2009-11-04 Mark Mentovai <mark@chromium.org>
+
+ Reviewed by Mark Rowe.
+
+ Provide TARGETING_TIGER and TARGETING_LEOPARD as analogues to
+ BUILDING_ON_TIGER and BUILDING_ON_LEOPARD. The TARGETING_ macros
+ consider the deployment target; the BUILDING_ON_ macros consider the
+ headers being built against.
+
+ * wtf/Platform.h:
+
+2009-11-04 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31151
+ Fix branchDouble behaviour on ARM THUMB2 JIT.
+
+ The ARMv7 JIT is currently using ARMv7Assembler::ConditionEQ to branch
+ for DoubleEqualOrUnordered, however this is incorrect – ConditionEQ won't
+ branch on unordered operands. Similarly, DoubleLessThanOrUnordered &
+ DoubleLessThanOrEqualOrUnordered use ARMv7Assembler::ConditionLO &
+ ARMv7Assembler::ConditionLS, whereas they should be using
+ ARMv7Assembler::ConditionLT & ARMv7Assembler::ConditionLE.
+
+ Fix these, and fill out the missing DoubleConditions.
+
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::):
+ (JSC::MacroAssemblerARMv7::branchDouble):
+
+2009-11-04 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber Stamped by Oliver Hunt.
+
+ Enable native call optimizations on ARMv7. (Existing ARM_TRADITIONAL
+ implementation was generic, worked perfectly, just needed turning on).
+
+ * jit/JITOpcodes.cpp:
+ * wtf/Platform.h:
+
+2009-11-04 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber Stamped by Mark Rowe, Oliver Hunt, and Sam Weinig.
+
+ Add a missing assert to the ARMv7 JIT.
+
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMThumbImmediate::ARMThumbImmediate):
+
+2009-11-04 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Oliver Hunt.
+
+ Remove bogus op_ prefix on dumped version of three opcodes.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+
+2009-11-04 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix dumping of constants in bytecode so that they aren't printed as large positive register numbers.
+
+ We do this by having the registerName function return information about the constant if the register
+ number corresponds to a constant. This requires that registerName, and several functions that call it,
+ be converted to member functions of CodeBlock so that the constant value can be retrieved. The
+ ExecState also needs to be threaded down through these functions so that it can be passed on to
+ constantName when needed.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::constantName):
+ (JSC::CodeBlock::registerName):
+ (JSC::CodeBlock::printUnaryOp):
+ (JSC::CodeBlock::printBinaryOp):
+ (JSC::CodeBlock::printConditionalJump):
+ (JSC::CodeBlock::printGetByIdOp):
+ (JSC::CodeBlock::printPutByIdOp):
+ (JSC::CodeBlock::dump):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::isConstantRegisterIndex):
+
+2009-11-04 Pavel Heimlich <tropikhajma@gmail.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=30647
+ Solaris build failure due to strnstr.
+
+ * wtf/StringExtras.h: Enable strnstr on Solaris, too.
+
+2009-11-04 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31104
+ Refactor x86-specific behaviour out of the JIT.
+
+ - Add explicit double branch conditions for ordered and unordered comparisons (presently the brehaviour is a mix).
+ - Refactor double to int conversion out into the MacroAssembler.
+ - Remove broken double to int conversion for !JSVALUE32_64 builds - this code was broken and slowing us down, fixing it showed it not to be an improvement.
+ - Remove exclusion of double to int conversion from (1 % X) cases in JSVALUE32_64 builds - if this was of benefit this is no longer the case; simplify.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::):
+ (JSC::MacroAssemblerX86Common::convertInt32ToDouble):
+ (JSC::MacroAssemblerX86Common::branchDouble):
+ (JSC::MacroAssemblerX86Common::branchConvertDoubleToInt32):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emitBinaryDoubleOp):
+ (JSC::JIT::emit_op_div):
+ (JSC::JIT::emitSlow_op_jnless):
+ (JSC::JIT::emitSlow_op_jnlesseq):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_jfalse):
+
+2009-11-04 Mark Mentovai <mark@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Remove BUILDING_ON_LEOPARD from JavaScriptCore.gyp. This is supposed
+ to be set as needed only in wtf/Platform.h.
+
+ * JavaScriptCore.gyp/JavaScriptCore.gyp:
+
+2009-11-02 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ REGRESSION (r48573): JSC may incorrectly cache chain lookups with a dictionary at the head of the chain
+ https://bugs.webkit.org/show_bug.cgi?id=31045
+
+ Add guards to prevent caching of prototype chain lookups with dictionaries at the
+ head of the chain. Also add a few tighter assertions to cached prototype lookups
+ to catch this in future.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::tryCacheGetByID):
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::tryCacheGetByID):
+
+2009-11-02 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ PLATFORM(CF) should be set when building for Qt on Darwin
+ https://bugs.webkit.org/show_bug.cgi?id=23671
+
+ * wtf/Platform.h: Turn on CF support if both QT and DARWIN
+ platforms are defined.
+
+2009-11-02 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by David Levin.
+
+ Remove threadsafe refcounting from tasks used with WTF::MessageQueue.
+ https://bugs.webkit.org/show_bug.cgi?id=30612
+
+ * wtf/MessageQueue.h:
+ (WTF::MessageQueue::alwaysTruePredicate):
+ (WTF::MessageQueue::~MessageQueue):
+ (WTF::MessageQueue::append):
+ (WTF::MessageQueue::appendAndCheckEmpty):
+ (WTF::MessageQueue::prepend):
+ (WTF::MessageQueue::waitForMessage):
+ (WTF::MessageQueue::waitForMessageFilteredWithTimeout):
+ (WTF::MessageQueue::tryGetMessage):
+ (WTF::MessageQueue::removeIf):
+ The MessageQueue is changed to act as a queue of OwnPtr<DataType>. It takes ownership
+ of posted tasks and passes it to the new owner (in another thread) when the task is fetched.
+ All methods have arguments of type PassOwnPtr<DataType> and return the same type.
+
+ * wtf/Threading.cpp:
+ (WTF::createThread):
+ Superficial change to trigger rebuild of JSC project on Windows,
+ workaround for https://bugs.webkit.org/show_bug.cgi?id=30890
+
+2009-10-30 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fixed failing layout test: restore a special case I accidentally deleted.
+
+ * runtime/DatePrototype.cpp:
+ (JSC::setNewValueFromDateArgs): In the case of applying a change to a date
+ that is NaN, reset the date to 0 *and* then apply the change; don't just
+ reset the date to 0.
+
+2009-10-30 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: update for object-to-pointer change.
+
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+
+2009-10-29 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=30942
+ Use pointers instead of copies to pass GregorianDateTime objects around.
+
+ SunSpider reports a shocking 4.5% speedup on date-format-xparb, and 1.3%
+ speedup on date-format-tofte.
+
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::gregorianDateTime):
+ * runtime/DateInstance.h:
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+ (JSC::dateProtoFuncToString):
+ (JSC::dateProtoFuncToUTCString):
+ (JSC::dateProtoFuncToISOString):
+ (JSC::dateProtoFuncToDateString):
+ (JSC::dateProtoFuncToTimeString):
+ (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::dateProtoFuncGetTimezoneOffset):
+ (JSC::setNewValueFromTimeArgs):
+ (JSC::setNewValueFromDateArgs):
+ (JSC::dateProtoFuncSetYear):
+ (JSC::dateProtoFuncGetYear): Renamed getGregorianDateTime to gregorianDateTime,
+ since it no longer has an out parameter. Uses 0 to indicate invalid dates.
+
+2009-10-30 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Allow custom memory allocation control for JavaScriptCore's ListHashSet
+ https://bugs.webkit.org/show_bug.cgi?id=30853
+
+ Inherits ListHashSet class from FastAllocBase because it is
+ instantiated by 'new' in WebCore/rendering/RenderBlock.cpp:1813.
+
+ * wtf/ListHashSet.h:
+
+2009-10-30 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Regression: crash enumerating properties of an object with getters or setters
+ https://bugs.webkit.org/show_bug.cgi?id=30948
+
+ Add a guard to prevent us trying to cache property enumeration on
+ objects with getters or setters.
+
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::create):
+
+2009-10-30 Roland Steiner <rolandsteiner@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Remove ENABLE_RUBY guards as discussed with Dave Hyatt and Maciej Stachowiak.
+
+ Bug 28420 - Implement HTML5 <ruby> rendering
+ (https://bugs.webkit.org/show_bug.cgi?id=28420)
+
+ No new tests (no functional change).
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2009-10-29 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ REGRESSION (r50218-r50262): E*TRADE accounts page is missing content
+ https://bugs.webkit.org/show_bug.cgi?id=30947
+ <rdar://problem/7348833>
+
+ The logic for flagging that a structure has non-enumerable properties
+ was in addPropertyWithoutTransition, rather than in the core Structure::put
+ method. Despite this I was unable to produce a testcase that caused
+ the failure that etrade was experiencing, but the new assertion in
+ getEnumerablePropertyNames triggers on numerous layout tests without
+ the fix, so in effecti all for..in enumeration in any test ends up
+ doing the required consistency check.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::addPropertyWithoutTransition):
+ (JSC::Structure::put):
+ (JSC::Structure::getEnumerablePropertyNames):
+ (JSC::Structure::checkConsistency):
+
+2009-10-29 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ Add cacheFlush support for Thumb-2 on Linux
+ https://bugs.webkit.org/show_bug.cgi?id=30865
+
+ * jit/ExecutableAllocator.h:
+ (JSC::ExecutableAllocator::cacheFlush):
+
+2009-10-28 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ JSC JIT on ARMv7 cannot link jumps >16Mb range
+ https://bugs.webkit.org/show_bug.cgi?id=30891
+
+ Start planing all relative jumps as move-32-bit-immediate-to-register-BX.
+ In the cases where the jump would fall within a relative jump range, use a relative jump.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::~ARMv7Assembler):
+ (JSC::ARMv7Assembler::LinkRecord::LinkRecord):
+ (JSC::ARMv7Assembler::):
+ (JSC::ARMv7Assembler::executableCopy):
+ (JSC::ARMv7Assembler::linkJump):
+ (JSC::ARMv7Assembler::relinkJump):
+ (JSC::ARMv7Assembler::setInt32):
+ (JSC::ARMv7Assembler::isB):
+ (JSC::ARMv7Assembler::isBX):
+ (JSC::ARMv7Assembler::isMOV_imm_T3):
+ (JSC::ARMv7Assembler::isMOVT):
+ (JSC::ARMv7Assembler::isNOP_T1):
+ (JSC::ARMv7Assembler::isNOP_T2):
+ (JSC::ARMv7Assembler::linkJumpAbsolute):
+ (JSC::ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmFirst):
+ (JSC::ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmSecond):
+ (JSC::ARMv7Assembler::ARMInstructionFormatter::twoWordOp5i6Imm4Reg4EncodedImm):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::makeJump):
+ (JSC::MacroAssemblerARMv7::makeBranch):
+ * jit/JIT.h:
+ * wtf/Platform.h:
+
+2009-10-28 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Improve for..in enumeration performance
+ https://bugs.webkit.org/show_bug.cgi?id=30887
+
+ Improve indexing of an object with a for..in iterator by
+ identifying cases where get_by_val is being used with a iterator
+ as the subscript and replace it with a new get_by_pname
+ bytecode. get_by_pname then optimizes lookups that directly access
+ the base object.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitGetByVal):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::pushOptimisedForIn):
+ (JSC::BytecodeGenerator::popOptimisedForIn):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetDirectOffset):
+ (JSC::JIT::emit_op_get_by_pname):
+ (JSC::JIT::emitSlow_op_get_by_pname):
+ * parser/Nodes.cpp:
+ (JSC::ForInNode::emitBytecode):
+ * runtime/JSObject.h:
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::create):
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::getOffset):
+ (JSC::JSPropertyNameIterator::JSPropertyNameIterator):
+ * runtime/JSValue.h:
+ (JSC::JSValue::):
+ * runtime/Structure.cpp:
+ (JSC::Structure::addPropertyTransition):
+ (JSC::Structure::changePrototypeTransition):
+ (JSC::Structure::despecifyFunctionTransition):
+ (JSC::Structure::addAnonymousSlotsTransition):
+ (JSC::Structure::getterSetterTransition):
+ (JSC::Structure::toDictionaryTransition):
+ (JSC::Structure::addPropertyWithoutTransition):
+ Track the existence (or not) of non-enumerable properties.
+ * runtime/Structure.h:
+ (JSC::Structure::propertyStorageCapacity):
+ (JSC::Structure::propertyStorageSize):
+ (JSC::Structure::hasNonEnumerableProperties):
+ (JSC::Structure::hasAnonymousSlots):
+
+2009-10-28 Dmitry Titov <dimich@chromium.org>
+
+ Not reviewed, attemp to fix Windows build.
+
+ Touch the cpp file to cause recompile.
+
+ * wtf/Threading.cpp:
+ (WTF::threadEntryPoint):
+
+2009-10-28 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by David Levin.
+
+ https://bugs.webkit.org/show_bug.cgi?id=30805
+ Add MessageQueue::removeIf(Predicate&) to remove certain tasks without pulling them from the queue.
+ Existing Database tests cover this since Database removes tasks when it is stopped.
+
+ * wtf/MessageQueue.h:
+ (WTF::::removeIf):
+
+2009-10-28 Afonso R. Costa Jr. <afonso.costa@openbossa.org>
+
+ Reviewed by Oliver Hunt.
+
+ [Qt] Enable YARR when YARR_JIT is enabled
+ https://bugs.webkit.org/show_bug.cgi?id=30730
+
+ When enabling or disabling JIT using JAVASCRIPTCORE_JIT, the ENABLE_YARR should
+ be toggled also.
+
+ * JavaScriptCore.pri:
+
+2009-10-24 Martin Robinson <martin.james.robinson@gmail.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fix strict aliasing warning by switching reinterpret_cast to bitwise_cast.
+
+ strict-aliasing warnings in JSFunction.h
+ https://bugs.webkit.org/show_bug.cgi?id=27869
+
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::nativeFunction):
+ (JSC::JSFunction::scopeChain):
+ (JSC::JSFunction::setScopeChain):
+ (JSC::JSFunction::setNativeFunction):
+
+2009-10-28 Jan-Arve Sæther <jan-arve.saether@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Build-fix for 64-bit Windows
+
+ * wtf/Platform.h: Make sure to use WTF_USE_JSVALUE64
+
+2009-10-28 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (build fix!).
+
+ * jit/JIT.h:
+
+2009-10-26 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Rubber-stamped by Darin Adler.
+
+ Export fastMalloc, fastCalloc, fastRealloc and fastFree on GCC/Unix
+ https://bugs.webkit.org/show_bug.cgi?id=30769
+
+ When using -fvisibility=hidden to hide all internal symbols by default
+ the malloc symbols will be hidden as well. For memory instrumentation
+ it is needed to provide an instrumented version of these symbols and
+ override the normal routines and by changing the visibility back to
+ default this becomes possible.
+
+ The only other solution would be to use system malloc instead of the
+ TCmalloc implementation but this will not allow to analyze memory
+ behavior with the default allocator.
+
+ * wtf/FastMalloc.h: Define WTF_FAST_MALLOC_EXPORT for GCC and !darwin
+
+2009-10-27 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber Stamped by Samuel Q. Weinig.
+
+ Make the asserts protecting the offsets in the JIT more descriptive.
+
+ * jit/JIT.h:
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_method_check):
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::emit_op_put_by_id):
+
+2009-10-27 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ A little bit of refactoring in the date code.
+
+ * JavaScriptCore.exp: Don't export this unused symbol.
+
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::DateInstance):
+ * runtime/DateInstance.h: Removed some unused functions. Changed the default
+ constructor to ensure that a DateInstance is always initialized.
+
+ * runtime/DatePrototype.cpp:
+ (JSC::DatePrototype::DatePrototype): Pass an initializer to our constructor,
+ since it now requires one.
+
+ * wtf/DateMath.cpp:
+ (WTF::msToGregorianDateTime): Only compute our offset from UTC if our
+ output will require it. Otherwise, our offset is 0.
+
+2009-10-27 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix: Mark DateInstaceCache.h private, so other frameworks can see it.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2009-10-27 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix: re-readded this file.
+
+ * runtime/DateInstanceCache.h: Added.
+ (JSC::DateInstanceData::create):
+ (JSC::DateInstanceData::DateInstanceData):
+ (JSC::DateInstanceCache::DateInstanceCache):
+ (JSC::DateInstanceCache::add):
+ (JSC::DateInstanceCache::lookup):
+
+2009-10-27 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler and Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=30800
+ Cache recently computed date data.
+
+ SunSpider reports a ~0.5% speedup, mostly from date-format-tofte.js.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj: Added new file.
+
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::DateInstance):
+ (JSC::DateInstance::getGregorianDateTime): Use the shared cache.
+
+ * runtime/DateInstance.h: Renamed m_cache to m_data, to avoid the confusion
+ of a "cache cache".
+
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+ (JSC::dateProtoFuncToString):
+ (JSC::dateProtoFuncToUTCString):
+ (JSC::dateProtoFuncToISOString):
+ (JSC::dateProtoFuncToDateString):
+ (JSC::dateProtoFuncToTimeString):
+ (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::dateProtoFuncGetTimezoneOffset):
+ (JSC::setNewValueFromTimeArgs):
+ (JSC::setNewValueFromDateArgs):
+ (JSC::dateProtoFuncSetYear):
+ (JSC::dateProtoFuncGetYear): Pass an ExecState to these functions, so they
+ can access the DateInstanceCache.
+
+ * runtime/JSGlobalData.h: Keep a DateInstanceCache.
+
+2009-10-27 James Robinson <jamesr@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Ensures that JavaScriptCore/wtf/CurrentTime.cpp is not built in PLATFORM(CHROMIUM) builds.
+
+ Chromium uses a different method to calculate the current time than is used in
+ JavaScriptCore/wtf/CurrentTime.cpp. This can lead to time skew when calls to currentTime() and Chromium's time
+ function are mixed. In particular, timers can get scheduled in the past which leads to 100% CPU use.
+ See http://code.google.com/p/chromium/issues/detail?id=25892 for an example.
+
+ https://bugs.webkit.org/show_bug.cgi?id=30833
+
+ * JavaScriptCore.gyp/JavaScriptCore.gyp:
+ * wtf/CurrentTime.cpp:
+
+2009-10-27 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Rubber-stamped by Tor Arne Vestbø.
+
+ Fix typo in RegexInterpreter.cpp and RegexJIT.cpp alterantive to
+ alternative.
+
+ * yarr/RegexInterpreter.cpp:
+ (JSC::Yarr::ByteCompiler::alternativeBodyDisjunction):
+ (JSC::Yarr::ByteCompiler::alternativeDisjunction):
+ (JSC::Yarr::ByteCompiler::emitDisjunction):
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::generateDisjunction):
+
+2009-10-26 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ Make .rc files compile on Windows without depending on MFC headers
+ https://bugs.webkit.org/show_bug.cgi?id=30750
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc: Use
+ winresrc.h because it exists even when MFC is not installed, and is
+ all that's needed here.
+
+2009-10-26 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ The thunkReturnAddress is on JITStackFrame on ARM JIT as well
+ https://bugs.webkit.org/show_bug.cgi?id=30782
+
+ Move the thunkReturnAddress from top of the stack into the JITStackFrame
+ structure. This is a requirement for JSValue32_64 support on ARM.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::ret): Return with link register
+ (JSC::MacroAssemblerARM::prepareCall): Store the return address in link register
+ * jit/JIT.h: Remove unused ctiReturnRegister
+ * jit/JITInlineMethods.h: Same as ARMv7
+ (JSC::JIT::restoreArgumentReference): Ditto.
+ (JSC::JIT::restoreArgumentReferenceForTrampoline): Ditto.
+ * jit/JITOpcodes.cpp: Remove ctiReturnRegister related instruction
+ * jit/JITStubs.cpp: Store thunkReturnAddress on JITStackFrame. Use
+ small trampoline functions which handle return addresses for each
+ CTI_STUB_FUNCTION.
+ * jit/JITStubs.h: Store thunkReturnAddress on JITStackFrame
+ (JSC::JITStackFrame::returnAddressSlot): Return with the address of thunkReturnAddress
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::generateEnter): Remove the unnecessary instruction
+
+2009-10-26 Steve Block <steveblock@google.com>
+
+ Reviewed by Darin Adler.
+
+ Adds ability to disable ReadWriteLock on platforms (eg Android) that use pthreads but do not support pthread_rwlock.
+ https://bugs.webkit.org/show_bug.cgi?id=30713
+
+ * wtf/Platform.h: Modified. Defines HAVE_PTHREAD_RWLOCK for all platforms currently using pthreads.
+ * wtf/Threading.h: Modified. Use pthread_rwlock_t only when HAVE_PTHREAD_RWLOCK is defined.
+ * wtf/ThreadingPthreads.cpp: Modified. Build ReadWriteLock methods only when HAVE_PTHREAD_RWLOCK is defined.
+
+2009-10-24 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Holger Freyther.
+
+ [Qt] [Symbian] Set the capability and memory required to run QtWebKit for Symbian
+ https://bugs.webkit.org/show_bug.cgi?id=30476
+
+ Assign ReadUserData WriteUserData NetworkServices Symbian capabilities
+ to jsc.exe.
+
+ * jsc.pro:
+
+2009-10-23 Steve Block <steveblock@google.com>
+
+ Reviewed by Dmitry Titov.
+
+ Fixes a leak in createThreadInternal on Android.
+ https://bugs.webkit.org/show_bug.cgi?id=30698
+
+ * wtf/ThreadingPthreads.cpp: Modified.
+ (WTF::createThreadInternal): Avoid leaking a ThreadData object on failure.
+
+2009-10-22 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Fixed ASSERT when opening Safari's Caches window while the Web Inspector
+ is open.
+
+ * runtime/Collector.cpp:
+ (JSC::typeName): Added two new types to the type name list in the Collector.
+ These types have been around for a while, but nobody remembered to consider them here.
+
+ * runtime/JSCell.h:
+ (JSC::JSCell::isPropertyNameIterator):
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::isPropertyNameIterator): Give the Collector
+ a way to tell if a cell is a JSPropertyNameIterator.
+
+2009-10-22 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Jon Honeycutt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=30686
+ Remove debug-specific def file.
+ Only Debug_All target uses JavaScriptCore_debug.dll naming, and since
+ that target is only used internally, maintaining two files just to
+ suppress a single link warning isn't worthwhile.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: Removed.
+
+2009-10-21 Jon Honeycutt <jhoneycutt@apple.com>
+
+ <rdar://problem/7270320> Screenshots of off-screen plug-ins are blank
+ <rdar://problem/7270314> After halting a transparent PluginView on
+ Windows, the transparency is applied twice
+
+ Reviewed by Dan Bernstein.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ Export WTF::deleteOwnedPtr(HDC).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
+ Ditto.
+
+2009-10-20 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: updated variable name.
+
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+
+2009-10-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_next_pname): Slightly tweaked this #ifdef to match the
+ size of a JSValue because m_jsStrings is an array of JSValues.
+
+2009-10-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Fixed a 64-bit regression caused by the fix for
+ https://bugs.webkit.org/show_bug.cgi?id=30570.
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_next_pname): Use TimesEight stepping on 64-bit, since
+ 64-bit pointers are eight bytes long.
+
+2009-10-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Refactored DateInstance::msToGregorianDateTime so that a DateInstance's
+ caller doesn't need to supply the DateInstance's own internal value to
+ the DateInstance.
+
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::getGregorianDateTime): Renamed from "msToGregorianDateTime".
+
+ * runtime/DateInstance.h:
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+ (JSC::dateProtoFuncToString):
+ (JSC::dateProtoFuncToUTCString):
+ (JSC::dateProtoFuncToISOString):
+ (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::dateProtoFuncGetTimezoneOffset):
+ (JSC::setNewValueFromTimeArgs):
+ (JSC::setNewValueFromDateArgs):
+ (JSC::dateProtoFuncSetYear):
+ (JSC::dateProtoFuncGetYear): Also renamed "utc" to "outputIsUTC", for clarity.
+
+2009-10-20 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Geoffrey Garen.
+
+ The op_next_pname should use 4 bytes addressing mode in case of JSValue32
+ https://bugs.webkit.org/show_bug.cgi?id=30570
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_next_pname):
+
+2009-10-20 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Oliver Hunt.
+
+ Move OverridesMarkChildren flag from DatePrototype to its parent class
+ https://bugs.webkit.org/show_bug.cgi?id=30372
+
+ * runtime/DateInstance.h:
+ (JSC::DateInstance::createStructure):
+ * runtime/DatePrototype.h:
+
+2009-10-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Tightened up some put_by_id_transition code generation.
+ https://bugs.webkit.org/show_bug.cgi?id=30539
+
+ * jit/JIT.h:
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::testPrototype):
+ (JSC::JIT::privateCompilePutByIdTransition): No need to do object type
+ checks or read Structures and prototypes from objects: they're all known
+ constants at compile time.
+
+2009-10-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Added a private API for getting a global context from a context, for
+ clients who want to preserve a context for a later callback.
+
+ * API/APICast.h:
+ (toGlobalRef): Added an ASSERT, since this function is used more often
+ than before.
+
+ * API/JSContextRef.cpp:
+ * API/JSContextRefPrivate.h: Added. The new API.
+
+ * API/tests/testapi.c:
+ (print_callAsFunction):
+ (main): Test the new API.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj: Build and export the new API.
+
+2009-10-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Tightened up some instanceof code generation.
+ https://bugs.webkit.org/show_bug.cgi?id=30488
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emitSlow_op_instanceof): No need to do object type checks -
+ cell type checks and ImplementsDefaultHasIntance checks implicitly
+ supersede object type checks.
+
+2009-10-18 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Darin Adler.
+
+ Use _stricmp and _strnicmp instead of deprecated stricmp and strnicmp.
+ https://bugs.webkit.org/show_bug.cgi?id=30474
+
+ stricmp and strnicmp are deprecated beginning in Visual
+ C++ 2005. Use _stricmp and _strnicmp instead in StringExtras.h.
+
+ * wtf/StringExtras.h:
+ (strncasecmp):
+ (strcasecmp):
+
+2009-10-16 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix: apparently we shouldn't export those symbols?
+
+ * JavaScriptCore.exp:
+
+2009-10-16 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix: export some symbols.
+
+ * JavaScriptCore.exp:
+
+2009-10-16 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ structure typeinfo flags should be inherited.
+ https://bugs.webkit.org/show_bug.cgi?id=30468
+
+ Add StructureFlag constant to the various JSC classes and use
+ it for the TypeInfo construction. This allows us to simply
+ accumulate flags by basing each classes StructureInfo on its parents.
+
+ * API/JSCallbackConstructor.h:
+ (JSC::JSCallbackConstructor::createStructure):
+ * API/JSCallbackFunction.h:
+ (JSC::JSCallbackFunction::createStructure):
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObject::createStructure):
+ * debugger/DebuggerActivation.h:
+ (JSC::DebuggerActivation::createStructure):
+ * runtime/Arguments.h:
+ (JSC::Arguments::createStructure):
+ * runtime/BooleanObject.h:
+ (JSC::BooleanObject::createStructure):
+ * runtime/DatePrototype.h:
+ (JSC::DatePrototype::createStructure):
+ * runtime/FunctionPrototype.h:
+ (JSC::FunctionPrototype::createStructure):
+ * runtime/GlobalEvalFunction.h:
+ (JSC::GlobalEvalFunction::createStructure):
+ * runtime/InternalFunction.h:
+ (JSC::InternalFunction::createStructure):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::createStructure):
+ * runtime/JSArray.h:
+ (JSC::JSArray::createStructure):
+ * runtime/JSByteArray.cpp:
+ (JSC::JSByteArray::createStructure):
+ * runtime/JSByteArray.h:
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::createStructure):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::createStructure):
+ * runtime/JSNotAnObject.h:
+ (JSC::JSNotAnObject::createStructure):
+ * runtime/JSONObject.h:
+ (JSC::JSONObject::createStructure):
+ * runtime/JSObject.h:
+ (JSC::JSObject::createStructure):
+ * runtime/JSStaticScopeObject.h:
+ (JSC::JSStaticScopeObject::createStructure):
+ * runtime/JSVariableObject.h:
+ (JSC::JSVariableObject::createStructure):
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::createStructure):
+ * runtime/MathObject.h:
+ (JSC::MathObject::createStructure):
+ * runtime/NumberConstructor.h:
+ (JSC::NumberConstructor::createStructure):
+ * runtime/NumberObject.h:
+ (JSC::NumberObject::createStructure):
+ * runtime/RegExpConstructor.h:
+ (JSC::RegExpConstructor::createStructure):
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::createStructure):
+ * runtime/StringObject.h:
+ (JSC::StringObject::createStructure):
+ * runtime/StringObjectThatMasqueradesAsUndefined.h:
+ (JSC::StringObjectThatMasqueradesAsUndefined::createStructure):
+
+2009-10-16 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fast for-in enumeration: Cache JSPropertyNameIterator; cache JSStrings
+ in JSPropertyNameIterator; inline more code.
+
+ 1.024x as fast on SunSpider (fasta: 1.43x as fast).
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitGetPropertyNames):
+ (JSC::BytecodeGenerator::emitNextPropertyName):
+ * bytecompiler/BytecodeGenerator.h: Added a few extra operands to
+ op_get_pnames and op_next_pname so that we can track iteration state
+ in the register file instead of in the JSPropertyNameIterator. (To be
+ cacheable, the JSPropertyNameIterator must be stateless.)
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::tryCachePutByID):
+ (JSC::Interpreter::tryCacheGetByID): Updated for rename to
+ "normalizePrototypeChain" and removal of "isCacheable".
+
+ (JSC::Interpreter::privateExecute): Updated for in-RegisterFile
+ iteration state tracking.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_get_pnames): Updated for in-RegisterFile
+ iteration state tracking.
+
+ (JSC::JIT::emit_op_next_pname): Inlined code generation for op_next_pname.
+
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::tryCachePutByID):
+ (JSC::JITThunks::tryCacheGetByID): Updated for rename to
+ "normalizePrototypeChain" and removal of "isCacheable".
+
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ (JSC::): Added has_property and to_object stubs. Removed op_next_pname
+ stub, since has_property is all we need anymore.
+
+ * parser/Nodes.cpp:
+ (JSC::ForInNode::emitBytecode): Updated for in-RegisterFile
+ iteration state tracking.
+
+ * runtime/JSCell.h:
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::getPropertyNames): Don't do caching at this layer
+ anymore, since we don't create a JSPropertyNameIterator at this layer.
+
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::create): Do do caching at this layer.
+ (JSC::JSPropertyNameIterator::get): Updated for in-RegisterFile
+ iteration state tracking.
+ (JSC::JSPropertyNameIterator::markChildren): Mark our JSStrings.
+
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::size):
+ (JSC::JSPropertyNameIterator::setCachedStructure):
+ (JSC::JSPropertyNameIterator::cachedStructure):
+ (JSC::JSPropertyNameIterator::setCachedPrototypeChain):
+ (JSC::JSPropertyNameIterator::cachedPrototypeChain):
+ (JSC::JSPropertyNameIterator::JSPropertyNameIterator):
+ (JSC::Structure::setEnumerationCache): Don't store iteration state in
+ a JSPropertyNameIterator. Do cache a JSPropertyNameIterator in a
+ Structure.
+
+ * runtime/JSValue.h:
+ (JSC::asCell):
+ * runtime/MarkStack.h: Make those mischievous #include gods happy.
+
+ * runtime/ObjectConstructor.cpp:
+
+ * runtime/Operations.h:
+ (JSC::normalizePrototypeChain): Renamed countPrototypeChainEntriesAndCheckForProxies
+ to normalizePrototypeChain, since it changes dictionary prototypes to
+ non-dictionary objects.
+
+ * runtime/PropertyNameArray.cpp:
+ (JSC::PropertyNameArray::add):
+ * runtime/PropertyNameArray.h:
+ (JSC::PropertyNameArrayData::PropertyNameArrayData):
+ (JSC::PropertyNameArray::data):
+ (JSC::PropertyNameArray::size):
+ (JSC::PropertyNameArray::begin):
+ (JSC::PropertyNameArray::end): Simplified some code here to help with
+ current and future refactoring.
+
+ * runtime/Protect.h:
+ * runtime/Structure.cpp:
+ (JSC::Structure::~Structure):
+ (JSC::Structure::addPropertyWithoutTransition):
+ (JSC::Structure::removePropertyWithoutTransition): No need to clear
+ the enumeration cache with adding / removing properties without
+ transition. It is an error to add / remove properties without transition
+ once an object has been observed, and we can ASSERT to catch that.
+
+ * runtime/Structure.h:
+ (JSC::Structure::enumerationCache): Changed the enumeration cache to
+ hold a JSPropertyNameIterator.
+
+ * runtime/StructureChain.cpp:
+ * runtime/StructureChain.h:
+ (JSC::StructureChain::head): Removed StructureChain::isCacheable because
+ it was wrong-headed in two ways: (1) It gave up when a prototype was a
+ dictionary, but instead we want un-dictionary heavily accessed
+ prototypes; (2) It folded a test for hasDefaultGetPropertyNames() into
+ a generic test for "cacheable-ness", but hasDefaultGetPropertyNames()
+ is only releavant to for-in caching.
+
+2009-10-16 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Adam Roben.
+
+ Add a Debug_All configuration to build entire stack as debug.
+ Change Debug_Internal to:
+ - stop using _debug suffix for all WebKit/Safari binaries
+ - not use _debug as a DLL naming suffix
+ - use non-debug C runtime lib.
+
+ * JavaScriptCore.vcproj/JavaScriptCore.make: Debug build in makefile should build Debug_All.
+ * JavaScriptCore.vcproj/JavaScriptCore.sln: Add Debug_All configuration.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add Debug_All configuration.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj: Renamed single configuration from "Release" to "all".
+ * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Add Debug_All configuration.
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj: Add Debug_All configuration.
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj: Add Debug_All configuration.
+ * JavaScriptCore.vcproj/testapi/testapi.vcproj: Add Debug_All configuration.
+
+2009-10-16 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Make typeinfo flags default to false
+ https://bugs.webkit.org/show_bug.cgi?id=30372
+
+ Last part -- replace HasDefaultGetPropertyNames with OverridesGetPropertyNames
+ flag.
+
+ * API/JSCallbackConstructor.h:
+ (JSC::JSCallbackConstructor::createStructure):
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObject::createStructure):
+ * debugger/DebuggerActivation.h:
+ (JSC::DebuggerActivation::createStructure):
+ * runtime/Arguments.h:
+ (JSC::Arguments::createStructure):
+ * runtime/BooleanObject.h:
+ (JSC::BooleanObject::createStructure):
+ * runtime/DatePrototype.h:
+ (JSC::DatePrototype::createStructure):
+ * runtime/FunctionPrototype.h:
+ (JSC::FunctionPrototype::createStructure):
+ * runtime/GlobalEvalFunction.h:
+ (JSC::GlobalEvalFunction::createStructure):
+ * runtime/JSAPIValueWrapper.h:
+ (JSC::JSAPIValueWrapper::createStructure):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::createStructure):
+ * runtime/JSArray.h:
+ (JSC::JSArray::createStructure):
+ * runtime/JSByteArray.cpp:
+ (JSC::JSByteArray::createStructure):
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::createStructure):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::createStructure):
+ * runtime/JSNotAnObject.h:
+ (JSC::JSNotAnObject::createStructure):
+ * runtime/JSONObject.h:
+ (JSC::JSONObject::createStructure):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::getPropertyNames):
+ * runtime/JSObject.h:
+ (JSC::JSObject::createStructure):
+ * runtime/JSStaticScopeObject.h:
+ (JSC::JSStaticScopeObject::createStructure):
+ * runtime/JSTypeInfo.h:
+ (JSC::TypeInfo::overridesGetPropertyNames):
+ * runtime/JSVariableObject.h:
+ (JSC::JSVariableObject::createStructure):
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::createStructure):
+ * runtime/MathObject.h:
+ (JSC::MathObject::createStructure):
+ * runtime/NumberConstructor.h:
+ (JSC::NumberConstructor::createStructure):
+ * runtime/NumberObject.h:
+ (JSC::NumberObject::createStructure):
+ * runtime/RegExpConstructor.h:
+ (JSC::RegExpConstructor::createStructure):
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::createStructure):
+ * runtime/StringObject.h:
+ (JSC::StringObject::createStructure):
+ * runtime/StringObjectThatMasqueradesAsUndefined.h:
+ (JSC::StringObjectThatMasqueradesAsUndefined::createStructure):
+ * runtime/StructureChain.cpp:
+ (JSC::StructureChain::isCacheable):
+
+2009-10-16 Kevin Ollivier <kevino@theolliviers.com>
+
+ wxMSW build fix, we can't use the simple hash there because the PlatformModuleVersion
+ structure differs.
+
+ * wtf/Platform.h:
+
+2009-10-16 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Implement ExecutableAllocator for Symbian
+ https://bugs.webkit.org/show_bug.cgi?id=29946
+
+ Tested with YARR JIT enabled for Symbian;
+ This patch does not (yet) enable YARR JIT by default.
+
+ * JavaScriptCore.pri:
+ * jit/ExecutableAllocator.h:
+ * jit/ExecutableAllocatorSymbian.cpp: Added.
+ (JSC::ExecutableAllocator::intializePageSize):
+ (JSC::ExecutablePool::systemAlloc):
+ (JSC::ExecutablePool::systemRelease):
+
+2009-10-15 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Make typeinfo flags default to false
+ https://bugs.webkit.org/show_bug.cgi?id=30372
+
+ Part 2 -- Reverse the TypeInfo HasDefaultMark flag to OverridesMarkChildren, etc
+
+ * API/JSCallbackConstructor.h:
+ (JSC::JSCallbackConstructor::createStructure):
+ * API/JSCallbackFunction.h:
+ (JSC::JSCallbackFunction::createStructure):
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObject::createStructure):
+ * debugger/DebuggerActivation.h:
+ (JSC::DebuggerActivation::createStructure):
+ * runtime/Arguments.h:
+ (JSC::Arguments::createStructure):
+ * runtime/BooleanObject.h:
+ (JSC::BooleanObject::createStructure):
+ * runtime/DatePrototype.h:
+ (JSC::DatePrototype::createStructure):
+ * runtime/FunctionPrototype.h:
+ (JSC::FunctionPrototype::createStructure):
+ * runtime/GetterSetter.h:
+ (JSC::GetterSetter::createStructure):
+ * runtime/GlobalEvalFunction.h:
+ (JSC::GlobalEvalFunction::createStructure):
+ * runtime/InternalFunction.h:
+ (JSC::InternalFunction::createStructure):
+ * runtime/JSAPIValueWrapper.h:
+ (JSC::JSAPIValueWrapper::createStructure):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::createStructure):
+ * runtime/JSArray.h:
+ (JSC::JSArray::createStructure):
+ (JSC::MarkStack::markChildren):
+ * runtime/JSByteArray.cpp:
+ (JSC::JSByteArray::createStructure):
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::createStructure):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::createStructure):
+ * runtime/JSNotAnObject.h:
+ (JSC::JSNotAnObject::createStructure):
+ * runtime/JSNumberCell.h:
+ (JSC::JSNumberCell::createStructure):
+ * runtime/JSONObject.h:
+ (JSC::JSONObject::createStructure):
+ * runtime/JSObject.h:
+ (JSC::JSObject::createStructure):
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::createStructure):
+ * runtime/JSStaticScopeObject.h:
+ (JSC::JSStaticScopeObject::createStructure):
+ * runtime/JSString.h:
+ (JSC::JSString::createStructure):
+ * runtime/JSTypeInfo.h:
+ (JSC::TypeInfo::overridesMarkChildren):
+ * runtime/JSVariableObject.h:
+ (JSC::JSVariableObject::createStructure):
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::createStructure):
+ * runtime/MathObject.h:
+ (JSC::MathObject::createStructure):
+ * runtime/NumberConstructor.h:
+ (JSC::NumberConstructor::createStructure):
+ * runtime/NumberObject.h:
+ (JSC::NumberObject::createStructure):
+ * runtime/RegExpConstructor.h:
+ (JSC::RegExpConstructor::createStructure):
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::createStructure):
+ * runtime/StringObject.h:
+ (JSC::StringObject::createStructure):
+ * runtime/StringObjectThatMasqueradesAsUndefined.h:
+ (JSC::StringObjectThatMasqueradesAsUndefined::createStructure):
+
+2009-10-14 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Make typeinfo flags default to false
+ https://bugs.webkit.org/show_bug.cgi?id=30372
+
+ Part 1. Reverse the HasStandardGetOwnPropertySlot flag.
+
+ * API/JSCallbackConstructor.h:
+ (JSC::JSCallbackConstructor::createStructure):
+ * API/JSCallbackFunction.h:
+ (JSC::JSCallbackFunction::createStructure):
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObject::createStructure):
+ * debugger/DebuggerActivation.h:
+ (JSC::DebuggerActivation::createStructure):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/Arguments.h:
+ (JSC::Arguments::createStructure):
+ * runtime/BooleanObject.h:
+ (JSC::BooleanObject::createStructure):
+ * runtime/DatePrototype.h:
+ (JSC::DatePrototype::createStructure):
+ * runtime/FunctionPrototype.h:
+ (JSC::FunctionPrototype::createStructure):
+ * runtime/GlobalEvalFunction.h:
+ (JSC::GlobalEvalFunction::createStructure):
+ * runtime/InternalFunction.h:
+ (JSC::InternalFunction::createStructure):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::createStructure):
+ * runtime/JSArray.h:
+ (JSC::JSArray::createStructure):
+ * runtime/JSByteArray.cpp:
+ (JSC::JSByteArray::createStructure):
+ * runtime/JSFunction.h:
+ (JSC::JSFunction::createStructure):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::createStructure):
+ * runtime/JSNumberCell.h:
+ (JSC::JSNumberCell::createStructure):
+ * runtime/JSONObject.h:
+ (JSC::JSONObject::createStructure):
+ * runtime/JSObject.h:
+ (JSC::JSObject::createStructure):
+ (JSC::JSCell::fastGetOwnPropertySlot):
+ * runtime/JSStaticScopeObject.h:
+ (JSC::JSStaticScopeObject::createStructure):
+ * runtime/JSString.h:
+ (JSC::JSString::createStructure):
+ * runtime/JSTypeInfo.h:
+ (JSC::TypeInfo::overridesGetOwnPropertySlot):
+ * runtime/JSVariableObject.h:
+ (JSC::JSVariableObject::createStructure):
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::createStructure):
+ * runtime/MathObject.h:
+ (JSC::MathObject::createStructure):
+ * runtime/NumberConstructor.h:
+ (JSC::NumberConstructor::createStructure):
+ * runtime/NumberObject.h:
+ (JSC::NumberObject::createStructure):
+ * runtime/RegExpConstructor.h:
+ (JSC::RegExpConstructor::createStructure):
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::createStructure):
+ * runtime/StringObject.h:
+ (JSC::StringObject::createStructure):
+ * runtime/StringObjectThatMasqueradesAsUndefined.h:
+ (JSC::StringObjectThatMasqueradesAsUndefined::createStructure):
+
+2009-10-14 Kevin Ollivier <kevino@theolliviers.com>
+2009-10-14 Darin Adler <darin@apple.com>
+
+ Additions so fix for https://bugs.webkit.org/show_bug.cgi?id=18994
+ can build on Windows.
+
+ * wtf/MathExtras.h: Added llround and llroundf for Windows.
+
+2009-10-14 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fix. Set ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH for plugins while we're still building stubs.
+
+ * wtf/Platform.h:
+
+2009-10-13 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Refactor ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH
+ https://bugs.webkit.org/show_bug.cgi?id=30278
+
+ Move the definition of ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH
+ from the make system into common code.
+
+ * wtf/Platform.h:
+
+2009-10-13 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ ARM compiler does not understand reinterpret_cast<void*>
+ https://bugs.webkit.org/show_bug.cgi?id=29034
+
+ Change reinterpret_cast<void*> to regular C style (void*) cast
+ for the ARM RVCT compiler.
+
+ * assembler/MacroAssemblerCodeRef.h:
+ (JSC::FunctionPtr::FunctionPtr):
+ * jit/JITOpcodes.cpp: Cast to FunctionPtr first
+ instead of directly casting to reinterpret_cast
+ * jit/JITStubCall.h: Ditto + change the type of m_stub
+ from void* to FunctionPtr.
+ (JSC::JITStubCall::JITStubCall):
+ (JSC::JITStubCall::call):
+ * jit/JITStubs.cpp: Ditto.
+ (JSC::DEFINE_STUB_FUNCTION(EncodedJSValue, op_throw)):
+
+2009-10-11 Oliver Hunt <oliver@apple.com>
+
+ Re-enable the JIT.
+
+ * wtf/Platform.h:
+
+2009-10-10 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Support for String.trim(), String.trimLeft() and String.trimRight() methods
+ https://bugs.webkit.org/show_bug.cgi?id=26590
+
+ Implement trim, trimLeft, and trimRight
+
+ * runtime/StringPrototype.cpp:
+ (JSC::isTrimWhitespace):
+ Our normal string whitespace function does not include U+200B which
+ is needed for compatibility with mozilla's implementation of trim.
+ U+200B does not appear to be expected according to spec, however I am
+ choosing to be lax, and match mozilla behavior so have added this
+ exception.
+ (JSC::trimString):
+
+2009-10-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Eliminated some legacy bytecode weirdness.
+
+ Use vPC[x] subscripting instead of ++vPC to access instruction operands.
+ This is simpler, and often more efficient.
+
+ To support this, and to remove use of hard-coded offsets in bytecode and
+ JIT code generation and dumping, calculate jump offsets from the beginning
+ of an instruction, rather than the middle or end.
+
+ Also, use OPCODE_LENGTH instead of hard-coded constants for the sizes of
+ opcodes.
+
+ SunSpider reports no change in JIT mode, and a 1.01x speedup in Interpreter
+ mode.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::printConditionalJump):
+ (JSC::CodeBlock::dump):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitJump):
+ (JSC::BytecodeGenerator::emitJumpIfTrue):
+ (JSC::BytecodeGenerator::emitJumpIfFalse):
+ (JSC::BytecodeGenerator::emitJumpIfNotFunctionCall):
+ (JSC::BytecodeGenerator::emitJumpIfNotFunctionApply):
+ (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/Label.h:
+ (JSC::Label::setLocation):
+ (JSC::Label::bind):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::resolve):
+ (JSC::Interpreter::resolveSkip):
+ (JSC::Interpreter::resolveGlobal):
+ (JSC::Interpreter::resolveBase):
+ (JSC::Interpreter::resolveBaseAndProperty):
+ (JSC::Interpreter::createExceptionScope):
+ (JSC::Interpreter::privateExecute):
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_jnless):
+ (JSC::JIT::emitSlow_op_jnless):
+ (JSC::JIT::emit_op_jnlesseq):
+ (JSC::JIT::emitSlow_op_jnlesseq):
+ (JSC::JIT::emitBinaryDoubleOp):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_jmp):
+ (JSC::JIT::emit_op_loop):
+ (JSC::JIT::emit_op_loop_if_less):
+ (JSC::JIT::emitSlow_op_loop_if_less):
+ (JSC::JIT::emit_op_loop_if_lesseq):
+ (JSC::JIT::emitSlow_op_loop_if_lesseq):
+ (JSC::JIT::emit_op_loop_if_true):
+ (JSC::JIT::emitSlow_op_loop_if_true):
+ (JSC::JIT::emit_op_jfalse):
+ (JSC::JIT::emitSlow_op_jfalse):
+ (JSC::JIT::emit_op_jtrue):
+ (JSC::JIT::emitSlow_op_jtrue):
+ (JSC::JIT::emit_op_jeq_null):
+ (JSC::JIT::emit_op_jneq_null):
+ (JSC::JIT::emit_op_jneq_ptr):
+ (JSC::JIT::emit_op_jsr):
+ (JSC::JIT::emit_op_next_pname):
+ (JSC::JIT::emit_op_jmp_scopes):
+
+2009-10-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Migrated some code that didn't belong out of Structure.
+
+ SunSpider says maybe 1.03x faster.
+
+ * runtime/JSCell.h: Nixed Structure::markAggregate, and made marking of
+ a Structure's prototype the direct responsility of the object using it.
+ (Giving Structure a mark function was misleading because it implied that
+ all live structures get marked during GC, when they don't.)
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::markIfNeeded):
+ (JSC::JSGlobalObject::markChildren): Added code to mark prototypes stored
+ on the global object. Maybe this wasn't necessary, but now we don't have
+ to wonder.
+
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::getPropertyNames):
+ (JSC::JSObject::getOwnPropertyNames):
+ (JSC::JSObject::getEnumerableNamesFromClassInfoTable):
+ * runtime/JSObject.h:
+ (JSC::JSObject::markChildrenDirect):
+ * runtime/PropertyNameArray.h:
+ * runtime/Structure.cpp:
+ * runtime/Structure.h:
+ (JSC::Structure::setEnumerationCache):
+ (JSC::Structure::enumerationCache): Moved property name gathering code
+ from Structure to JSObject because having a Structure iterate its JSObject
+ was a layering violation. A JSObject is implemented using a Structure; not
+ the other way around.
+
+2009-10-09 Mark Rowe <mrowe@apple.com>
+
+ Attempt to fix the GTK release build.
+
+ * GNUmakefile.am: Include Grammar.cpp in release builds now that
+ AllInOneFile.cpp is gone.
+
+2009-10-09 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Rubber-stamped by Eric Seidel.
+
+ Add ARM JIT support for Gtk port (disabled by default)
+ https://bugs.webkit.org/show_bug.cgi?id=30228
+
+ * GNUmakefile.am:
+
+2009-10-08 Geoffrey Garen <ggaren@apple.com>
+
+ Tiger build fix: added a few more variable initializations.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncReplace):
+ (JSC::stringProtoFuncSearch):
+
+2009-10-08 Geoffrey Garen <ggaren@apple.com>
+
+ Qt build fix: added missing #include.
+
+ * jsc.cpp:
+
+2009-10-08 Geoffrey Garen <ggaren@apple.com>
+
+ Tiger build fix: initialize variable whose initialization the compiler
+ can't otherwise figure out.
+
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::match):
+
+2009-10-08 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: updated exports.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
+
+2009-10-08 Geoffrey Garen <ggaren@apple.com>
+
+ Tiger build fix: fixed file name case.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2009-10-08 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ At long last, I pronounce the death of AllInOneFile.cpp.
+
+ SunSpider reports a 1.01x speedup.
+
+ * AllInOneFile.cpp: Removed.
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.xcodeproj/project.pbxproj: Added missing project files
+ to compilation stages.
+
+ * parser/Grammar.y:
+ * parser/Lexer.cpp:
+ * parser/Lexer.h:
+ (JSC::jscyylex):
+ * runtime/ArrayConstructor.cpp:
+ (JSC::constructArrayWithSizeQuirk):
+ * runtime/Collector.h:
+ * runtime/JSCell.cpp:
+ (JSC::JSCell::operator new):
+ * runtime/JSCell.h:
+ (JSC::JSCell::operator new):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::operator new):
+ * runtime/JSNumberCell.h:
+ (JSC::JSNumberCell::operator new):
+ * runtime/JSString.cpp:
+ * runtime/JSString.h:
+ (JSC::jsString):
+ (JSC::jsSubstring):
+ (JSC::jsOwnedString):
+ * runtime/RegExpConstructor.cpp:
+ * runtime/RegExpConstructor.h:
+ (JSC::RegExpConstructorPrivate::RegExpConstructorPrivate):
+ (JSC::RegExpConstructorPrivate::lastOvector):
+ (JSC::RegExpConstructorPrivate::tempOvector):
+ (JSC::RegExpConstructorPrivate::changeLastOvector):
+ (JSC::RegExpConstructor::performMatch):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncMatch):
+ * yarr/RegexJIT.cpp:
+ * yarr/RegexJIT.h:
+ (JSC::Yarr::executeRegex): Inlined a few things that Shark said
+ were hot, on the presumption that AllInOneFile.cpp used to inline them
+ automatically.
+
+2009-10-08 Zoltan Herczeg <zherczeg@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ Fix for JIT'ed op_call instructions (evals, constructs, etc.)
+ when !ENABLE(JIT_OPTIMIZE_CALL) && USE(JSVALUE32_64)
+
+ https://bugs.webkit.org/show_bug.cgi?id=30201
+
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+
+2009-10-07 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: removed no longer exported symbol.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
+
+2009-10-07 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fixed <rdar://problem/5751979> Database code takes JSLock on secondary
+ thread, permanently slowing down JavaScript
+
+ Removed the optional lock from Heap::protect, Heap::unprotect, and friends,
+ since WebCore no longer uses it.
+
+ * JavaScriptCore.exp:
+ * runtime/Collector.cpp:
+ (JSC::Heap::protect):
+ (JSC::Heap::unprotect):
+ (JSC::Heap::markProtectedObjects):
+ (JSC::Heap::protectedGlobalObjectCount):
+ (JSC::Heap::protectedObjectCount):
+ (JSC::Heap::protectedObjectTypeCounts):
+ * runtime/Collector.h:
+
+2009-10-07 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Allow custom memory allocation control for JavaScriptCore's IdentifierArena
+ https://bugs.webkit.org/show_bug.cgi?id=30158
+
+ Inherits IdentifierArena class from FastAllocBase because it has been
+ instantiated by 'new' in JavaScriptCore/parser/ParserArena.cpp:36.
+
+ * parser/ParserArena.h:
+
+2009-10-07 Adam Roben <aroben@apple.com>
+
+ Export DateInstance::info in a way that works on Windows
+
+ Fixes <http://webkit.org/b/30171>
+ fast/dom/Window/window-postmessage-clone.html fails on Windows
+
+ Reviewed by Anders Carlsson.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
+ Removed the export of DateInstance::info from here.
+
+ * runtime/DateInstance.h: Use JS_EXPORTDATA to export
+ DateInstance::info, which is the required way of exporting data on
+ Windows.
+
+2009-10-07 Jørgen Lind <jorgen.lind@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ When enabling or disabling the JIT through .qmake.cache, make sure
+ to also toggle ENABLE_YARR_JIT.
+
+ * JavaScriptCore.pri:
+
+2009-10-06 Priit Laes <plaes@plaes.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Linking fails with "relocation R_X86_64_PC32 against symbol
+ `cti_vm_throw'"
+ https://bugs.webkit.org/show_bug.cgi?id=28422
+
+ * jit/JITStubs.cpp:
+ Mark cti_vm_throw symbol as PLT-indirect symbol, so it doesn't end up
+ in text segment causing relocation errors on amd64 architecture.
+ Introduced new define SYMBOL_STRING_RELOCATION for such symbols.
+
+2009-10-06 Oliver Hunt <oliver@apple.com>
+
+ Windows linking fix
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
+
+2009-10-06 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ Windows build fix.
+
+ * runtime/DateInstance.cpp:
+
+2009-10-05 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ It should be possible to post (clone) built-in JS objects to Workers
+ https://bugs.webkit.org/show_bug.cgi?id=22878
+
+ Expose helpers to throw correct exceptions during object graph walk
+ used for cloning and add a helper function to create Date instances
+ without going through the JS Date constructor function.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::DateInstance):
+ * runtime/DateInstance.h:
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createTypeError):
+ * runtime/ExceptionHelpers.h:
+
+2009-10-06 David Levin <levin@chromium.org>
+
+ Reviewed by Oliver Hunt.
+
+ StringImpl needs a method to get an instance for another thread which doesn't copy the underlying buffer.
+ https://bugs.webkit.org/show_bug.cgi?id=30095
+
+ * wtf/CrossThreadRefCounted.h:
+ Removed an unused function and assert improvement.
+ (WTF::CrossThreadRefCounted::isOwnedByCurrentThread): Moved out common code from asserts.
+ (WTF::CrossThreadRefCounted::ref): Changed assert to use the common method.
+ (WTF::CrossThreadRefCounted::deref): Changed assert to use the common method.
+ (WTF::CrossThreadRefCounted::crossThreadCopy): Since this includes a potentially
+ non-threadsafe operation, add an assert that the class is owned by the current thread.
+
+2009-10-05 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fix. Add Symbian files to the list of excludes.
+
+ * wscript:
+
+2009-10-05 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Remove precompiled header from JavaScriptCore compilation to
+ prevent qmake warning during autonomous compilation.
+ https://bugs.webkit.org/show_bug.cgi?id=30069
+
+ * JavaScriptCore.pro:
+
2009-10-02 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
@@ -88,6 +7495,62 @@
(JSC::JSValue::operator bool): Test for the empty value tag, instead
of testing for the cell tag with a 0 payload.
+2009-10-02 Steve Falkenburg <sfalken@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ <https://bugs.webkit.org/show_bug.cgi?id=29989>
+ Safari version number shouldn't be exposed in WebKit code
+
+ For a WebKit version of 532.3.4:
+ Product version is: 5.32.3.4 (was 4.0.3.0)
+ File version is: 5.32.3.4 (was 4.532.3.4)
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc:
+
+2009-10-02 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Rubber-stamped by Simon Hausmann.
+
+ Fix the Qt on Mac OS X build.
+
+ * wtf/FastMalloc.cpp:
+
+2009-10-02 Jørgen Lind <jorgen.lind@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Allow enabling and disabling of the JIT through a qmake variable.
+
+ Qt's configure may set this variable through .qmake.cache if a
+ commandline option is given and/or the compile test for hwcap.h
+ failed/succeeded.
+
+ * JavaScriptCore.pri:
+
+2009-10-01 Mark Rowe <mrowe@apple.com>
+
+ Fix the Tiger build. Don't unconditionally enable 3D canvas as it is not supported on Tiger.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2009-10-01 Yongjun Zhang <yongjun.zhang@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=29187
+
+ Don't inline ~ListRefPtr() to work around winscw compiler forward declaration
+ bug regarding templated classes.
+
+ The compiler bug is reported at:
+ https://xdabug001.ext.nokia.com/bugzilla/show_bug.cgi?id=9812
+
+ The change will be reverted when the above bug is fixed in winscw compiler.
+
+ * wtf/ListRefPtr.h:
+ (WTF::::~ListRefPtr):
+
2009-10-01 Zoltan Horvath <zoltan@webkit.org>
Reviewed by Simon Hausmann.
@@ -109,6 +7572,25 @@
(WTF::sleep):
* wtf/FastMalloc.h:
+2009-09-30 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by George Staikos.
+
+ Defines two pseudo-platforms for ARM and Thumb-2 instruction set.
+ https://bugs.webkit.org/show_bug.cgi?id=29122
+
+ Introduces WTF_PLATFORM_ARM_TRADITIONAL and WTF_PLATFORM_ARM_THUMB2
+ macros on ARM platforms. The PLATFORM(ARM_THUMB2) should be used
+ when Thumb-2 instruction set is the required target. The
+ PLATFORM(ARM_TRADITIONAL) is for generic ARM instruction set. In
+ case where the code is common the PLATFORM(ARM) have to be used.
+
+ Modified by George Wright <gwright@rim.com> to correctly work
+ with the RVCT-defined __TARGET_ARCH_ARM and __TARGET_ARCH_THUMB
+ compiler macros, as well as adding readability changes.
+
+ * wtf/Platform.h:
+
2009-09-30 Oliver Hunt <oliver@apple.com>
Reviewed by Geoff Garen.
@@ -143,12 +7625,106 @@
Reviewed by Simon Hausmann.
+ Reduce heap size on Symbian from 64MB to 8MB.
+
+ This is not a perfect fix, it requires more fine tuning.
+ But this makes it possible again to debug in the emulator,
+ which is more important in order to be able to fix other
+ run-time issues.
+
+ * runtime/Collector.h:
+
+2009-09-30 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Simon Hausmann.
+
Fix CRASH() macro for Symbian build.
* wtf/Assertions.h: Added missing }
2009-09-29 Geoffrey Garen <ggaren@apple.com>
+ Reviewed by Gavin Barraclough.
+
+ Inlined a few math operations.
+
+ ~1% SunSpider speedup.
+
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ (JSC::JIT::emitSlow_op_add):
+ (JSC::JIT::emitSlow_op_mul):
+ (JSC::JIT::emit_op_sub):
+ (JSC::JIT::emitSlow_op_sub): Don't take a stub call when operating on
+ a constant int and a double.
+
+2009-09-28 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Tidy up codeblock sampler
+ https://bugs.webkit.org/show_bug.cgi?id=29836
+
+ Some rather simple refactoring of codeblock sampler so that
+ it's easier for us to use it to find problems in non-jsc
+ environments
+
+ * JavaScriptCore.exp:
+ * bytecode/SamplingTool.h:
+ * debugger/Debugger.cpp:
+ (JSC::evaluateInGlobalCallFrame):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::evaluate):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::enableSampler):
+ (JSC::Interpreter::dumpSampleData):
+ (JSC::Interpreter::startSampling):
+ (JSC::Interpreter::stopSampling):
+ * interpreter/Interpreter.h:
+ (JSC::Interpreter::sampler):
+ * jit/JIT.h:
+ * jsc.cpp:
+ (runWithScripts):
+ * runtime/Completion.cpp:
+ (JSC::checkSyntax):
+ (JSC::evaluate):
+ * runtime/Executable.h:
+ (JSC::EvalExecutable::EvalExecutable):
+ (JSC::ProgramExecutable::create):
+ (JSC::ProgramExecutable::ProgramExecutable):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::startSampling):
+ (JSC::JSGlobalData::stopSampling):
+ (JSC::JSGlobalData::dumpSampleData):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::globalFuncEval):
+
+2009-09-29 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Add GYP generated files to svn:ignore
+ https://bugs.webkit.org/show_bug.cgi?id=29895
+
+ The following files are generated by JavaScriptCore's GYP file and should be ignored:
+
+ pcre.mk
+ wtf.scons
+ wtf.mk
+ SConstruct
+ wtf_config.scons
+ wtf_config.mk
+ pcre.scons
+
+ * JavaScriptCore.gyp: Changed property svn:ignore.
+
+2009-09-29 Geoffrey Garen <ggaren@apple.com>
+
Reviewed by Sam Weinig.
Standardized an optimization for adding non-numbers.
@@ -159,6 +7735,32 @@
(JSC::JIT::emit_op_add):
(JSC::JIT::emitSlow_op_add):
+2009-09-29 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: export a new symbol.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
+
+2009-09-28 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Removed virtual destructor from JSGlobalObjectData to eliminate pointer
+ fix-ups when accessing JSGlobalObject::d.
+
+ Replaced with an explicit destructor function pointer.
+
+ 6% speedup on bench-alloc-nonretained.js.
+
+ * JavaScriptCore.exp:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::~JSGlobalObject):
+ (JSC::JSGlobalObject::destroyJSGlobalObjectData):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData):
+ (JSC::JSGlobalObject::JSGlobalObject):
+
2009-09-29 Janne Koskinen <janne.p.koskinen@digia.com>
Reviewed by David Kilzer.
@@ -187,6 +7789,12 @@
2009-09-28 Mark Rowe <mrowe@apple.com>
+ Fix the PowerPC build.
+
+ * JavaScriptCore.exp:
+
+2009-09-28 Mark Rowe <mrowe@apple.com>
+
Reviewed by Gavin Barraclough.
<rdar://problem/7195704> JavaScriptCore fails to mark registers when built for x86_64 using LLVM GCC.
@@ -195,22 +7803,175 @@
(JSC::Heap::markCurrentThreadConservatively): Force jmp_buf to use the appropriate alignment for a pointer
to ensure that we correctly interpret the contents of registers during marking.
-2009-09-29 Geoffrey Garen <ggaren@apple.com>
+2009-09-28 Geoffrey Garen <ggaren@apple.com>
- Reviewed by Gavin Barraclough.
+ Windows build fix: added new exports.
- Inlined a few math operations.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
+
+2009-09-28 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: removed exports that no longer exist.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
+
+2009-09-28 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ NotNullPassRefPtr: smart pointer optimized for passing references that are not null
+ https://bugs.webkit.org/show_bug.cgi?id=29822
- ~1% SunSpider speedup.
+ Added NotNullPassRefPtr, and deployed it in all places that initialize
+ JavaScript objects.
+
+ 2.2% speedup on bench-allocate-nonretained.js.
- * jit/JIT.h:
- * jit/JITArithmetic.cpp:
- (JSC::JIT::compileBinaryArithOpSlowCase):
- (JSC::JIT::emitSlow_op_add):
- (JSC::JIT::emitSlow_op_mul):
- (JSC::JIT::emit_op_sub):
- (JSC::JIT::emitSlow_op_sub): Don't take a stub call when operating on
- a constant int and a double.
+ * API/JSCallbackConstructor.cpp:
+ (JSC::JSCallbackConstructor::JSCallbackConstructor):
+ * API/JSCallbackConstructor.h:
+ * API/JSCallbackObject.h:
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::JSCallbackObject::JSCallbackObject):
+ * JavaScriptCore.exp:
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::addFunctionDecl):
+ (JSC::CodeBlock::addFunctionExpr):
+ * runtime/ArrayConstructor.cpp:
+ (JSC::ArrayConstructor::ArrayConstructor):
+ * runtime/ArrayConstructor.h:
+ * runtime/ArrayPrototype.cpp:
+ (JSC::ArrayPrototype::ArrayPrototype):
+ * runtime/ArrayPrototype.h:
+ * 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:
+ * 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):
+ * runtime/FunctionPrototype.h:
+ * runtime/GlobalEvalFunction.cpp:
+ (JSC::GlobalEvalFunction::GlobalEvalFunction):
+ * runtime/GlobalEvalFunction.h:
+ * runtime/InternalFunction.cpp:
+ (JSC::InternalFunction::InternalFunction):
+ * runtime/InternalFunction.h:
+ (JSC::InternalFunction::InternalFunction):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::JSActivation):
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::JSActivationData::JSActivationData):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::JSArray):
+ * runtime/JSArray.h:
+ * runtime/JSByteArray.cpp:
+ (JSC::JSByteArray::JSByteArray):
+ * runtime/JSByteArray.h:
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::JSFunction):
+ * runtime/JSFunction.h:
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::JSGlobalObject):
+ * runtime/JSONObject.h:
+ (JSC::JSONObject::JSONObject):
+ * runtime/JSObject.h:
+ (JSC::JSObject::JSObject):
+ (JSC::JSObject::setStructure):
+ * runtime/JSVariableObject.h:
+ (JSC::JSVariableObject::JSVariableObject):
+ * runtime/JSWrapperObject.h:
+ (JSC::JSWrapperObject::JSWrapperObject):
+ * runtime/MathObject.cpp:
+ (JSC::MathObject::MathObject):
+ * runtime/MathObject.h:
+ * 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:
+ * 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/PropertyNameArray.h:
+ (JSC::PropertyNameArrayData::setCachedPrototypeChain):
+ * runtime/PrototypeFunction.cpp:
+ (JSC::PrototypeFunction::PrototypeFunction):
+ * runtime/PrototypeFunction.h:
+ * runtime/RegExpConstructor.cpp:
+ (JSC::RegExpConstructor::RegExpConstructor):
+ * runtime/RegExpConstructor.h:
+ * runtime/RegExpObject.cpp:
+ (JSC::RegExpObject::RegExpObject):
+ * runtime/RegExpObject.h:
+ (JSC::RegExpObject::RegExpObjectData::RegExpObjectData):
+ * 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:
+ * runtime/StringObjectThatMasqueradesAsUndefined.h:
+ (JSC::StringObjectThatMasqueradesAsUndefined::StringObjectThatMasqueradesAsUndefined):
+ * runtime/StringPrototype.cpp:
+ (JSC::StringPrototype::StringPrototype):
+ * runtime/StringPrototype.h:
+ * wtf/PassRefPtr.h:
+ (WTF::NotNullPassRefPtr::NotNullPassRefPtr):
+ (WTF::NotNullPassRefPtr::~NotNullPassRefPtr):
+ (WTF::NotNullPassRefPtr::get):
+ (WTF::NotNullPassRefPtr::clear):
+ (WTF::NotNullPassRefPtr::releaseRef):
+ (WTF::NotNullPassRefPtr::operator*):
+ (WTF::NotNullPassRefPtr::operator->):
+ (WTF::NotNullPassRefPtr::operator!):
+ (WTF::NotNullPassRefPtr::operator UnspecifiedBoolType):
+ * wtf/RefPtr.h:
+ (WTF::RefPtr::RefPtr):
+ (WTF::operator==):
2009-09-28 Oliver Hunt <oliver@apple.com>
@@ -249,28 +8010,6 @@
* wtf/Platform.h: Add a WTF_USE_QXMLQUERY #define.
-2009-09-28 Yongjun Zhang <yongjun.zhang@nokia.com>
-
- Reviewed by Eric Seidel.
-
- https://bugs.webkit.org/show_bug.cgi?id=28054
-
- Use derefInNotNull() to work around winscw compiler forward declaration bug
- regarding templated classes.
-
- The compiler bug is reported at
- https://xdabug001.ext.nokia.com/bugzilla/show_bug.cgi?id=9812.
-
- The change should be reverted when the above bug is fixed in winscw compiler.
-
- Add parenthesis around (RefPtr::*UnspecifiedBoolType) to make winscw compiler
- work with the default UnSpecifiedBoolType() operator, which removes the winscw hack.
-
- * wtf/RefPtr.h:
- (WTF::RefPtr::~RefPtr):
- (WTF::RefPtr::clear):
- (WTF::RefPtr::operator UnspecifiedBoolType):
-
2009-09-28 Gabor Loki <loki@inf.u-szeged.hu>
Reviewed by Simon Hausmann.
@@ -351,6 +8090,81 @@
* yarr/RegexJIT.cpp:
(JSC::Yarr::RegexGenerator::generatePatternCharacterPair):
+2009-09-25 Jeremy Orlow <jorlow@chromium.org>
+
+ This is breaking Chromium try bots, so I'm counting this as a build fix.
+
+ Add more svn:ignore exceptions. On different platforms, these files are
+ generated with different case for JavaScriptCore. Also there are some
+ wtf project files that get built apparently.
+
+ * JavaScriptCore.gyp: Changed property svn:ignore.
+
+2009-09-25 Ada Chan <adachan@apple.com>
+
+ Build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
+
+2009-09-25 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Inlined some object creation code, including lexicalGlobalObject access
+ https://bugs.webkit.org/show_bug.cgi?id=29750
+
+ SunSpider says 0.5% faster.
+
+ 0.8% speedup on bench-alloc-nonretained.js.
+ 2.5% speedup on v8-splay.js.
+
+ * interpreter/CachedCall.h:
+ (JSC::CachedCall::CachedCall):
+ * interpreter/CallFrame.h:
+ (JSC::ExecState::lexicalGlobalObject):
+ (JSC::ExecState::globalThisValue):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::dumpRegisters):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction):
+ * runtime/ScopeChain.cpp:
+ (JSC::ScopeChainNode::print):
+ * runtime/ScopeChain.h:
+ (JSC::ScopeChainNode::ScopeChainNode):
+ (JSC::ScopeChainNode::~ScopeChainNode):
+ (JSC::ScopeChainNode::push):
+ (JSC::ScopeChain::ScopeChain):
+ (JSC::ScopeChain::globalObject): Added a globalObject data member to ScopeChainNode.
+ Replaced accessor function for globalObject() with data member. Replaced
+ globalThisObject() accessor with direct access to globalThis, to match.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+ * runtime/JSGlobalObject.h: Inlined array and object construction.
+
+2009-09-25 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Add ARM version detection rules for Symbian
+ https://bugs.webkit.org/show_bug.cgi?id=29715
+
+ * wtf/Platform.h:
+
+2009-09-24 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Mark "Do It!" Rowe.
+
+ Some GCC versions don't like C++-style comments in preprocessor
+ directives, change to C-style to shut them up.
+
+ * wtf/Platform.h:
+
2009-09-24 Oliver Hunt <oliver@apple.com>
Reviewed by Gavin Barraclough.
@@ -375,6 +8189,33 @@
(JSC::JIT::emitLoadInt32ToDouble):
(JSC::JIT::emitJumpSlowCaseIfNotImmediateNumber):
+2009-09-24 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Add GYP generated files to svn:ignore
+ https://bugs.webkit.org/show_bug.cgi?id=29724
+
+ Adding the following files to the svn:ignore list (all in the
+ JavaScriptCore/JavaScriptCore.gyp directory)
+
+ JavaScriptCore.xcodeproj
+ JavaScriptCore.sln
+ JavaScriptCore.vcproj
+ JavaScriptCore_Debug.rules
+ JavaScriptCore_Release.rules
+ JavaScriptCore_Release - no tcmalloc.rules
+ JavaScriptCore_Purify.rules
+ JavaScriptCore.mk
+ JavaScriptCore_Debug_rules.mk
+ JavaScriptCore_Release_rules.mk
+ JavaScriptCore_Release - no tcmalloc_rules.mk
+ JavaScriptCore_Purify_rules.mk
+ JavaScriptCore.scons
+ JavaScriptCore_main.scons
+
+ * JavaScriptCore.gyp: Changed property svn:ignore.
+
2009-09-24 Yong Li <yong.li@torchmobile.com>
Reviewed by Adam Barth.
@@ -391,17 +8232,6 @@
2009-09-24 Mark Rowe <mrowe@apple.com>
- Reviewed by Gavin Barraclough.
-
- Fix FastMalloc to build with assertions enabled.
-
- * wtf/FastMalloc.cpp:
- (WTF::TCMalloc_Central_FreeList::ReleaseToSpans):
- * wtf/TCSpinLock.h:
- (TCMalloc_SpinLock::IsHeld):
-
-2009-09-24 Mark Rowe <mrowe@apple.com>
-
Reviewed by Sam Weinig.
<rdar://problem/7215058> FastMalloc scavenging thread should be named
@@ -414,12 +8244,87 @@
2009-09-24 Geoffrey Garen <ggaren@apple.com>
+ Reviewed by Sam Weinig.
+
+ Renamed clear to removeAll, as suggested by Darin Adler.
+
+ * wtf/HashCountedSet.h:
+ (WTF::::removeAll):
+
+2009-09-24 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Fix FastMalloc to build with assertions enabled.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMalloc_Central_FreeList::ReleaseToSpans):
+ * wtf/TCSpinLock.h:
+ (TCMalloc_SpinLock::IsHeld):
+
+2009-09-24 Geoffrey Garen <ggaren@apple.com>
+
Suggested by Darin Adler.
Removed some unnecessary parameter names.
* wtf/HashCountedSet.h:
+2009-09-24 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Simon Hausmann.
+
+ On Windows JSChar is typedef'ed to wchar_t.
+
+ When building with WINSCW for Symbian we need to do the
+ same typedef.
+
+ * API/JSStringRef.h:
+
+2009-09-23 Geoffrey Garen <ggaren@apple.com>
+
+ A piece of my last patch that I forgot.
+
+ * wtf/HashCountedSet.h:
+ (WTF::::clear): Added HashCountedSet::clear.
+
+2009-09-24 Gabor Loki <loki@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ Avoid __clear_cache built-in function if DISABLE_BUILTIN_CLEAR_CACHE define is set
+ https://bugs.webkit.org/show_bug.cgi?id=28886
+
+ There are some GCC packages (for example GCC-2006q3 from CodeSourcery)
+ which contain __clear_cache built-in function only for C while the C++
+ version of __clear_cache is missing on ARM architectures.
+
+ Fixed a small bug in the inline assembly of cacheFlush function on
+ ARM_TRADITIONAL.
+
+ * jit/ExecutableAllocator.h:
+ (JSC::ExecutableAllocator::cacheFlush):
+
+2009-09-23 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Added the ability to swap vectors with inline capacities, so you can
+ store a vector with inline capacity in a hash table.
+
+ * wtf/Vector.h:
+ (WTF::swap):
+ (WTF::VectorBuffer::swap):
+
+2009-09-23 David Kilzer <ddkilzer@apple.com>
+
+ Move definition of USE(PLUGIN_HOST_PROCESS) from WebKitPrefix.h to Platform.h
+
+ Reviewed by Mark Rowe.
+
+ * wtf/Platform.h: Define WTF_USE_PLUGIN_HOST_PROCESS to 1 when
+ building on 64-bit SnowLeopard. Define to 0 elsewhere.
+
2009-09-22 Oliver Hunt <oliver@apple.com>
Reviewed by Geoff Garen.
@@ -474,71 +8379,84 @@
* wtf/Forward.h: Added PassOwnPtr.
-2009-09-22 Simon Hausmann <simon.hausmann@nokia.com>
+2009-09-22 Yaar Schnitman <yaar@chromium.org>
- Unreviewed build fix for Windows CE < 5
+ Reviewed by David Levin.
- Define WINCEBASIC to disable the IsDebuggerPresent() code in
- wtf/Assertions.cpp.
+ Ported chromium.org's javascriptcore.gyp for the webkit chromium port.
- * JavaScriptCore.pri:
+ https://bugs.webkit.org/show_bug.cgi?id=29617
-2009-10-02 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+ * JavaScriptCore.gyp/JavaScriptCore.gyp: Added.
- Rubber-stamped by Simon Hausmann.
+2009-09-22 Thiago Macieira <thiago.macieira@nokia.com>
- Fix the Qt on Mac OS X build.
+ Reviewed by Simon Hausmann.
- * wtf/FastMalloc.cpp:
+ Fix compilation with WINSCW: no varargs macros
-2009-10-02 Jørgen Lind <jorgen.lind@nokia.com>
+ Disable variadic arguments for WINSCW just like we do
+ for MSVC7.
+
+ * wtf/Assertions.h:
+
+2009-09-22 Kent Hansen <khansen@trolltech.com>
Reviewed by Simon Hausmann.
- Allow enabling and disabling of the JIT through a qmake variable.
+ Disable variadic macros on MSVC7.
- Qt's configure may set this variable through .qmake.cache if a
- commandline option is given and/or the compile test for hwcap.h
- failed/succeeded.
+ This was originally added in r26589 but not extended
+ when LOG_DISABLED/ASSERT_DISABLED was introduced.
+
+ * wtf/Assertions.h:
+
+2009-09-22 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Unreviewed build fix for Windows CE < 5
+
+ Define WINCEBASIC to disable the IsDebuggerPresent() code in
+ wtf/Assertions.cpp.
* JavaScriptCore.pri:
-2009-09-23 Geoffrey Garen <ggaren@apple.com>
+2009-09-22 Joerg Bornemann <joerg.bornemann@nokia.com>
- A piece of my last patch that I forgot.
+ Reviewed by Simon Hausmann.
- * wtf/HashCountedSet.h:
- (WTF::::clear): Added HashCountedSet::clear.
+ Fix major memory leak in JavaScriptCore RegisterFile on Windows CE
-2009-09-24 Gabor Loki <loki@inf.u-szeged.hu>
+ https://bugs.webkit.org/show_bug.cgi?id=29367
- Reviewed by Gavin Barraclough.
+ On Widows CE we must decommit all committed pages before we release
+ them. See VirtualFree documentation.
+ Desktop Windows behaves much smoother in this situation.
- Reduce heap size on Symbian from 64MB to 8MB.
+ * interpreter/RegisterFile.cpp:
+ (JSC::RegisterFile::~RegisterFile):
- This is not a perfect fix, it requires more fine tuning.
- But this makes it possible again to debug in the emulator,
- which is more important in order to be able to fix other
- run-time issues.
+2009-09-21 Greg Bolsinga <bolsinga@apple.com>
- * runtime/Collector.h:
+ Reviewed by Simon Fraser & Sam Weinig.
-2009-09-30 Janne Koskinen <janne.p.koskinen@digia.com>
+ Add ENABLE(ORIENTATION_EVENTS)
+ https://bugs.webkit.org/show_bug.cgi?id=29508
- Reviewed by Simon Hausmann.
+ * wtf/Platform.h: Also sort PLATFORM(IPHONE) #defines.
- Avoid __clear_cache built-in function if DISABLE_BUILTIN_CLEAR_CACHE define is set
- https://bugs.webkit.org/show_bug.cgi?id=28886
+2009-09-21 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
- There are some GCC packages (for example GCC-2006q3 from CodeSourcery)
- which contain __clear_cache built-in function only for C while the C++
- version of __clear_cache is missing on ARM architectures.
+ Reviewed by Eric Seidel.
- Fixed a small bug in the inline assembly of cacheFlush function on
- ARM_TRADITIONAL.
+ [Fix] SourceCode's uninitialized member
+
+ Potential source of crashes and bugs was fixed. Default constructor
+ didn't initialized m_provider member.
- * jit/ExecutableAllocator.h:
- (JSC::ExecutableAllocator::cacheFlush):
+ https://bugs.webkit.org/show_bug.cgi?id=29364
+
+ * parser/SourceCode.h:
+ (JSC::SourceCode::SourceCode):
2009-09-21 Oliver Hunt <oliver@apple.com>
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/Info.plist b/src/3rdparty/javascriptcore/JavaScriptCore/Info.plist
index 17949b0..77c9eb8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/Info.plist
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/Info.plist
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleGetInfoString</key>
- <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>
+ <string>${BUNDLE_VERSION}, Copyright 2003-2010 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/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.gypi b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.gypi
index 15a0c0f..24577da 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.gypi
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.gypi
@@ -1,7 +1,6 @@
{
'variables': {
'javascriptcore_files': [
- 'AllInOneFile.cpp',
'API/APICast.h',
'API/JavaScript.h',
'API/JavaScriptCore.h',
@@ -19,6 +18,7 @@
'API/JSClassRef.h',
'API/JSContextRef.cpp',
'API/JSContextRef.h',
+ 'API/JSContextRefPrivate.h',
'API/JSObjectRef.cpp',
'API/JSObjectRef.h',
'API/JSProfilerPrivate.cpp',
@@ -64,6 +64,7 @@
'bytecode/StructureStubInfo.h',
'bytecompiler/BytecodeGenerator.cpp',
'bytecompiler/BytecodeGenerator.h',
+ 'bytecompiler/NodesCodegen.cpp',
'bytecompiler/Label.h',
'bytecompiler/LabelScope.h',
'bytecompiler/RegisterID.h',
@@ -148,8 +149,6 @@
'pcre/ucpinternal.h',
'pcre/ucptable.cpp',
'profiler/CallIdentifier.h',
- 'profiler/HeavyProfile.cpp',
- 'profiler/HeavyProfile.h',
'profiler/Profile.cpp',
'profiler/Profile.h',
'profiler/ProfileGenerator.cpp',
@@ -159,8 +158,6 @@
'profiler/Profiler.cpp',
'profiler/Profiler.h',
'profiler/ProfilerServer.h',
- 'profiler/TreeProfile.cpp',
- 'profiler/TreeProfile.h',
'runtime/ArgList.cpp',
'runtime/ArgList.h',
'runtime/Arguments.cpp',
@@ -194,6 +191,7 @@
'runtime/DateConversion.h',
'runtime/DateInstance.cpp',
'runtime/DateInstance.h',
+ 'runtime/DateInstanceCache.h',
'runtime/DatePrototype.cpp',
'runtime/DatePrototype.h',
'runtime/Error.cpp',
@@ -331,6 +329,7 @@
'runtime/Tracing.h',
'runtime/UString.cpp',
'runtime/UString.h',
+ 'runtime/WeakRandom.h',
'wrec/CharacterClass.cpp',
'wrec/CharacterClass.h',
'wrec/CharacterClassConstructor.cpp',
@@ -368,8 +367,8 @@
'wtf/FastMalloc.h',
'wtf/Forward.h',
'wtf/GetPtr.h',
- 'wtf/GOwnPtr.cpp',
- 'wtf/GOwnPtr.h',
+ 'wtf/gtk/GOwnPtr.cpp',
+ 'wtf/gtk/GOwnPtr.h',
'wtf/gtk/MainThreadGtk.cpp',
'wtf/gtk/ThreadingGtk.cpp',
'wtf/HashCountedSet.h',
@@ -399,8 +398,6 @@
'wtf/PassRefPtr.h',
'wtf/Platform.h',
'wtf/PtrAndFlags.h',
- 'wtf/qt/MainThreadQt.cpp',
- 'wtf/qt/ThreadingQt.cpp',
'wtf/RandomNumber.cpp',
'wtf/RandomNumber.h',
'wtf/RandomNumberSeed.h',
@@ -413,11 +410,16 @@
'wtf/SegmentedVector.h',
'wtf/StdLibExtras.h',
'wtf/StringExtras.h',
+ 'wtf/StringHashFunctions.h',
'wtf/TCPackedCache.h',
+ 'wtf/qt/MainThreadQt.cpp',
+ 'wtf/qt/ThreadingQt.cpp',
'wtf/TCPageMap.h',
'wtf/TCSpinLock.h',
'wtf/TCSystemAlloc.cpp',
'wtf/TCSystemAlloc.h',
+ 'wtf/ThreadIdentifierDataPthreads.cpp',
+ 'wtf/ThreadIdentifierDataPthreads.h',
'wtf/Threading.cpp',
'wtf/Threading.h',
'wtf/ThreadingNone.cpp',
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.order b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.order
index 3ae3ec6..d6f6caa 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.order
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.order
@@ -1625,7 +1625,6 @@ __ZN3JSC18EmptyStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10Registe
__ZN3JSCL27compareByStringPairForQSortEPKvS1_
__Z22jsc_pcre_ucp_othercasej
__ZN3JSCL35objectProtoFuncPropertyIsEnumerableEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC8JSObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
__ZN3WTF7HashMapIjN3JSC7JSValueENS_7IntHashIjEENS_10HashTraitsIjEENS5_IS2_EEE3setERKjRKS2_
__ZN3WTF9HashTableIjSt4pairIjN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEE
__ZN3JSC12RegisterFile21releaseExcessCapacityEv
@@ -1841,7 +1840,6 @@ __ZN3JSC6JSCell14toThisJSStringEPNS_9ExecStateE
__ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE
__ZN3JSCL27objectProtoFuncLookupSetterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
__ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
-__ZNK3JSC16JSVariableObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
__ZN3JSC9ExecState22regExpConstructorTableEPS0_
__ZN3JSCL24regExpConstructorDollar7EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
__ZN3JSCL24regExpConstructorDollar8EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri
index a6fb2f8..75737ae 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri
@@ -1,14 +1,23 @@
# JavaScriptCore - Qt4 build info
VPATH += $$PWD
+CONFIG(standalone_package) {
+ isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = $$PWD/generated
+} else {
+ isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = generated
+}
+
CONFIG(debug, debug|release) {
- isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = generated$${QMAKE_DIR_SEP}debug
OBJECTS_DIR = obj/debug
} else { # Release
- isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = generated$${QMAKE_DIR_SEP}release
OBJECTS_DIR = obj/release
}
+symbian: {
+ # Need to guarantee this comes before system includes of /epoc32/include
+ MMP_RULES += "USERINCLUDE ../JavaScriptCore/profiler"
+}
+
INCLUDEPATH = \
$$PWD \
$$PWD/.. \
@@ -19,6 +28,7 @@ INCLUDEPATH = \
$$PWD/interpreter \
$$PWD/jit \
$$PWD/parser \
+ $$PWD/pcre \
$$PWD/profiler \
$$PWD/runtime \
$$PWD/wrec \
@@ -27,12 +37,11 @@ INCLUDEPATH = \
$$PWD/yarr \
$$PWD/API \
$$PWD/ForwardingHeaders \
- $$GENERATED_SOURCES_DIR \
+ $$JSC_GENERATED_SOURCES_DIR \
$$INCLUDEPATH
DEFINES += BUILDING_QT__ BUILDING_JavaScriptCore BUILDING_WTF
-GENERATED_SOURCES_DIR_SLASH = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}
win32-* {
LIBS += -lwinmm
}
@@ -47,11 +56,6 @@ contains(JAVASCRIPTCORE_JIT,no) {
DEFINES+=ENABLE_YARR=0
}
-# In debug mode JIT disabled until crash fixed
-win32-* {
- CONFIG(debug):!contains(DEFINES, ENABLE_JIT=1): DEFINES+=ENABLE_JIT=0
-}
-
# Rules when JIT enabled (not disabled)
!contains(DEFINES, ENABLE_JIT=0) {
linux*-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,0) {
@@ -68,33 +72,7 @@ wince* {
include(pcre/pcre.pri)
-LUT_FILES += \
- runtime/DatePrototype.cpp \
- runtime/JSONObject.cpp \
- runtime/NumberConstructor.cpp \
- runtime/StringPrototype.cpp \
- runtime/ArrayPrototype.cpp \
- runtime/MathObject.cpp \
- runtime/RegExpConstructor.cpp \
- runtime/RegExpObject.cpp
-
-KEYWORDLUT_FILES += \
- parser/Keywords.table
-
-JSCBISON += \
- parser/Grammar.y
-
SOURCES += \
- wtf/Assertions.cpp \
- wtf/ByteArray.cpp \
- wtf/HashTable.cpp \
- wtf/MainThread.cpp \
- wtf/RandomNumber.cpp \
- wtf/RefCountedLeakCounter.cpp \
- wtf/TypeTraits.cpp \
- wtf/unicode/CollatorDefault.cpp \
- wtf/unicode/icu/CollatorICU.cpp \
- wtf/unicode/UTF8.cpp \
API/JSBase.cpp \
API/JSCallbackConstructor.cpp \
API/JSCallbackFunction.cpp \
@@ -105,55 +83,39 @@ SOURCES += \
API/JSStringRef.cpp \
API/JSValueRef.cpp \
API/OpaqueJSString.cpp \
- runtime/InitializeThreading.cpp \
- runtime/JSGlobalData.cpp \
- runtime/JSGlobalObject.cpp \
- runtime/JSStaticScopeObject.cpp \
- runtime/JSVariableObject.cpp \
- runtime/JSActivation.cpp \
- runtime/JSNotAnObject.cpp \
- runtime/JSONObject.cpp \
- runtime/LiteralParser.cpp \
- runtime/MarkStack.cpp \
- runtime/TimeoutChecker.cpp \
- bytecode/CodeBlock.cpp \
- bytecode/StructureStubInfo.cpp \
- bytecode/JumpTable.cpp \
assembler/ARMAssembler.cpp \
assembler/MacroAssemblerARM.cpp \
- jit/JIT.cpp \
- jit/JITCall.cpp \
+ bytecode/CodeBlock.cpp \
+ bytecode/JumpTable.cpp \
+ bytecode/Opcode.cpp \
+ bytecode/SamplingTool.cpp \
+ bytecode/StructureStubInfo.cpp \
+ bytecompiler/BytecodeGenerator.cpp \
+ bytecompiler/NodesCodegen.cpp \
+ debugger/DebuggerActivation.cpp \
+ debugger/DebuggerCallFrame.cpp \
+ debugger/Debugger.cpp \
+ interpreter/CallFrame.cpp \
+ interpreter/Interpreter.cpp \
+ interpreter/RegisterFile.cpp \
+ jit/ExecutableAllocatorPosix.cpp \
+ jit/ExecutableAllocatorSymbian.cpp \
+ jit/ExecutableAllocatorWin.cpp \
+ jit/ExecutableAllocator.cpp \
jit/JITArithmetic.cpp \
+ jit/JITCall.cpp \
+ jit/JIT.cpp \
jit/JITOpcodes.cpp \
jit/JITPropertyAccess.cpp \
- jit/ExecutableAllocator.cpp \
jit/JITStubs.cpp \
- bytecompiler/BytecodeGenerator.cpp \
- runtime/ExceptionHelpers.cpp \
- runtime/JSPropertyNameIterator.cpp \
- interpreter/Interpreter.cpp \
- bytecode/Opcode.cpp \
- bytecode/SamplingTool.cpp \
- yarr/RegexCompiler.cpp \
- yarr/RegexInterpreter.cpp \
- yarr/RegexJIT.cpp \
- interpreter/RegisterFile.cpp
-
-win32-*|wince* {
- SOURCES += jit/ExecutableAllocatorWin.cpp \
- runtime/MarkStackWin.cpp
-} else {
- SOURCES += jit/ExecutableAllocatorPosix.cpp \
- runtime/MarkStackPosix.cpp
-}
-
-!contains(DEFINES, USE_SYSTEM_MALLOC) {
- SOURCES += wtf/TCSystemAlloc.cpp
-}
-
-# AllInOneFile.cpp helps gcc analize and optimize code
-# Other compilers may be able to do this at link time
-SOURCES += \
+ parser/Lexer.cpp \
+ parser/Nodes.cpp \
+ parser/ParserArena.cpp \
+ parser/Parser.cpp \
+ profiler/Profile.cpp \
+ profiler/ProfileGenerator.cpp \
+ profiler/ProfileNode.cpp \
+ profiler/Profiler.cpp \
runtime/ArgList.cpp \
runtime/Arguments.cpp \
runtime/ArrayConstructor.cpp \
@@ -164,62 +126,67 @@ SOURCES += \
runtime/CallData.cpp \
runtime/Collector.cpp \
runtime/CommonIdentifiers.cpp \
+ runtime/Completion.cpp \
runtime/ConstructData.cpp \
- wtf/CurrentTime.cpp \
runtime/DateConstructor.cpp \
runtime/DateConversion.cpp \
runtime/DateInstance.cpp \
runtime/DatePrototype.cpp \
- debugger/Debugger.cpp \
- debugger/DebuggerCallFrame.cpp \
- debugger/DebuggerActivation.cpp \
- wtf/dtoa.cpp \
- runtime/Error.cpp \
runtime/ErrorConstructor.cpp \
+ runtime/Error.cpp \
runtime/ErrorInstance.cpp \
runtime/ErrorPrototype.cpp \
- interpreter/CallFrame.cpp \
+ runtime/ExceptionHelpers.cpp \
runtime/Executable.cpp \
runtime/FunctionConstructor.cpp \
runtime/FunctionPrototype.cpp \
runtime/GetterSetter.cpp \
runtime/GlobalEvalFunction.cpp \
runtime/Identifier.cpp \
+ runtime/InitializeThreading.cpp \
runtime/InternalFunction.cpp \
- runtime/Completion.cpp \
- runtime/JSArray.cpp \
+ runtime/JSActivation.cpp \
runtime/JSAPIValueWrapper.cpp \
+ runtime/JSArray.cpp \
runtime/JSByteArray.cpp \
runtime/JSCell.cpp \
runtime/JSFunction.cpp \
+ runtime/JSGlobalData.cpp \
+ runtime/JSGlobalObject.cpp \
runtime/JSGlobalObjectFunctions.cpp \
runtime/JSImmediate.cpp \
runtime/JSLock.cpp \
+ runtime/JSNotAnObject.cpp \
runtime/JSNumberCell.cpp \
runtime/JSObject.cpp \
+ runtime/JSONObject.cpp \
+ runtime/JSPropertyNameIterator.cpp \
+ runtime/JSStaticScopeObject.cpp \
runtime/JSString.cpp \
runtime/JSValue.cpp \
+ runtime/JSVariableObject.cpp \
runtime/JSWrapperObject.cpp \
- parser/Lexer.cpp \
+ runtime/LiteralParser.cpp \
runtime/Lookup.cpp \
+ runtime/MarkStackPosix.cpp \
+ runtime/MarkStackSymbian.cpp \
+ runtime/MarkStackWin.cpp \
+ runtime/MarkStack.cpp \
runtime/MathObject.cpp \
runtime/NativeErrorConstructor.cpp \
runtime/NativeErrorPrototype.cpp \
- parser/Nodes.cpp \
runtime/NumberConstructor.cpp \
runtime/NumberObject.cpp \
runtime/NumberPrototype.cpp \
runtime/ObjectConstructor.cpp \
runtime/ObjectPrototype.cpp \
runtime/Operations.cpp \
- parser/Parser.cpp \
- parser/ParserArena.cpp \
runtime/PropertyDescriptor.cpp \
runtime/PropertyNameArray.cpp \
runtime/PropertySlot.cpp \
runtime/PrototypeFunction.cpp \
- runtime/RegExp.cpp \
runtime/RegExpConstructor.cpp \
+ runtime/RegExp.cpp \
runtime/RegExpObject.cpp \
runtime/RegExpPrototype.cpp \
runtime/ScopeChain.cpp \
@@ -227,50 +194,38 @@ SOURCES += \
runtime/StringConstructor.cpp \
runtime/StringObject.cpp \
runtime/StringPrototype.cpp \
- runtime/Structure.cpp \
runtime/StructureChain.cpp \
+ runtime/Structure.cpp \
+ runtime/TimeoutChecker.cpp \
runtime/UString.cpp \
- profiler/HeavyProfile.cpp \
- profiler/Profile.cpp \
- profiler/ProfileGenerator.cpp \
- profiler/ProfileNode.cpp \
- profiler/Profiler.cpp \
- profiler/TreeProfile.cpp \
+ runtime/UStringImpl.cpp \
+ wtf/Assertions.cpp \
+ wtf/ByteArray.cpp \
+ wtf/CurrentTime.cpp \
wtf/DateMath.cpp \
+ wtf/dtoa.cpp \
wtf/FastMalloc.cpp \
+ wtf/HashTable.cpp \
+ wtf/MainThread.cpp \
+ wtf/qt/MainThreadQt.cpp \
+ wtf/qt/ThreadingQt.cpp \
+ wtf/RandomNumber.cpp \
+ wtf/RefCountedLeakCounter.cpp \
+ wtf/ThreadingNone.cpp \
wtf/Threading.cpp \
- wtf/qt/MainThreadQt.cpp
-
-!contains(DEFINES, ENABLE_SINGLE_THREADED=1) {
- SOURCES += wtf/qt/ThreadingQt.cpp
-} else {
- DEFINES += ENABLE_JSC_MULTIPLE_THREADS=0
- SOURCES += wtf/ThreadingNone.cpp
-}
-
-# GENERATOR 1-A: LUT creator
-lut.output = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.lut.h
-lut.commands = perl $$PWD/create_hash_table ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT}
-lut.depend = ${QMAKE_FILE_NAME}
-lut.input = LUT_FILES
-lut.CONFIG += no_link
-addExtraCompiler(lut)
+ wtf/TypeTraits.cpp \
+ wtf/unicode/CollatorDefault.cpp \
+ wtf/unicode/icu/CollatorICU.cpp \
+ wtf/unicode/UTF8.cpp \
+ yarr/RegexCompiler.cpp \
+ yarr/RegexInterpreter.cpp \
+ yarr/RegexJIT.cpp
-# GENERATOR 1-B: particular LUT creator (for 1 file only)
-keywordlut.output = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}Lexer.lut.h
-keywordlut.commands = perl $$PWD/create_hash_table ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT}
-keywordlut.depend = ${QMAKE_FILE_NAME}
-keywordlut.input = KEYWORDLUT_FILES
-keywordlut.CONFIG += no_link
-addExtraCompiler(keywordlut)
+# Generated files, simply list them for JavaScriptCore
+SOURCES += \
+ $${JSC_GENERATED_SOURCES_DIR}/Grammar.cpp
-# GENERATOR 2: bison grammar
-jscbison.output = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.cpp
-jscbison.commands = bison -d -p jscyy ${QMAKE_FILE_NAME} -o $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.c && $(MOVE) $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.c ${QMAKE_FILE_OUT} && $(MOVE) $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.h $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.h
-jscbison.depend = ${QMAKE_FILE_NAME}
-jscbison.input = JSCBISON
-jscbison.variable_out = GENERATED_SOURCES
-jscbison.dependency_type = TYPE_C
-jscbison.CONFIG = target_predeps
-addExtraCompilerWithHeader(jscbison)
+!contains(DEFINES, USE_SYSTEM_MALLOC) {
+ SOURCES += wtf/TCSystemAlloc.cpp
+}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.cpp
index 1324586..6dd2b87 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.cpp
@@ -26,7 +26,7 @@
#include "config.h"
-#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL)
+#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
#include "ARMAssembler.h"
@@ -34,39 +34,6 @@ namespace JSC {
// Patching helpers
-ARMWord* ARMAssembler::getLdrImmAddress(ARMWord* insn, uint32_t* constPool)
-{
- // Must be an ldr ..., [pc +/- imm]
- ASSERT((*insn & 0x0f7f0000) == 0x051f0000);
-
- if (constPool && (*insn & 0x1))
- return reinterpret_cast<ARMWord*>(constPool + ((*insn & SDT_OFFSET_MASK) >> 1));
-
- ARMWord addr = reinterpret_cast<ARMWord>(insn) + 2 * sizeof(ARMWord);
- if (*insn & DT_UP)
- return reinterpret_cast<ARMWord*>(addr + (*insn & SDT_OFFSET_MASK));
- else
- return reinterpret_cast<ARMWord*>(addr - (*insn & SDT_OFFSET_MASK));
-}
-
-void ARMAssembler::linkBranch(void* code, JmpSrc from, void* to, int useConstantPool)
-{
- ARMWord* insn = reinterpret_cast<ARMWord*>(code) + (from.m_offset / sizeof(ARMWord));
-
- if (!useConstantPool) {
- int diff = reinterpret_cast<ARMWord*>(to) - reinterpret_cast<ARMWord*>(insn + 2);
-
- if ((diff <= BOFFSET_MAX && diff >= BOFFSET_MIN)) {
- *insn = B | getConditionalField(*insn) | (diff & BRANCH_MASK);
- ExecutableAllocator::cacheFlush(insn, sizeof(ARMWord));
- return;
- }
- }
- ARMWord* addr = getLdrImmAddress(insn);
- *addr = reinterpret_cast<ARMWord>(to);
- ExecutableAllocator::cacheFlush(addr, sizeof(ARMWord));
-}
-
void ARMAssembler::patchConstantPoolLoad(void* loadAddr, void* constPoolAddr)
{
ARMWord *ldr = reinterpret_cast<ARMWord*>(loadAddr);
@@ -118,7 +85,7 @@ ARMWord ARMAssembler::getOp2(ARMWord imm)
if ((imm & 0x00ffffff) == 0)
return OP2_IMM | (imm >> 24) | (rol << 8);
- return 0;
+ return INVALID_IMM;
}
int ARMAssembler::genInt(int reg, ARMWord imm, bool positive)
@@ -236,25 +203,18 @@ ARMWord ARMAssembler::getImm(ARMWord imm, int tmpReg, bool invert)
// Do it by 1 instruction
tmp = getOp2(imm);
- if (tmp)
+ if (tmp != INVALID_IMM)
return tmp;
tmp = getOp2(~imm);
- if (tmp) {
+ if (tmp != INVALID_IMM) {
if (invert)
return tmp | OP2_INV_IMM;
mvn_r(tmpReg, tmp);
return tmpReg;
}
- // Do it by 2 instruction
- if (genInt(tmpReg, imm, true))
- return tmpReg;
- if (genInt(tmpReg, ~imm, false))
- return tmpReg;
-
- ldr_imm(tmpReg, imm);
- return tmpReg;
+ return encodeComplexImm(imm, tmpReg);
}
void ARMAssembler::moveImm(ARMWord imm, int dest)
@@ -263,24 +223,41 @@ void ARMAssembler::moveImm(ARMWord imm, int dest)
// Do it by 1 instruction
tmp = getOp2(imm);
- if (tmp) {
+ if (tmp != INVALID_IMM) {
mov_r(dest, tmp);
return;
}
tmp = getOp2(~imm);
- if (tmp) {
+ if (tmp != INVALID_IMM) {
mvn_r(dest, tmp);
return;
}
+ encodeComplexImm(imm, dest);
+}
+
+ARMWord ARMAssembler::encodeComplexImm(ARMWord imm, int dest)
+{
+#if WTF_ARM_ARCH_AT_LEAST(7)
+ ARMWord tmp = getImm16Op2(imm);
+ if (tmp != INVALID_IMM) {
+ movw_r(dest, tmp);
+ return dest;
+ }
+ movw_r(dest, getImm16Op2(imm & 0xffff));
+ movt_r(dest, getImm16Op2(imm >> 16));
+ return dest;
+#else
// Do it by 2 instruction
if (genInt(dest, imm, true))
- return;
+ return dest;
if (genInt(dest, ~imm, false))
- return;
+ return dest;
ldr_imm(dest, imm);
+ return dest;
+#endif
}
// Memory load/store helpers
@@ -378,10 +355,17 @@ void* ARMAssembler::executableCopy(ExecutablePool* allocator)
// The last bit is set if the constant must be placed on constant pool.
int pos = (*iter) & (~0x1);
ARMWord* ldrAddr = reinterpret_cast<ARMWord*>(data + pos);
- ARMWord offset = *getLdrImmAddress(ldrAddr);
- if (offset != 0xffffffff) {
- JmpSrc jmpSrc(pos);
- linkBranch(data, jmpSrc, data + offset, ((*iter) & 1));
+ ARMWord* addr = getLdrImmAddress(ldrAddr);
+ if (*addr != 0xffffffff) {
+ if (!(*iter & 1)) {
+ int diff = reinterpret_cast<ARMWord*>(data + *addr) - (ldrAddr + DefaultPrefetching);
+
+ if ((diff <= BOFFSET_MAX && diff >= BOFFSET_MIN)) {
+ *ldrAddr = B | getConditionalField(*ldrAddr) | (diff & BRANCH_MASK);
+ continue;
+ }
+ }
+ *addr = reinterpret_cast<ARMWord>(data + *addr);
}
}
@@ -390,4 +374,4 @@ void* ARMAssembler::executableCopy(ExecutablePool* allocator)
} // namespace JSC
-#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL)
+#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.h
index 9f9a450..6967b37 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMAssembler.h
@@ -29,7 +29,7 @@
#include <wtf/Platform.h>
-#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL)
+#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
#include "AssemblerBufferWithConstantPool.h"
#include <wtf/Assertions.h>
@@ -121,6 +121,7 @@ namespace JSC {
MUL = 0x00000090,
MULL = 0x00c00090,
FADDD = 0x0e300b00,
+ FDIVD = 0x0e800b00,
FSUBD = 0x0e300b40,
FMULD = 0x0e200b00,
FCMPD = 0x0eb40b40,
@@ -133,12 +134,18 @@ namespace JSC {
B = 0x0a000000,
BL = 0x0b000000,
FMSR = 0x0e000a10,
+ FMRS = 0x0e100a10,
FSITOD = 0x0eb80bc0,
+ FTOSID = 0x0ebd0b40,
FMSTAT = 0x0ef1fa10,
-#if ARM_ARCH_VERSION >= 5
+#if WTF_ARM_ARCH_AT_LEAST(5)
CLZ = 0x016f0f10,
BKPT = 0xe120070,
#endif
+#if WTF_ARM_ARCH_AT_LEAST(7)
+ MOVW = 0x03000000,
+ MOVT = 0x03400000,
+#endif
};
enum {
@@ -175,6 +182,9 @@ namespace JSC {
padForAlign32 = 0xee120070,
};
+ static const ARMWord INVALID_IMM = 0xf0000000;
+ static const int DefaultPrefetching = 2;
+
class JmpSrc {
friend class ARMAssembler;
public:
@@ -333,6 +343,20 @@ namespace JSC {
emitInst(static_cast<ARMWord>(cc) | MOV, rd, ARMRegisters::r0, op2);
}
+#if WTF_ARM_ARCH_AT_LEAST(7)
+ void movw_r(int rd, ARMWord op2, Condition cc = AL)
+ {
+ ASSERT((op2 | 0xf0fff) == 0xf0fff);
+ m_buffer.putInt(static_cast<ARMWord>(cc) | MOVW | RD(rd) | op2);
+ }
+
+ void movt_r(int rd, ARMWord op2, Condition cc = AL)
+ {
+ ASSERT((op2 | 0xf0fff) == 0xf0fff);
+ m_buffer.putInt(static_cast<ARMWord>(cc) | MOVT | RD(rd) | op2);
+ }
+#endif
+
void movs_r(int rd, ARMWord op2, Condition cc = AL)
{
emitInst(static_cast<ARMWord>(cc) | MOV | SET_CC, rd, ARMRegisters::r0, op2);
@@ -378,6 +402,11 @@ namespace JSC {
emitInst(static_cast<ARMWord>(cc) | FADDD, dd, dn, dm);
}
+ void fdivd_r(int dd, int dn, int dm, Condition cc = AL)
+ {
+ emitInst(static_cast<ARMWord>(cc) | FDIVD, dd, dn, dm);
+ }
+
void fsubd_r(int dd, int dn, int dm, Condition cc = AL)
{
emitInst(static_cast<ARMWord>(cc) | FSUBD, dd, dn, dm);
@@ -482,17 +511,27 @@ namespace JSC {
emitInst(static_cast<ARMWord>(cc) | FMSR, rn, dd, 0);
}
+ void fmrs_r(int rd, int dn, Condition cc = AL)
+ {
+ emitInst(static_cast<ARMWord>(cc) | FMRS, rd, dn, 0);
+ }
+
void fsitod_r(int dd, int dm, Condition cc = AL)
{
emitInst(static_cast<ARMWord>(cc) | FSITOD, dd, 0, dm);
}
+ void ftosid_r(int fd, int dm, Condition cc = AL)
+ {
+ emitInst(static_cast<ARMWord>(cc) | FTOSID, fd, 0, dm);
+ }
+
void fmstat(Condition cc = AL)
{
m_buffer.putInt(static_cast<ARMWord>(cc) | FMSTAT);
}
-#if ARM_ARCH_VERSION >= 5
+#if WTF_ARM_ARCH_AT_LEAST(5)
void clz_r(int rd, int rm, Condition cc = AL)
{
m_buffer.putInt(static_cast<ARMWord>(cc) | CLZ | RD(rd) | RM(rm));
@@ -501,7 +540,7 @@ namespace JSC {
void bkpt(ARMWord value)
{
-#if ARM_ARCH_VERSION >= 5
+#if WTF_ARM_ARCH_AT_LEAST(5)
m_buffer.putInt(BKPT | ((value & 0xff0) << 4) | (value & 0xf));
#else
// Cannot access to Zero memory address
@@ -594,15 +633,32 @@ namespace JSC {
// Patching helpers
- static ARMWord* getLdrImmAddress(ARMWord* insn, uint32_t* constPool = 0);
- static void linkBranch(void* code, JmpSrc from, void* to, int useConstantPool = 0);
+ static ARMWord* getLdrImmAddress(ARMWord* insn)
+ {
+ // Must be an ldr ..., [pc +/- imm]
+ ASSERT((*insn & 0x0f7f0000) == 0x051f0000);
+
+ ARMWord addr = reinterpret_cast<ARMWord>(insn) + DefaultPrefetching * sizeof(ARMWord);
+ if (*insn & DT_UP)
+ return reinterpret_cast<ARMWord*>(addr + (*insn & SDT_OFFSET_MASK));
+ return reinterpret_cast<ARMWord*>(addr - (*insn & SDT_OFFSET_MASK));
+ }
+
+ static ARMWord* getLdrImmAddressOnPool(ARMWord* insn, uint32_t* constPool)
+ {
+ // Must be an ldr ..., [pc +/- imm]
+ ASSERT((*insn & 0x0f7f0000) == 0x051f0000);
+
+ if (*insn & 0x1)
+ return reinterpret_cast<ARMWord*>(constPool + ((*insn & SDT_OFFSET_MASK) >> 1));
+ return getLdrImmAddress(insn);
+ }
static void patchPointerInternal(intptr_t from, void* to)
{
ARMWord* insn = reinterpret_cast<ARMWord*>(from);
ARMWord* addr = getLdrImmAddress(insn);
*addr = reinterpret_cast<ARMWord>(to);
- ExecutableAllocator::cacheFlush(addr, sizeof(ARMWord));
}
static ARMWord patchConstantPoolLoad(ARMWord load, ARMWord value)
@@ -647,12 +703,13 @@ namespace JSC {
void linkJump(JmpSrc from, JmpDst to)
{
ARMWord* insn = reinterpret_cast<ARMWord*>(m_buffer.data()) + (from.m_offset / sizeof(ARMWord));
- *getLdrImmAddress(insn, m_buffer.poolAddress()) = static_cast<ARMWord>(to.m_offset);
+ ARMWord* addr = getLdrImmAddressOnPool(insn, m_buffer.poolAddress());
+ *addr = static_cast<ARMWord>(to.m_offset);
}
static void linkJump(void* code, JmpSrc from, void* to)
{
- linkBranch(code, from, to);
+ patchPointerInternal(reinterpret_cast<intptr_t>(code) + from.m_offset, to);
}
static void relinkJump(void* from, void* to)
@@ -662,12 +719,12 @@ namespace JSC {
static void linkCall(void* code, JmpSrc from, void* to)
{
- linkBranch(code, from, to, true);
+ patchPointerInternal(reinterpret_cast<intptr_t>(code) + from.m_offset, to);
}
static void relinkCall(void* from, void* to)
{
- relinkJump(from, to);
+ patchPointerInternal(reinterpret_cast<intptr_t>(from) - sizeof(ARMWord), to);
}
// Address operations
@@ -708,8 +765,18 @@ namespace JSC {
}
static ARMWord getOp2(ARMWord imm);
+
+#if WTF_ARM_ARCH_AT_LEAST(7)
+ static ARMWord getImm16Op2(ARMWord imm)
+ {
+ if (imm <= 0xffff)
+ return (imm & 0xf000) << 4 | (imm & 0xfff);
+ return INVALID_IMM;
+ }
+#endif
ARMWord getImm(ARMWord imm, int tmpReg, bool invert = false);
void moveImm(ARMWord imm, int dest);
+ ARMWord encodeComplexImm(ARMWord imm, int dest);
// Memory load/store helpers
@@ -764,6 +831,6 @@ namespace JSC {
} // namespace JSC
-#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL)
+#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
#endif // ARMAssembler_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMv7Assembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMv7Assembler.h
index 078de44..6cde63b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -28,7 +28,7 @@
#include <wtf/Platform.h>
-#if ENABLE(ASSEMBLER) && PLATFORM(ARM_THUMB2)
+#if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
#include "AssemblerBuffer.h"
#include <wtf/Assertions.h>
@@ -236,6 +236,11 @@ class ARMThumbImmediate {
ARMThumbImmediate(ThumbImmediateType type, uint16_t value)
: m_type(TypeUInt16)
{
+ // Make sure this constructor is only reached with type TypeUInt16;
+ // this extra parameter makes the code a little clearer by making it
+ // explicit at call sites which type is being constructed
+ ASSERT_UNUSED(type, type == TypeUInt16);
+
m_value.asInt = value;
}
@@ -407,6 +412,11 @@ register writeback
class ARMv7Assembler {
public:
+ ~ARMv7Assembler()
+ {
+ ASSERT(m_jumpsToLink.isEmpty());
+ }
+
typedef ARMRegisters::RegisterID RegisterID;
typedef ARMRegisters::FPRegisterID FPRegisterID;
@@ -477,6 +487,17 @@ public:
private:
+ struct LinkRecord {
+ LinkRecord(intptr_t from, intptr_t to)
+ : from(from)
+ , to(to)
+ {
+ }
+
+ intptr_t from;
+ intptr_t to;
+ };
+
// ARMv7, Appx-A.6.3
bool BadReg(RegisterID reg)
{
@@ -574,6 +595,7 @@ private:
OP_SUB_SP_imm_T1 = 0xB080,
OP_BKPT = 0xBE00,
OP_IT = 0xBF00,
+ OP_NOP_T1 = 0xBF00,
} OpcodeID;
typedef enum {
@@ -608,6 +630,7 @@ private:
OP_MOV_imm_T3 = 0xF240,
OP_SUB_imm_T4 = 0xF2A0,
OP_MOVT = 0xF2C0,
+ OP_NOP_T2a = 0xF3AF,
OP_LDRH_reg_T2 = 0xF830,
OP_LDRH_imm_T3 = 0xF830,
OP_STR_imm_T4 = 0xF840,
@@ -626,6 +649,7 @@ private:
typedef enum {
OP_B_T4b = 0x9000,
+ OP_NOP_T2b = 0x8000,
} OpcodeID2;
struct FourFours {
@@ -1481,6 +1505,15 @@ public:
void* executableCopy(ExecutablePool* allocator)
{
void* copy = m_formatter.executableCopy(allocator);
+
+ unsigned jumpCount = m_jumpsToLink.size();
+ for (unsigned i = 0; i < jumpCount; ++i) {
+ uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(copy) + m_jumpsToLink[i].from);
+ uint16_t* target = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(copy) + m_jumpsToLink[i].to);
+ linkJumpAbsolute(location, target);
+ }
+ m_jumpsToLink.clear();
+
ASSERT(copy);
return copy;
}
@@ -1503,11 +1536,7 @@ public:
{
ASSERT(to.m_offset != -1);
ASSERT(from.m_offset != -1);
-
- uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(m_formatter.data()) + from.m_offset);
- intptr_t relative = to.m_offset - from.m_offset;
-
- linkWithOffset(location, relative);
+ m_jumpsToLink.append(LinkRecord(from.m_offset, to.m_offset));
}
static void linkJump(void* code, JmpSrc from, void* to)
@@ -1515,9 +1544,7 @@ public:
ASSERT(from.m_offset != -1);
uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
- intptr_t relative = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(location);
-
- linkWithOffset(location, relative);
+ linkJumpAbsolute(location, to);
}
// bah, this mathod should really be static, since it is used by the LinkBuffer.
@@ -1541,10 +1568,9 @@ public:
ASSERT(!(reinterpret_cast<intptr_t>(from) & 1));
ASSERT(!(reinterpret_cast<intptr_t>(to) & 1));
- intptr_t relative = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
- linkWithOffset(reinterpret_cast<uint16_t*>(from), relative);
+ linkJumpAbsolute(reinterpret_cast<uint16_t*>(from), to);
- ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 2, 2 * sizeof(uint16_t));
+ ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 5, 5 * sizeof(uint16_t));
}
static void relinkCall(void* from, void* to)
@@ -1613,14 +1639,14 @@ private:
static void setInt32(void* code, uint32_t value)
{
uint16_t* location = reinterpret_cast<uint16_t*>(code);
+ ASSERT(isMOV_imm_T3(location - 4) && isMOVT(location - 2));
- uint16_t lo16 = value;
- uint16_t hi16 = value >> 16;
-
- spliceHi5(location - 4, lo16);
- spliceLo11(location - 3, lo16);
- spliceHi5(location - 2, hi16);
- spliceLo11(location - 1, hi16);
+ ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(value));
+ ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(value >> 16));
+ location[-4] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16);
+ location[-3] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-3] >> 8) & 0xf, lo16);
+ location[-2] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16);
+ location[-1] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-1] >> 8) & 0xf, hi16);
ExecutableAllocator::cacheFlush(location - 4, 4 * sizeof(uint16_t));
}
@@ -1630,41 +1656,89 @@ private:
setInt32(code, reinterpret_cast<uint32_t>(value));
}
- // Linking & patching:
- // This method assumes that the JmpSrc being linked is a T4 b instruction.
- static void linkWithOffset(uint16_t* instruction, intptr_t relative)
- {
- // Currently branches > 16m = mostly deathy.
- if (((relative << 7) >> 7) != relative) {
- // FIXME: This CRASH means we cannot turn the JIT on by default on arm-v7.
- fprintf(stderr, "Error: Cannot link T4b.\n");
- CRASH();
- }
-
- // ARM encoding for the top two bits below the sign bit is 'peculiar'.
- if (relative >= 0)
- relative ^= 0xC00000;
+ static bool isB(void* address)
+ {
+ uint16_t* instruction = static_cast<uint16_t*>(address);
+ return ((instruction[0] & 0xf800) == OP_B_T4a) && ((instruction[1] & 0xd000) == OP_B_T4b);
+ }
- // All branch offsets should be an even distance.
- ASSERT(!(relative & 1));
+ static bool isBX(void* address)
+ {
+ uint16_t* instruction = static_cast<uint16_t*>(address);
+ return (instruction[0] & 0xff87) == OP_BX;
+ }
- int word1 = ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12);
- int word2 = ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1);
+ static bool isMOV_imm_T3(void* address)
+ {
+ uint16_t* instruction = static_cast<uint16_t*>(address);
+ return ((instruction[0] & 0xFBF0) == OP_MOV_imm_T3) && ((instruction[1] & 0x8000) == 0);
+ }
- instruction[-2] = OP_B_T4a | word1;
- instruction[-1] = OP_B_T4b | word2;
+ static bool isMOVT(void* address)
+ {
+ uint16_t* instruction = static_cast<uint16_t*>(address);
+ return ((instruction[0] & 0xFBF0) == OP_MOVT) && ((instruction[1] & 0x8000) == 0);
}
- // These functions can be used to splice 16-bit immediates back into previously generated instructions.
- static void spliceHi5(uint16_t* where, uint16_t what)
+ static bool isNOP_T1(void* address)
{
- uint16_t pattern = (what >> 12) | ((what & 0x0800) >> 1);
- *where = (*where & 0xFBF0) | pattern;
+ uint16_t* instruction = static_cast<uint16_t*>(address);
+ return instruction[0] == OP_NOP_T1;
}
- static void spliceLo11(uint16_t* where, uint16_t what)
+
+ static bool isNOP_T2(void* address)
{
- uint16_t pattern = ((what & 0x0700) << 4) | (what & 0x00FF);
- *where = (*where & 0x8F00) | pattern;
+ uint16_t* instruction = static_cast<uint16_t*>(address);
+ return (instruction[0] == OP_NOP_T2a) && (instruction[1] == OP_NOP_T2b);
+ }
+
+ static void linkJumpAbsolute(uint16_t* instruction, void* target)
+ {
+ // FIMXE: this should be up in the MacroAssembler layer. :-(
+ const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip;
+
+ ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
+ ASSERT(!(reinterpret_cast<intptr_t>(target) & 1));
+
+ ASSERT( (isMOV_imm_T3(instruction - 5) && isMOVT(instruction - 3) && isBX(instruction - 1))
+ || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2)) );
+
+ intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
+ if (((relative << 7) >> 7) == relative) {
+ // ARM encoding for the top two bits below the sign bit is 'peculiar'.
+ if (relative >= 0)
+ relative ^= 0xC00000;
+
+ // All branch offsets should be an even distance.
+ ASSERT(!(relative & 1));
+ // There may be a better way to fix this, but right now put the NOPs first, since in the
+ // case of an conditional branch this will be coming after an ITTT predicating *three*
+ // instructions! Looking backwards to modify the ITTT to an IT is not easy, due to
+ // variable wdith encoding - the previous instruction might *look* like an ITTT but
+ // actually be the second half of a 2-word op.
+ instruction[-5] = OP_NOP_T1;
+ instruction[-4] = OP_NOP_T2a;
+ instruction[-3] = OP_NOP_T2b;
+ instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12);
+ instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1);
+ } else {
+ ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1));
+ ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16));
+ instruction[-5] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16);
+ instruction[-4] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, lo16);
+ instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16);
+ instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16);
+ instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3);
+ }
+ }
+
+ static uint16_t twoWordOp5i6Imm4Reg4EncodedImmFirst(uint16_t op, ARMThumbImmediate imm)
+ {
+ return op | (imm.m_value.i << 10) | imm.m_value.imm4;
+ }
+ static uint16_t twoWordOp5i6Imm4Reg4EncodedImmSecond(uint16_t rd, ARMThumbImmediate imm)
+ {
+ return (imm.m_value.imm3 << 12) | (rd << 8) | imm.m_value.imm8;
}
class ARMInstructionFormatter {
@@ -1723,8 +1797,11 @@ private:
void twoWordOp5i6Imm4Reg4EncodedImm(OpcodeID1 op, int imm4, RegisterID rd, ARMThumbImmediate imm)
{
- m_buffer.putShort(op | (imm.m_value.i << 10) | imm4);
- m_buffer.putShort((imm.m_value.imm3 << 12) | (rd << 8) | imm.m_value.imm8);
+ ARMThumbImmediate newImm = imm;
+ newImm.m_value.imm4 = imm4;
+
+ m_buffer.putShort(ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmFirst(op, newImm));
+ m_buffer.putShort(ARMv7Assembler::twoWordOp5i6Imm4Reg4EncodedImmSecond(rd, newImm));
}
void twoWordOp12Reg4Reg4Imm12(OpcodeID1 op, RegisterID reg1, RegisterID reg2, uint16_t imm)
@@ -1749,10 +1826,12 @@ private:
private:
AssemblerBuffer m_buffer;
} m_formatter;
+
+ Vector<LinkRecord> m_jumpsToLink;
};
} // namespace JSC
-#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_THUMB2)
+#endif // ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
#endif // ARMAssembler_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AbstractMacroAssembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AbstractMacroAssembler.h
index 525fe98..198e8d1 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -173,16 +173,16 @@ public:
struct Imm32 {
explicit Imm32(int32_t value)
: m_value(value)
-#if PLATFORM(ARM)
+#if CPU(ARM)
, m_isPointer(false)
#endif
{
}
-#if !PLATFORM(X86_64)
+#if !CPU(X86_64)
explicit Imm32(ImmPtr ptr)
: m_value(ptr.asIntptr())
-#if PLATFORM(ARM)
+#if CPU(ARM)
, m_isPointer(true)
#endif
{
@@ -190,7 +190,7 @@ public:
#endif
int32_t m_value;
-#if PLATFORM(ARM)
+#if CPU(ARM)
// We rely on being able to regenerate code to recover exception handling
// information. Since ARMv7 supports 16-bit immediates there is a danger
// that if pointer values change the layout of the generated code will change.
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssembler.h
index 2743ab4..76bd205 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssembler.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssembler.h
@@ -30,19 +30,19 @@
#if ENABLE(ASSEMBLER)
-#if PLATFORM(ARM_THUMB2)
+#if CPU(ARM_THUMB2)
#include "MacroAssemblerARMv7.h"
namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; };
-#elif PLATFORM(ARM_TRADITIONAL)
+#elif CPU(ARM_TRADITIONAL)
#include "MacroAssemblerARM.h"
namespace JSC { typedef MacroAssemblerARM MacroAssemblerBase; };
-#elif PLATFORM(X86)
+#elif CPU(X86)
#include "MacroAssemblerX86.h"
namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; };
-#elif PLATFORM(X86_64)
+#elif CPU(X86_64)
#include "MacroAssemblerX86_64.h"
namespace JSC { typedef MacroAssemblerX86_64 MacroAssemblerBase; };
@@ -60,7 +60,7 @@ public:
using MacroAssemblerBase::jump;
using MacroAssemblerBase::branch32;
using MacroAssemblerBase::branch16;
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
using MacroAssemblerBase::branchPtr;
using MacroAssemblerBase::branchTestPtr;
#endif
@@ -133,7 +133,8 @@ public:
// Ptr methods
// On 32-bit platforms (i.e. x86), these methods directly map onto their 32-bit equivalents.
-#if !PLATFORM(X86_64)
+ // FIXME: should this use a test for 32-bitness instead of this specific exception?
+#if !CPU(X86_64)
void addPtr(RegisterID src, RegisterID dest)
{
add32(src, dest);
@@ -179,16 +180,6 @@ public:
or32(imm, dest);
}
- void rshiftPtr(RegisterID shift_amount, RegisterID dest)
- {
- rshift32(shift_amount, dest);
- }
-
- void rshiftPtr(Imm32 imm, RegisterID dest)
- {
- rshift32(imm, dest);
- }
-
void subPtr(RegisterID src, RegisterID dest)
{
sub32(src, dest);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp
index d726ecd..b5b20fa 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.cpp
@@ -26,11 +26,11 @@
#include "config.h"
-#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL)
+#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
#include "MacroAssemblerARM.h"
-#if PLATFORM(LINUX)
+#if OS(LINUX)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -43,7 +43,7 @@ namespace JSC {
static bool isVFPPresent()
{
-#if PLATFORM(LINUX)
+#if OS(LINUX)
int fd = open("/proc/self/auxv", O_RDONLY);
if (fd > 0) {
Elf32_auxv_t aux;
@@ -62,7 +62,8 @@ static bool isVFPPresent()
const bool MacroAssemblerARM::s_isVFPPresent = isVFPPresent();
-#if defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_REQUIRE_NATURAL_ALIGNMENT
+#if CPU(ARMV5_OR_LOWER)
+/* On ARMv5 and below, natural alignment is required. */
void MacroAssemblerARM::load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
{
ARMWord op2;
@@ -91,4 +92,4 @@ void MacroAssemblerARM::load32WithUnalignedHalfWords(BaseIndex address, Register
}
-#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL)
+#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h
index aa8cbb0..21b8de8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -30,7 +30,7 @@
#include <wtf/Platform.h>
-#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL)
+#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
#include "ARMAssembler.h"
#include "AbstractMacroAssembler.h"
@@ -38,6 +38,9 @@
namespace JSC {
class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler> {
+ static const int DoubleConditionMask = 0x0f;
+ static const int DoubleConditionBitSpecial = 0x10;
+ COMPILE_ASSERT(!(DoubleConditionBitSpecial & DoubleConditionMask), DoubleConditionBitSpecial_should_not_interfere_with_ARMAssembler_Condition_codes);
public:
enum Condition {
Equal = ARMAssembler::EQ,
@@ -57,14 +60,24 @@ public:
};
enum DoubleCondition {
+ // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
DoubleEqual = ARMAssembler::EQ,
+ DoubleNotEqual = ARMAssembler::NE | DoubleConditionBitSpecial,
DoubleGreaterThan = ARMAssembler::GT,
DoubleGreaterThanOrEqual = ARMAssembler::GE,
- DoubleLessThan = ARMAssembler::LT,
- DoubleLessThanOrEqual = ARMAssembler::LE,
+ DoubleLessThan = ARMAssembler::CC,
+ DoubleLessThanOrEqual = ARMAssembler::LS,
+ // If either operand is NaN, these conditions always evaluate to true.
+ DoubleEqualOrUnordered = ARMAssembler::EQ | DoubleConditionBitSpecial,
+ DoubleNotEqualOrUnordered = ARMAssembler::NE,
+ DoubleGreaterThanOrUnordered = ARMAssembler::HI,
+ DoubleGreaterThanOrEqualOrUnordered = ARMAssembler::CS,
+ DoubleLessThanOrUnordered = ARMAssembler::LT,
+ DoubleLessThanOrEqualOrUnordered = ARMAssembler::LE,
};
static const RegisterID stackPointerRegister = ARMRegisters::sp;
+ static const RegisterID linkRegister = ARMRegisters::lr;
static const Scale ScalePtr = TimesFour;
@@ -105,14 +118,18 @@ public:
m_assembler.ands_r(dest, dest, w);
}
- void lshift32(Imm32 imm, RegisterID dest)
+ void lshift32(RegisterID shift_amount, RegisterID dest)
{
- m_assembler.movs_r(dest, m_assembler.lsl(dest, imm.m_value & 0x1f));
+ ARMWord w = ARMAssembler::getOp2(0x1f);
+ ASSERT(w != ARMAssembler::INVALID_IMM);
+ m_assembler.and_r(ARMRegisters::S0, shift_amount, w);
+
+ m_assembler.movs_r(dest, m_assembler.lsl_r(dest, ARMRegisters::S0));
}
- void lshift32(RegisterID shift_amount, RegisterID dest)
+ void lshift32(Imm32 imm, RegisterID dest)
{
- m_assembler.movs_r(dest, m_assembler.lsl_r(dest, shift_amount));
+ m_assembler.movs_r(dest, m_assembler.lsl(dest, imm.m_value & 0x1f));
}
void mul32(RegisterID src, RegisterID dest)
@@ -130,6 +147,11 @@ public:
m_assembler.muls_r(dest, src, ARMRegisters::S0);
}
+ void neg32(RegisterID srcDest)
+ {
+ m_assembler.rsbs_r(srcDest, srcDest, ARMAssembler::getOp2(0));
+ }
+
void not32(RegisterID dest)
{
m_assembler.mvns_r(dest, dest);
@@ -147,7 +169,11 @@ public:
void rshift32(RegisterID shift_amount, RegisterID dest)
{
- m_assembler.movs_r(dest, m_assembler.asr_r(dest, shift_amount));
+ ARMWord w = ARMAssembler::getOp2(0x1f);
+ ASSERT(w != ARMAssembler::INVALID_IMM);
+ m_assembler.and_r(ARMRegisters::S0, shift_amount, w);
+
+ m_assembler.movs_r(dest, m_assembler.asr_r(dest, ARMRegisters::S0));
}
void rshift32(Imm32 imm, RegisterID dest)
@@ -198,7 +224,7 @@ public:
m_assembler.baseIndexTransfer32(true, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
}
-#if defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_REQUIRE_NATURAL_ALIGNMENT
+#if CPU(ARMV5_OR_LOWER)
void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest);
#else
void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
@@ -504,6 +530,13 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
+ Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
+ {
+ ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
+ or32(src, dest);
+ return Jump(m_assembler.jmp(ARMCondition(cond)));
+ }
+
void breakpoint()
{
m_assembler.bkpt(0);
@@ -530,7 +563,7 @@ public:
void ret()
{
- pop(ARMRegisters::pc);
+ m_assembler.mov_r(ARMRegisters::pc, linkRegister);
}
void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
@@ -547,6 +580,25 @@ public:
m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond));
}
+ void set8(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
+ {
+ // ARM doesn't have byte registers
+ set32(cond, left, right, dest);
+ }
+
+ void set8(Condition cond, Address left, RegisterID right, RegisterID dest)
+ {
+ // ARM doesn't have byte registers
+ load32(left, ARMRegisters::S1);
+ set32(cond, ARMRegisters::S1, right, dest);
+ }
+
+ void set8(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ {
+ // ARM doesn't have byte registers
+ set32(cond, left, right, dest);
+ }
+
void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest)
{
load32(address, ARMRegisters::S1);
@@ -558,6 +610,12 @@ public:
m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond));
}
+ void setTest8(Condition cond, Address address, Imm32 mask, RegisterID dest)
+ {
+ // ARM doesn't have byte registers
+ setTest32(cond, address, mask, dest);
+ }
+
void add32(Imm32 imm, RegisterID src, RegisterID dest)
{
m_assembler.add_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
@@ -665,6 +723,12 @@ public:
m_assembler.doubleTransfer(true, dest, address.base, address.offset);
}
+ void loadDouble(void* address, FPRegisterID dest)
+ {
+ m_assembler.ldr_un_imm(ARMRegisters::S0, (ARMWord)address);
+ m_assembler.fdtr_u(true, dest, ARMRegisters::S0, 0);
+ }
+
void storeDouble(FPRegisterID src, ImplicitAddress address)
{
m_assembler.doubleTransfer(false, src, address.base, address.offset);
@@ -681,6 +745,18 @@ public:
addDouble(ARMRegisters::SD0, dest);
}
+ void divDouble(FPRegisterID src, FPRegisterID dest)
+ {
+ m_assembler.fdivd_r(dest, dest, src);
+ }
+
+ void divDouble(Address src, FPRegisterID dest)
+ {
+ ASSERT_NOT_REACHED(); // Untested
+ loadDouble(src, ARMRegisters::SD0);
+ divDouble(ARMRegisters::SD0, dest);
+ }
+
void subDouble(FPRegisterID src, FPRegisterID dest)
{
m_assembler.fsubd_r(dest, dest, src);
@@ -709,11 +785,30 @@ public:
m_assembler.fsitod_r(dest, dest);
}
+ void convertInt32ToDouble(Address src, FPRegisterID dest)
+ {
+ ASSERT_NOT_REACHED(); // Untested
+ // flds does not worth the effort here
+ load32(src, ARMRegisters::S1);
+ convertInt32ToDouble(ARMRegisters::S1, dest);
+ }
+
+ void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
+ {
+ ASSERT_NOT_REACHED(); // Untested
+ // flds does not worth the effort here
+ m_assembler.ldr_un_imm(ARMRegisters::S1, (ARMWord)src.m_ptr);
+ m_assembler.dtr_u(true, ARMRegisters::S1, ARMRegisters::S1, 0);
+ convertInt32ToDouble(ARMRegisters::S1, dest);
+ }
+
Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
{
m_assembler.fcmpd_r(left, right);
m_assembler.fmstat();
- return Jump(m_assembler.jmp(static_cast<ARMAssembler::Condition>(cond)));
+ if (cond & DoubleConditionBitSpecial)
+ m_assembler.cmp_r(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::VS);
+ return Jump(m_assembler.jmp(static_cast<ARMAssembler::Condition>(cond & ~DoubleConditionMask)));
}
// Truncates 'src' to an integer, and places the resulting 'dest'.
@@ -728,6 +823,29 @@ public:
return jump();
}
+ // Convert 'src' to an integer, and places the resulting 'dest'.
+ // If the result is not representable as a 32 bit value, branch.
+ // May also branch for some values that are representable in 32 bits
+ // (specifically, in this case, 0).
+ void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+ {
+ m_assembler.ftosid_r(ARMRegisters::SD0, src);
+ m_assembler.fmrs_r(dest, ARMRegisters::SD0);
+
+ // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
+ m_assembler.fsitod_r(ARMRegisters::SD0, ARMRegisters::SD0);
+ failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, ARMRegisters::SD0));
+
+ // If the result is zero, it might have been -0.0, and 0.0 equals to -0.0
+ failureCases.append(branchTest32(Zero, dest));
+ }
+
+ void zeroDouble(FPRegisterID srcDest)
+ {
+ m_assembler.mov_r(ARMRegisters::S0, ARMAssembler::getOp2(0));
+ convertInt32ToDouble(ARMRegisters::S0, srcDest);
+ }
+
protected:
ARMAssembler::Condition ARMCondition(Condition cond)
{
@@ -746,11 +864,9 @@ protected:
void prepareCall()
{
- ensureSpace(3 * sizeof(ARMWord), sizeof(ARMWord));
+ ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord));
- // S0 might be used for parameter passing
- m_assembler.add_r(ARMRegisters::S1, ARMRegisters::pc, ARMAssembler::OP2_IMM | 0x4);
- m_assembler.push_r(ARMRegisters::S1);
+ m_assembler.mov_r(linkRegister, ARMRegisters::pc);
}
void call32(RegisterID base, int32_t offset)
@@ -812,6 +928,6 @@ private:
}
-#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL)
+#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
#endif // MacroAssemblerARM_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index a549604..532a9cf 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -93,13 +93,21 @@ public:
Zero = ARMv7Assembler::ConditionEQ,
NonZero = ARMv7Assembler::ConditionNE
};
-
enum DoubleCondition {
+ // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
DoubleEqual = ARMv7Assembler::ConditionEQ,
+ DoubleNotEqual = ARMv7Assembler::ConditionVC, // Not the right flag! check for this & handle differently.
DoubleGreaterThan = ARMv7Assembler::ConditionGT,
DoubleGreaterThanOrEqual = ARMv7Assembler::ConditionGE,
DoubleLessThan = ARMv7Assembler::ConditionLO,
DoubleLessThanOrEqual = ARMv7Assembler::ConditionLS,
+ // If either operand is NaN, these conditions always evaluate to true.
+ DoubleEqualOrUnordered = ARMv7Assembler::ConditionVS, // Not the right flag! check for this & handle differently.
+ DoubleNotEqualOrUnordered = ARMv7Assembler::ConditionNE,
+ DoubleGreaterThanOrUnordered = ARMv7Assembler::ConditionHI,
+ DoubleGreaterThanOrEqualOrUnordered = ARMv7Assembler::ConditionHS,
+ DoubleLessThanOrUnordered = ARMv7Assembler::ConditionLT,
+ DoubleLessThanOrEqualOrUnordered = ARMv7Assembler::ConditionLE,
};
static const RegisterID stackPointerRegister = ARMRegisters::sp;
@@ -189,14 +197,19 @@ public:
}
}
- void lshift32(Imm32 imm, RegisterID dest)
+ void lshift32(RegisterID shift_amount, RegisterID dest)
{
- m_assembler.lsl(dest, dest, imm.m_value);
+ // Clamp the shift to the range 0..31
+ ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f);
+ ASSERT(armImm.isValid());
+ m_assembler.ARM_and(dataTempRegister, shift_amount, armImm);
+
+ m_assembler.lsl(dest, dest, dataTempRegister);
}
- void lshift32(RegisterID shift_amount, RegisterID dest)
+ void lshift32(Imm32 imm, RegisterID dest)
{
- m_assembler.lsl(dest, dest, shift_amount);
+ m_assembler.lsl(dest, dest, imm.m_value & 0x1f);
}
void mul32(RegisterID src, RegisterID dest)
@@ -233,12 +246,17 @@ public:
void rshift32(RegisterID shift_amount, RegisterID dest)
{
- m_assembler.asr(dest, dest, shift_amount);
+ // Clamp the shift to the range 0..31
+ ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f);
+ ASSERT(armImm.isValid());
+ m_assembler.ARM_and(dataTempRegister, shift_amount, armImm);
+
+ m_assembler.asr(dest, dest, dataTempRegister);
}
void rshift32(Imm32 imm, RegisterID dest)
{
- m_assembler.asr(dest, dest, imm.m_value);
+ m_assembler.asr(dest, dest, imm.m_value & 0x1f);
}
void sub32(RegisterID src, RegisterID dest)
@@ -531,6 +549,23 @@ public:
{
m_assembler.vcmp_F64(left, right);
m_assembler.vmrs_APSR_nzcv_FPSCR();
+
+ if (cond == DoubleNotEqual) {
+ // ConditionNE jumps if NotEqual *or* unordered - force the unordered cases not to jump.
+ Jump unordered = makeBranch(ARMv7Assembler::ConditionVS);
+ Jump result = makeBranch(ARMv7Assembler::ConditionNE);
+ unordered.link(this);
+ return result;
+ }
+ if (cond == DoubleEqualOrUnordered) {
+ Jump unordered = makeBranch(ARMv7Assembler::ConditionVS);
+ Jump notEqual = makeBranch(ARMv7Assembler::ConditionNE);
+ unordered.link(this);
+ // We get here if either unordered, or equal.
+ Jump result = makeJump();
+ notEqual.link(this);
+ return result;
+ }
return makeBranch(cond);
}
@@ -990,13 +1025,15 @@ public:
protected:
ARMv7Assembler::JmpSrc makeJump()
{
- return m_assembler.b();
+ moveFixedWidthEncoding(Imm32(0), dataTempRegister);
+ return m_assembler.bx(dataTempRegister);
}
ARMv7Assembler::JmpSrc makeBranch(ARMv7Assembler::Condition cond)
{
- m_assembler.it(cond);
- return m_assembler.b();
+ m_assembler.it(cond, true, true);
+ moveFixedWidthEncoding(Imm32(0), dataTempRegister);
+ return m_assembler.bx(dataTempRegister);
}
ARMv7Assembler::JmpSrc makeBranch(Condition cond) { return makeBranch(armV7Condition(cond)); }
ARMv7Assembler::JmpSrc makeBranch(DoubleCondition cond) { return makeBranch(armV7Condition(cond)); }
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
index 568260a..cae8bf6 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
@@ -37,7 +37,7 @@
// ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
// instruction address on the platform (for example, check any alignment requirements).
-#if PLATFORM(ARM_THUMB2)
+#if CPU(ARM_THUMB2)
// ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded
// into the processor are decorated with the bottom bit set, indicating that this is
// thumb code (as oposed to 32-bit traditional ARM). The first test checks for both
@@ -69,7 +69,13 @@ public:
template<typename FunctionType>
explicit FunctionPtr(FunctionType* value)
+#if COMPILER(RVCT)
+ // RVTC compiler needs C-style cast as it fails with the following error
+ // Error: #694: reinterpret_cast cannot cast away const or other type qualifiers
+ : m_value((void*)(value))
+#else
: m_value(reinterpret_cast<void*>(value))
+#endif
{
ASSERT_VALID_CODE_POINTER(m_value);
}
@@ -124,7 +130,7 @@ public:
}
explicit MacroAssemblerCodePtr(void* value)
-#if PLATFORM(ARM_THUMB2)
+#if CPU(ARM_THUMB2)
// Decorate the pointer as a thumb code pointer.
: m_value(reinterpret_cast<char*>(value) + 1)
#else
@@ -141,7 +147,7 @@ public:
}
void* executableAddress() const { return m_value; }
-#if PLATFORM(ARM_THUMB2)
+#if CPU(ARM_THUMB2)
// To use this pointer as a data address remove the decoration.
void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
#else
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86.h
index 6e96240..ca7c31a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86.h
@@ -28,7 +28,7 @@
#include <wtf/Platform.h>
-#if ENABLE(ASSEMBLER) && PLATFORM(X86)
+#if ENABLE(ASSEMBLER) && CPU(X86)
#include "MacroAssemblerX86Common.h"
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h
index 5ebefa7..449df86 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86Common.h
@@ -36,6 +36,10 @@
namespace JSC {
class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> {
+ static const int DoubleConditionBitInvert = 0x10;
+ static const int DoubleConditionBitSpecial = 0x20;
+ static const int DoubleConditionBits = DoubleConditionBitInvert | DoubleConditionBitSpecial;
+
public:
enum Condition {
@@ -56,13 +60,24 @@ public:
};
enum DoubleCondition {
- DoubleEqual = X86Assembler::ConditionE,
+ // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
+ DoubleEqual = X86Assembler::ConditionE | DoubleConditionBitSpecial,
DoubleNotEqual = X86Assembler::ConditionNE,
DoubleGreaterThan = X86Assembler::ConditionA,
DoubleGreaterThanOrEqual = X86Assembler::ConditionAE,
- DoubleLessThan = X86Assembler::ConditionB,
- DoubleLessThanOrEqual = X86Assembler::ConditionBE,
+ DoubleLessThan = X86Assembler::ConditionA | DoubleConditionBitInvert,
+ DoubleLessThanOrEqual = X86Assembler::ConditionAE | DoubleConditionBitInvert,
+ // If either operand is NaN, these conditions always evaluate to true.
+ DoubleEqualOrUnordered = X86Assembler::ConditionE,
+ DoubleNotEqualOrUnordered = X86Assembler::ConditionNE | DoubleConditionBitSpecial,
+ DoubleGreaterThanOrUnordered = X86Assembler::ConditionB | DoubleConditionBitInvert,
+ DoubleGreaterThanOrEqualOrUnordered = X86Assembler::ConditionBE | DoubleConditionBitInvert,
+ DoubleLessThanOrUnordered = X86Assembler::ConditionB,
+ DoubleLessThanOrEqualOrUnordered = X86Assembler::ConditionBE,
};
+ COMPILE_ASSERT(
+ !((X86Assembler::ConditionE | X86Assembler::ConditionNE | X86Assembler::ConditionA | X86Assembler::ConditionAE | X86Assembler::ConditionB | X86Assembler::ConditionBE) & DoubleConditionBits),
+ DoubleConditionBits_should_not_interfere_with_X86Assembler_Condition_codes);
static const RegisterID stackPointerRegister = X86Registers::esp;
@@ -416,20 +431,35 @@ public:
void convertInt32ToDouble(Address src, FPRegisterID dest)
{
+ ASSERT(isSSE2Present());
m_assembler.cvtsi2sd_mr(src.offset, src.base, dest);
}
Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
{
ASSERT(isSSE2Present());
- m_assembler.ucomisd_rr(right, left);
- return Jump(m_assembler.jCC(x86Condition(cond)));
- }
- Jump branchDouble(DoubleCondition cond, FPRegisterID left, Address right)
- {
- m_assembler.ucomisd_mr(right.offset, right.base, left);
- return Jump(m_assembler.jCC(x86Condition(cond)));
+ if (cond & DoubleConditionBitInvert)
+ m_assembler.ucomisd_rr(left, right);
+ else
+ m_assembler.ucomisd_rr(right, left);
+
+ if (cond == DoubleEqual) {
+ Jump isUnordered(m_assembler.jp());
+ Jump result = Jump(m_assembler.je());
+ isUnordered.link(this);
+ return result;
+ } else if (cond == DoubleNotEqualOrUnordered) {
+ Jump isUnordered(m_assembler.jp());
+ Jump isEqual(m_assembler.je());
+ isUnordered.link(this);
+ Jump result = jump();
+ isEqual.link(this);
+ return result;
+ }
+
+ ASSERT(!(cond & DoubleConditionBitSpecial));
+ return Jump(m_assembler.jCC(static_cast<X86Assembler::Condition>(cond & ~DoubleConditionBits)));
}
// Truncates 'src' to an integer, and places the resulting 'dest'.
@@ -443,6 +473,25 @@ public:
return branch32(Equal, dest, Imm32(0x80000000));
}
+ // Convert 'src' to an integer, and places the resulting 'dest'.
+ // If the result is not representable as a 32 bit value, branch.
+ // May also branch for some values that are representable in 32 bits
+ // (specifically, in this case, 0).
+ void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+ {
+ ASSERT(isSSE2Present());
+ m_assembler.cvttsd2si_rr(src, dest);
+
+ // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
+ failureCases.append(branchTest32(Zero, dest));
+
+ // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
+ convertInt32ToDouble(dest, fpTemp);
+ m_assembler.ucomisd_rr(fpTemp, src);
+ failureCases.append(m_assembler.jp());
+ failureCases.append(m_assembler.jne());
+ }
+
void zeroDouble(FPRegisterID srcDest)
{
ASSERT(isSSE2Present());
@@ -493,7 +542,7 @@ public:
m_assembler.movl_i32r(imm.m_value, dest);
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void move(RegisterID src, RegisterID dest)
{
// Note: on 64-bit this is is a full register move; perhaps it would be
@@ -509,7 +558,8 @@ public:
void swap(RegisterID reg1, RegisterID reg2)
{
- m_assembler.xchgq_rr(reg1, reg2);
+ if (reg1 != reg2)
+ m_assembler.xchgq_rr(reg1, reg2);
}
void signExtend32ToPtr(RegisterID src, RegisterID dest)
@@ -889,18 +939,13 @@ protected:
return static_cast<X86Assembler::Condition>(cond);
}
- X86Assembler::Condition x86Condition(DoubleCondition cond)
- {
- return static_cast<X86Assembler::Condition>(cond);
- }
-
private:
// Only MacroAssemblerX86 should be using the following method; SSE2 is always available on
// x86_64, and clients & subclasses of MacroAssembler should be using 'supportsFloatingPoint()'.
friend class MacroAssemblerX86;
-#if PLATFORM(X86)
-#if PLATFORM(MAC)
+#if CPU(X86)
+#if OS(MAC_OS_X)
// All X86 Macs are guaranteed to support at least SSE2,
static bool isSSE2Present()
@@ -908,7 +953,7 @@ private:
return true;
}
-#else // PLATFORM(MAC)
+#else // OS(MAC_OS_X)
enum SSE2CheckState {
NotCheckedSSE2,
@@ -951,8 +996,8 @@ private:
static SSE2CheckState s_sse2CheckState;
-#endif // PLATFORM(MAC)
-#elif !defined(NDEBUG) // PLATFORM(X86)
+#endif // OS(MAC_OS_X)
+#elif !defined(NDEBUG) // CPU(X86)
// On x86-64 we should never be checking for SSE2 in a non-debug build,
// but non debug add this method to keep the asserts above happy.
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86_64.h
index 0f95fe6..ec93f8c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86_64.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/MacroAssemblerX86_64.h
@@ -28,7 +28,7 @@
#include <wtf/Platform.h>
-#if ENABLE(ASSEMBLER) && PLATFORM(X86_64)
+#if ENABLE(ASSEMBLER) && CPU(X86_64)
#include "MacroAssemblerX86Common.h"
@@ -192,33 +192,6 @@ public:
m_assembler.orq_ir(imm.m_value, dest);
}
- void rshiftPtr(RegisterID shift_amount, RegisterID dest)
- {
- // On x86 we can only shift by ecx; if asked to shift by another register we'll
- // need rejig the shift amount into ecx first, and restore the registers afterwards.
- if (shift_amount != X86Registers::ecx) {
- swap(shift_amount, X86Registers::ecx);
-
- // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
- if (dest == shift_amount)
- m_assembler.sarq_CLr(X86Registers::ecx);
- // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
- else if (dest == X86Registers::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, X86Registers::ecx);
- } else
- m_assembler.sarq_CLr(dest);
- }
-
- void rshiftPtr(Imm32 imm, RegisterID dest)
- {
- m_assembler.sarq_i8r(imm.m_value, dest);
- }
-
void subPtr(RegisterID src, RegisterID dest)
{
m_assembler.subq_rr(src, dest);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h
index cbbaaa5..ab3d05f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h
@@ -28,7 +28,7 @@
#include <wtf/Platform.h>
-#if ENABLE(ASSEMBLER) && (PLATFORM(X86) || PLATFORM(X86_64))
+#if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
#include "AssemblerBuffer.h"
#include <stdint.h>
@@ -50,7 +50,7 @@ namespace X86Registers {
esi,
edi,
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
r8,
r9,
r10,
@@ -118,12 +118,12 @@ private:
OP_XOR_GvEv = 0x33,
OP_CMP_EvGv = 0x39,
OP_CMP_GvEv = 0x3B,
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
PRE_REX = 0x40,
#endif
OP_PUSH_EAX = 0x50,
OP_POP_EAX = 0x58,
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
OP_MOVSXD_GvEv = 0x63,
#endif
PRE_OPERAND_SIZE = 0x66,
@@ -296,7 +296,7 @@ public:
// Arithmetic operations:
-#if !PLATFORM(X86_64)
+#if !CPU(X86_64)
void adcl_im(int imm, void* addr)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -346,7 +346,7 @@ public:
}
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void addq_rr(RegisterID src, RegisterID dst)
{
m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
@@ -423,7 +423,7 @@ public:
}
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void andq_rr(RegisterID src, RegisterID dst)
{
m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
@@ -509,7 +509,7 @@ public:
}
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void orq_rr(RegisterID src, RegisterID dst)
{
m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
@@ -575,7 +575,7 @@ public:
}
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void subq_rr(RegisterID src, RegisterID dst)
{
m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
@@ -641,7 +641,7 @@ public:
}
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void xorq_rr(RegisterID src, RegisterID dst)
{
m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
@@ -689,7 +689,7 @@ public:
m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void sarq_CLr(RegisterID dst)
{
m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
@@ -789,7 +789,7 @@ public:
m_formatter.immediate32(imm);
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void cmpq_rr(RegisterID src, RegisterID dst)
{
m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
@@ -897,7 +897,7 @@ public:
m_formatter.immediate32(imm);
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void testq_rr(RegisterID src, RegisterID dst)
{
m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
@@ -971,7 +971,7 @@ public:
m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void xchgq_rr(RegisterID src, RegisterID dst)
{
m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
@@ -1001,7 +1001,7 @@ public:
void movl_mEAX(void* addr)
{
m_formatter.oneByteOp(OP_MOV_EAXOv);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
#else
m_formatter.immediate32(reinterpret_cast<int>(addr));
@@ -1038,14 +1038,14 @@ public:
void movl_EAXm(void* addr)
{
m_formatter.oneByteOp(OP_MOV_OvEAX);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
#else
m_formatter.immediate32(reinterpret_cast<int>(addr));
#endif
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void movq_rr(RegisterID src, RegisterID dst)
{
m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
@@ -1157,7 +1157,7 @@ public:
{
m_formatter.oneByteOp(OP_LEA, dst, base, offset);
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void leaq_mr(int offset, RegisterID base, RegisterID dst)
{
m_formatter.oneByteOp64(OP_LEA, dst, base, offset);
@@ -1323,7 +1323,7 @@ public:
m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
}
-#if !PLATFORM(X86_64)
+#if !CPU(X86_64)
void cvtsi2sd_mr(void* address, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_F2);
@@ -1343,7 +1343,7 @@ public:
m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
}
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
void movq_rr(XMMRegisterID src, RegisterID dst)
{
m_formatter.prefix(PRE_SSE_66);
@@ -1369,7 +1369,7 @@ public:
m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
}
-#if !PLATFORM(X86_64)
+#if !CPU(X86_64)
void movsd_mr(void* address, XMMRegisterID dst)
{
m_formatter.prefix(PRE_SSE_F2);
@@ -1535,7 +1535,7 @@ public:
static void repatchLoadPtrToLEA(void* where)
{
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
// On x86-64 pointer memory accesses require a 64-bit operand, and as such a REX prefix.
// Skip over the prefix byte.
where = reinterpret_cast<char*>(where) + 1;
@@ -1679,7 +1679,7 @@ private:
memoryModRM(reg, base, index, scale, offset);
}
-#if !PLATFORM(X86_64)
+#if !CPU(X86_64)
void oneByteOp(OneByteOpcodeID opcode, int reg, void* address)
{
m_buffer.ensureSpace(maxInstructionSize);
@@ -1722,7 +1722,7 @@ private:
memoryModRM(reg, base, index, scale, offset);
}
-#if !PLATFORM(X86_64)
+#if !CPU(X86_64)
void twoByteOp(TwoByteOpcodeID opcode, int reg, void* address)
{
m_buffer.ensureSpace(maxInstructionSize);
@@ -1732,7 +1732,7 @@ private:
}
#endif
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
// Quad-word-sized operands:
//
// Used to format 64-bit operantions, planting a REX.w prefix.
@@ -1891,7 +1891,7 @@ private:
static const RegisterID noBase = X86Registers::ebp;
static const RegisterID hasSib = X86Registers::esp;
static const RegisterID noIndex = X86Registers::esp;
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
static const RegisterID noBase2 = X86Registers::r13;
static const RegisterID hasSib2 = X86Registers::r12;
@@ -1967,7 +1967,7 @@ private:
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 CPU(X86_64)
if ((base == hasSib) || (base == hasSib2)) {
#else
if (base == hasSib) {
@@ -1982,7 +1982,7 @@ private:
m_buffer.putIntUnchecked(offset);
}
} else {
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
if (!offset && (base != noBase) && (base != noBase2))
#else
if (!offset && (base != noBase))
@@ -2001,7 +2001,7 @@ private:
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 CPU(X86_64)
if ((base == hasSib) || (base == hasSib2)) {
#else
if (base == hasSib) {
@@ -2018,7 +2018,7 @@ private:
{
ASSERT(index != noIndex);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
if (!offset && (base != noBase) && (base != noBase2))
#else
if (!offset && (base != noBase))
@@ -2033,7 +2033,7 @@ private:
}
}
-#if !PLATFORM(X86_64)
+#if !CPU(X86_64)
void memoryModRM(int reg, void* address)
{
// noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
@@ -2048,6 +2048,6 @@ private:
} // namespace JSC
-#endif // ENABLE(ASSEMBLER) && PLATFORM(X86)
+#endif // ENABLE(ASSEMBLER) && CPU(X86)
#endif // X86Assembler_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp
index 7e5f6cf..2256583 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -51,7 +51,7 @@ 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);
+ result = makeString(result.substr(0, pos), "\"\\\"\"", result.substr(pos + 1));
pos += 4;
}
return result;
@@ -62,49 +62,50 @@ static UString valueToSourceString(ExecState* exec, JSValue val)
if (!val)
return "0";
- if (val.isString()) {
- UString result("\"");
- result += escapeQuotes(val.toString(exec)) + "\"";
- return result;
- }
+ if (val.isString())
+ return makeString("\"", escapeQuotes(val.toString(exec)), "\"");
return val.toString(exec);
}
-static CString registerName(int r)
+static CString constantName(ExecState* exec, int k, JSValue value)
{
- if (r == missingThisObjectMarker())
- return "<null>";
-
- return (UString("r") + UString::from(r)).UTF8String();
+ return makeString(valueToSourceString(exec, value), "(@k", UString::from(k - FirstConstantRegisterIndex), ")").UTF8String();
}
-static CString constantName(ExecState* exec, int k, JSValue value)
+static CString idName(int id0, const Identifier& ident)
{
- return (valueToSourceString(exec, value) + "(@k" + UString::from(k) + ")").UTF8String();
+ return makeString(ident.ustring(), "(@id", UString::from(id0), ")").UTF8String();
}
-static CString idName(int id0, const Identifier& ident)
+CString CodeBlock::registerName(ExecState* exec, int r) const
{
- return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String();
+ if (r == missingThisObjectMarker())
+ return "<null>";
+
+ if (isConstantRegisterIndex(r))
+ return constantName(exec, r, getConstant(r));
+
+ return makeString("r", UString::from(r)).UTF8String();
}
static UString regexpToSourceString(RegExp* regExp)
{
- UString pattern = UString("/") + regExp->pattern() + "/";
+ char postfix[5] = { '/', 0, 0, 0, 0 };
+ int index = 1;
if (regExp->global())
- pattern += "g";
+ postfix[index++] = 'g';
if (regExp->ignoreCase())
- pattern += "i";
+ postfix[index++] = 'i';
if (regExp->multiline())
- pattern += "m";
+ postfix[index] = 'm';
- return pattern;
+ return makeString("/", regExp->pattern(), postfix);
}
static CString regexpName(int re, RegExp* regexp)
{
- return (regexpToSourceString(regexp) + "(@re" + UString::from(re) + ")").UTF8String();
+ return makeString(regexpToSourceString(regexp), "(@re", UString::from(re), ")").UTF8String();
}
static UString pointerToSourceString(void* p)
@@ -135,49 +136,44 @@ NEVER_INLINE static const char* debugHookName(int debugHookID)
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)
+void CodeBlock::printUnaryOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const
{
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());
+ printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(exec, r0).c_str(), registerName(exec, r1).c_str());
}
-static void printBinaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op)
+void CodeBlock::printBinaryOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const
{
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());
+ printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str());
}
-static void printConditionalJump(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int location, const char* op)
+void CodeBlock::printConditionalJump(ExecState* exec, const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator& it, int location, const char* op) const
{
int r0 = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(exec, r0).c_str(), offset, location + offset);
}
-static void printGetByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op)
+void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const
{
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());
+ printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
it += 4;
}
-static void printPutByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op)
+void CodeBlock::printPutByIdOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const
{
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());
+ printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str());
it += 4;
}
@@ -362,7 +358,7 @@ void CodeBlock::dump(ExecState* exec) const
unsigned registerIndex = m_numVars;
size_t i = 0;
do {
- printf(" r%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue()).ascii());
+ printf(" k%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue()).ascii());
++i;
++registerIndex;
} while (i < m_constantRegisters.size());
@@ -486,7 +482,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
case op_enter_with_activation: {
int r0 = (++it)->u.operand;
- printf("[%4d] enter_with_activation %s\n", location, registerName(r0).c_str());
+ printf("[%4d] enter_with_activation %s\n", location, registerName(exec, r0).c_str());
break;
}
case op_create_arguments: {
@@ -499,148 +495,148 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
case op_convert_this: {
int r0 = (++it)->u.operand;
- printf("[%4d] convert_this %s\n", location, registerName(r0).c_str());
+ printf("[%4d] convert_this %s\n", location, registerName(exec, r0).c_str());
break;
}
case op_new_object: {
int r0 = (++it)->u.operand;
- printf("[%4d] new_object\t %s\n", location, registerName(r0).c_str());
+ printf("[%4d] new_object\t %s\n", location, registerName(exec, 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);
+ printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, argv).c_str(), argc);
break;
}
case op_new_regexp: {
int r0 = (++it)->u.operand;
int re0 = (++it)->u.operand;
- printf("[%4d] new_regexp\t %s, %s\n", location, registerName(r0).c_str(), regexpName(re0, regexp(re0)).c_str());
+ printf("[%4d] new_regexp\t %s, %s\n", location, registerName(exec, 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());
+ printf("[%4d] mov\t\t %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str());
break;
}
case op_not: {
- printUnaryOp(location, it, "not");
+ printUnaryOp(exec, location, it, "not");
break;
}
case op_eq: {
- printBinaryOp(location, it, "eq");
+ printBinaryOp(exec, location, it, "eq");
break;
}
case op_eq_null: {
- printUnaryOp(location, it, "eq_null");
+ printUnaryOp(exec, location, it, "eq_null");
break;
}
case op_neq: {
- printBinaryOp(location, it, "neq");
+ printBinaryOp(exec, location, it, "neq");
break;
}
case op_neq_null: {
- printUnaryOp(location, it, "neq_null");
+ printUnaryOp(exec, location, it, "neq_null");
break;
}
case op_stricteq: {
- printBinaryOp(location, it, "stricteq");
+ printBinaryOp(exec, location, it, "stricteq");
break;
}
case op_nstricteq: {
- printBinaryOp(location, it, "nstricteq");
+ printBinaryOp(exec, location, it, "nstricteq");
break;
}
case op_less: {
- printBinaryOp(location, it, "less");
+ printBinaryOp(exec, location, it, "less");
break;
}
case op_lesseq: {
- printBinaryOp(location, it, "lesseq");
+ printBinaryOp(exec, 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());
+ printf("[%4d] pre_inc\t\t %s\n", location, registerName(exec, 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());
+ printf("[%4d] pre_dec\t\t %s\n", location, registerName(exec, r0).c_str());
break;
}
case op_post_inc: {
- printUnaryOp(location, it, "post_inc");
+ printUnaryOp(exec, location, it, "post_inc");
break;
}
case op_post_dec: {
- printUnaryOp(location, it, "post_dec");
+ printUnaryOp(exec, location, it, "post_dec");
break;
}
case op_to_jsnumber: {
- printUnaryOp(location, it, "to_jsnumber");
+ printUnaryOp(exec, location, it, "to_jsnumber");
break;
}
case op_negate: {
- printUnaryOp(location, it, "negate");
+ printUnaryOp(exec, location, it, "negate");
break;
}
case op_add: {
- printBinaryOp(location, it, "add");
+ printBinaryOp(exec, location, it, "add");
++it;
break;
}
case op_mul: {
- printBinaryOp(location, it, "mul");
+ printBinaryOp(exec, location, it, "mul");
++it;
break;
}
case op_div: {
- printBinaryOp(location, it, "div");
+ printBinaryOp(exec, location, it, "div");
++it;
break;
}
case op_mod: {
- printBinaryOp(location, it, "mod");
+ printBinaryOp(exec, location, it, "mod");
break;
}
case op_sub: {
- printBinaryOp(location, it, "sub");
+ printBinaryOp(exec, location, it, "sub");
++it;
break;
}
case op_lshift: {
- printBinaryOp(location, it, "lshift");
+ printBinaryOp(exec, location, it, "lshift");
break;
}
case op_rshift: {
- printBinaryOp(location, it, "rshift");
+ printBinaryOp(exec, location, it, "rshift");
break;
}
case op_urshift: {
- printBinaryOp(location, it, "urshift");
+ printBinaryOp(exec, location, it, "urshift");
break;
}
case op_bitand: {
- printBinaryOp(location, it, "bitand");
+ printBinaryOp(exec, location, it, "bitand");
++it;
break;
}
case op_bitxor: {
- printBinaryOp(location, it, "bitxor");
+ printBinaryOp(exec, location, it, "bitxor");
++it;
break;
}
case op_bitor: {
- printBinaryOp(location, it, "bitor");
+ printBinaryOp(exec, location, it, "bitor");
++it;
break;
}
case op_bitnot: {
- printUnaryOp(location, it, "bitnot");
+ printUnaryOp(exec, location, it, "bitnot");
break;
}
case op_instanceof: {
@@ -648,59 +644,59 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r1 = (++it)->u.operand;
int r2 = (++it)->u.operand;
int r3 = (++it)->u.operand;
- printf("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str());
+ printf("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str(), registerName(exec, r3).c_str());
break;
}
case op_typeof: {
- printUnaryOp(location, it, "typeof");
+ printUnaryOp(exec, location, it, "typeof");
break;
}
case op_is_undefined: {
- printUnaryOp(location, it, "is_undefined");
+ printUnaryOp(exec, location, it, "is_undefined");
break;
}
case op_is_boolean: {
- printUnaryOp(location, it, "is_boolean");
+ printUnaryOp(exec, location, it, "is_boolean");
break;
}
case op_is_number: {
- printUnaryOp(location, it, "is_number");
+ printUnaryOp(exec, location, it, "is_number");
break;
}
case op_is_string: {
- printUnaryOp(location, it, "is_string");
+ printUnaryOp(exec, location, it, "is_string");
break;
}
case op_is_object: {
- printUnaryOp(location, it, "is_object");
+ printUnaryOp(exec, location, it, "is_object");
break;
}
case op_is_function: {
- printUnaryOp(location, it, "is_function");
+ printUnaryOp(exec, location, it, "is_function");
break;
}
case op_in: {
- printBinaryOp(location, it, "in");
+ printBinaryOp(exec, 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());
+ printf("[%4d] resolve\t\t %s, %s\n", location, registerName(exec, 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);
+ printf("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), skipLevels);
break;
}
case op_resolve_global: {
int r0 = (++it)->u.operand;
JSValue scope = JSValue((++it)->u.jsCell);
int id0 = (++it)->u.operand;
- printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).c_str());
+ printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).c_str());
it += 2;
break;
}
@@ -708,244 +704,265 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r0 = (++it)->u.operand;
int index = (++it)->u.operand;
int skipLevels = (++it)->u.operand;
- printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(r0).c_str(), index, skipLevels);
+ printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(exec, 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());
+ printf("[%4d] put_scoped_var\t %d, %d, %s\n", location, index, skipLevels, registerName(exec, r0).c_str());
break;
}
case op_get_global_var: {
int r0 = (++it)->u.operand;
JSValue scope = JSValue((++it)->u.jsCell);
int index = (++it)->u.operand;
- printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), index);
+ printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(exec, r0).c_str(), valueToSourceString(exec, scope).ascii(), index);
break;
}
case op_put_global_var: {
JSValue scope = JSValue((++it)->u.jsCell);
int index = (++it)->u.operand;
int r0 = (++it)->u.operand;
- printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(r0).c_str());
+ printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(exec, 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());
+ printf("[%4d] resolve_base\t %s, %s\n", location, registerName(exec, 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());
+ printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
break;
}
case op_get_by_id: {
- printGetByIdOp(location, it, m_identifiers, "get_by_id");
+ printGetByIdOp(exec, location, it, "get_by_id");
break;
}
case op_get_by_id_self: {
- printGetByIdOp(location, it, m_identifiers, "get_by_id_self");
+ printGetByIdOp(exec, location, it, "get_by_id_self");
break;
}
case op_get_by_id_self_list: {
- printGetByIdOp(location, it, m_identifiers, "get_by_id_self_list");
+ printGetByIdOp(exec, location, it, "get_by_id_self_list");
break;
}
case op_get_by_id_proto: {
- printGetByIdOp(location, it, m_identifiers, "get_by_id_proto");
+ printGetByIdOp(exec, location, it, "get_by_id_proto");
break;
}
case op_get_by_id_proto_list: {
- printGetByIdOp(location, it, m_identifiers, "op_get_by_id_proto_list");
+ printGetByIdOp(exec, location, it, "op_get_by_id_proto_list");
break;
}
case op_get_by_id_chain: {
- printGetByIdOp(location, it, m_identifiers, "get_by_id_chain");
+ printGetByIdOp(exec, location, it, "get_by_id_chain");
break;
}
case op_get_by_id_generic: {
- printGetByIdOp(location, it, m_identifiers, "get_by_id_generic");
+ printGetByIdOp(exec, location, it, "get_by_id_generic");
break;
}
case op_get_array_length: {
- printGetByIdOp(location, it, m_identifiers, "get_array_length");
+ printGetByIdOp(exec, location, it, "get_array_length");
break;
}
case op_get_string_length: {
- printGetByIdOp(location, it, m_identifiers, "get_string_length");
+ printGetByIdOp(exec, location, it, "get_string_length");
break;
}
case op_put_by_id: {
- printPutByIdOp(location, it, m_identifiers, "put_by_id");
+ printPutByIdOp(exec, location, it, "put_by_id");
break;
}
case op_put_by_id_replace: {
- printPutByIdOp(location, it, m_identifiers, "put_by_id_replace");
+ printPutByIdOp(exec, location, it, "put_by_id_replace");
break;
}
case op_put_by_id_transition: {
- printPutByIdOp(location, it, m_identifiers, "put_by_id_transition");
+ printPutByIdOp(exec, location, it, "put_by_id_transition");
break;
}
case op_put_by_id_generic: {
- printPutByIdOp(location, it, m_identifiers, "put_by_id_generic");
+ printPutByIdOp(exec, location, it, "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());
+ printf("[%4d] put_getter\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str());
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());
+ printf("[%4d] put_setter\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str());
break;
}
case op_method_check: {
- printf("[%4d] op_method_check\n", location);
+ printf("[%4d] method_check\n", location);
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());
+ printf("[%4d] del_by_id\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
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());
+ printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str());
+ break;
+ }
+ case op_get_by_pname: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int r2 = (++it)->u.operand;
+ int r3 = (++it)->u.operand;
+ int r4 = (++it)->u.operand;
+ int r5 = (++it)->u.operand;
+ printf("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str(), registerName(exec, r3).c_str(), registerName(exec, r4).c_str(), registerName(exec, r5).c_str());
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());
+ printf("[%4d] put_by_val\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str());
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());
+ printf("[%4d] del_by_val\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str());
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());
+ printf("[%4d] put_by_index\t %s, %u, %s\n", location, registerName(exec, r0).c_str(), n0, registerName(exec, 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));
+ printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, location + offset);
break;
}
case op_loop: {
int offset = (++it)->u.operand;
- printf("[%4d] loop\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset));
+ printf("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset);
break;
}
case op_jtrue: {
- printConditionalJump(begin, it, location, "jtrue");
+ printConditionalJump(exec, begin, it, location, "jtrue");
break;
}
case op_loop_if_true: {
- printConditionalJump(begin, it, location, "loop_if_true");
+ printConditionalJump(exec, begin, it, location, "loop_if_true");
+ break;
+ }
+ case op_loop_if_false: {
+ printConditionalJump(exec, begin, it, location, "loop_if_false");
break;
}
case op_jfalse: {
- printConditionalJump(begin, it, location, "jfalse");
+ printConditionalJump(exec, begin, it, location, "jfalse");
break;
}
case op_jeq_null: {
- printConditionalJump(begin, it, location, "jeq_null");
+ printConditionalJump(exec, begin, it, location, "jeq_null");
break;
}
case op_jneq_null: {
- printConditionalJump(begin, it, location, "jneq_null");
+ printConditionalJump(exec, begin, it, location, "jneq_null");
break;
}
case op_jneq_ptr: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
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));
+ printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
break;
}
case op_jnlesseq: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
break;
}
case op_loop_if_less: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int offset = (++it)->u.operand;
- printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+ printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
+ break;
+ }
+ case op_jless: {
+ int r0 = (++it)->u.operand;
+ int r1 = (++it)->u.operand;
+ int offset = (++it)->u.operand;
+ printf("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
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));
+ printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
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());
+ printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, 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());
+ printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, 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());
+ printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, 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);
+ printf("[%4d] new_func\t\t %s, f%d\n", location, registerName(exec, 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);
+ printf("[%4d] new_func_exp\t %s, f%d\n", location, registerName(exec, r0).c_str(), f0);
break;
}
case op_call: {
@@ -953,7 +970,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int func = (++it)->u.operand;
int argCount = (++it)->u.operand;
int registerOffset = (++it)->u.operand;
- printf("[%4d] call\t\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset);
+ printf("[%4d] call\t\t %s, %s, %d, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), argCount, registerOffset);
break;
}
case op_call_eval: {
@@ -961,7 +978,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int func = (++it)->u.operand;
int argCount = (++it)->u.operand;
int registerOffset = (++it)->u.operand;
- printf("[%4d] call_eval\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset);
+ printf("[%4d] call_eval\t %s, %s, %d, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), argCount, registerOffset);
break;
}
case op_call_varargs: {
@@ -969,16 +986,16 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int func = (++it)->u.operand;
int argCount = (++it)->u.operand;
int registerOffset = (++it)->u.operand;
- printf("[%4d] call_varargs\t %s, %s, %s, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), registerName(argCount).c_str(), registerOffset);
+ printf("[%4d] call_varargs\t %s, %s, %s, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), registerName(exec, argCount).c_str(), registerOffset);
break;
}
case op_load_varargs: {
- printUnaryOp(location, it, "load_varargs");
+ printUnaryOp(exec, location, it, "load_varargs");
break;
}
case op_tear_off_activation: {
int r0 = (++it)->u.operand;
- printf("[%4d] tear_off_activation\t %s\n", location, registerName(r0).c_str());
+ printf("[%4d] tear_off_activation\t %s\n", location, registerName(exec, r0).c_str());
break;
}
case op_tear_off_arguments: {
@@ -987,7 +1004,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
case op_ret: {
int r0 = (++it)->u.operand;
- printf("[%4d] ret\t\t %s\n", location, registerName(r0).c_str());
+ printf("[%4d] ret\t\t %s\n", location, registerName(exec, r0).c_str());
break;
}
case op_construct: {
@@ -997,44 +1014,49 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int registerOffset = (++it)->u.operand;
int proto = (++it)->u.operand;
int thisRegister = (++it)->u.operand;
- printf("[%4d] construct\t %s, %s, %d, %d, %s, %s\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset, registerName(proto).c_str(), registerName(thisRegister).c_str());
+ printf("[%4d] construct\t %s, %s, %d, %d, %s, %s\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), argCount, registerOffset, registerName(exec, proto).c_str(), registerName(exec, thisRegister).c_str());
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());
+ printf("[%4d] construct_verify\t %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str());
break;
}
case op_strcat: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
int count = (++it)->u.operand;
- printf("[%4d] op_strcat\t %s, %s, %d\n", location, registerName(r0).c_str(), registerName(r1).c_str(), count);
+ printf("[%4d] strcat\t\t %s, %s, %d\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), count);
break;
}
case op_to_primitive: {
int r0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- printf("[%4d] op_to_primitive\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
+ printf("[%4d] to_primitive\t %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, 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());
+ int r0 = it[1].u.operand;
+ int r1 = it[2].u.operand;
+ int r2 = it[3].u.operand;
+ int r3 = it[4].u.operand;
+ int offset = it[5].u.operand;
+ printf("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str(), registerName(exec, r3).c_str(), offset, location + offset);
+ it += OPCODE_LENGTH(op_get_pnames) - 1;
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));
+ int dest = it[1].u.operand;
+ int iter = it[4].u.operand;
+ int offset = it[5].u.operand;
+ printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(exec, dest).c_str(), registerName(exec, iter).c_str(), offset, location + offset);
+ it += OPCODE_LENGTH(op_next_pname) - 1;
break;
}
case op_push_scope: {
int r0 = (++it)->u.operand;
- printf("[%4d] push_scope\t %s\n", location, registerName(r0).c_str());
+ printf("[%4d] push_scope\t %s\n", location, registerName(exec, r0).c_str());
break;
}
case op_pop_scope: {
@@ -1045,64 +1067,63 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int r0 = (++it)->u.operand;
int id0 = (++it)->u.operand;
int r1 = (++it)->u.operand;
- printf("[%4d] push_new_scope \t%s, %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());
+ printf("[%4d] push_new_scope \t%s, %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str());
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));
+ printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, location + offset);
break;
}
case op_catch: {
int r0 = (++it)->u.operand;
- printf("[%4d] catch\t\t %s\n", location, registerName(r0).c_str());
+ printf("[%4d] catch\t\t %s\n", location, registerName(exec, r0).c_str());
break;
}
case op_throw: {
int r0 = (++it)->u.operand;
- printf("[%4d] throw\t\t %s\n", location, registerName(r0).c_str());
+ printf("[%4d] throw\t\t %s\n", location, registerName(exec, 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, getConstant(k0)).c_str());
+ printf("[%4d] new_error\t %s, %d, %s\n", location, registerName(exec, r0).c_str(), errorType, constantName(exec, k0, getConstant(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));
+ printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(exec, retAddrDst).c_str(), offset, location + offset);
break;
}
case op_sret: {
int retAddrSrc = (++it)->u.operand;
- printf("[%4d] sret\t\t %s\n", location, registerName(retAddrSrc).c_str());
+ printf("[%4d] sret\t\t %s\n", location, registerName(exec, retAddrSrc).c_str());
break;
}
case op_debug: {
int debugHookID = (++it)->u.operand;
int firstLine = (++it)->u.operand;
int lastLine = (++it)->u.operand;
- int column = (++it)->u.operand;
- printf("[%4d] debug\t\t %s, %d, %d, %d\n", location, debugHookName(debugHookID), firstLine, lastLine, column);
+ 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());
+ printf("[%4d] profile_will_call %s\n", location, registerName(exec, 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());
+ printf("[%4d] profile_did_call\t %s\n", location, registerName(exec, function).c_str());
break;
}
case op_end: {
int r0 = (++it)->u.operand;
- printf("[%4d] end\t\t %s\n", location, registerName(r0).c_str());
+ printf("[%4d] end\t\t %s\n", location, registerName(exec, r0).c_str());
break;
}
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h
index 0163540..eb874cc 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/CodeBlock.h
@@ -438,13 +438,13 @@ namespace JSC {
size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
void addConstantRegister(const Register& r) { return m_constantRegisters.append(r); }
Register& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
- ALWAYS_INLINE bool isConstantRegisterIndex(int index) { return index >= FirstConstantRegisterIndex; }
+ ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].jsValue(); }
- unsigned addFunctionDecl(PassRefPtr<FunctionExecutable> n) { unsigned size = m_functionDecls.size(); m_functionDecls.append(n); return size; }
+ unsigned addFunctionDecl(NonNullPassRefPtr<FunctionExecutable> n) { unsigned size = m_functionDecls.size(); m_functionDecls.append(n); return size; }
FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
int numberOfFunctionDecls() { return m_functionDecls.size(); }
- unsigned addFunctionExpr(PassRefPtr<FunctionExecutable> n) { unsigned size = m_functionExprs.size(); m_functionExprs.append(n); return size; }
+ unsigned addFunctionExpr(NonNullPassRefPtr<FunctionExecutable> n) { unsigned size = m_functionExprs.size(); m_functionExprs.append(n); return size; }
FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
@@ -482,6 +482,13 @@ namespace JSC {
private:
#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
+
+ CString registerName(ExecState*, int r) const;
+ void printUnaryOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
+ void printBinaryOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
+ void printConditionalJump(ExecState*, const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator&, int location, const char* op) const;
+ void printGetByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
+ void printPutByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
#endif
void reparseForExceptionInfoIfNecessary(CallFrame*);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h
index cf50442..d9b2153 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/Opcode.h
@@ -113,6 +113,7 @@ namespace JSC {
macro(op_put_by_id_generic, 8) \
macro(op_del_by_id, 4) \
macro(op_get_by_val, 4) \
+ macro(op_get_by_pname, 7) \
macro(op_put_by_val, 4) \
macro(op_del_by_val, 4) \
macro(op_put_by_index, 4) \
@@ -127,9 +128,11 @@ namespace JSC {
macro(op_jneq_ptr, 4) \
macro(op_jnless, 4) \
macro(op_jnlesseq, 4) \
+ macro(op_jless, 4) \
macro(op_jmp_scopes, 3) \
macro(op_loop, 2) \
macro(op_loop_if_true, 3) \
+ macro(op_loop_if_false, 3) \
macro(op_loop_if_less, 4) \
macro(op_loop_if_lesseq, 4) \
macro(op_switch_imm, 4) \
@@ -152,8 +155,8 @@ namespace JSC {
macro(op_strcat, 4) \
macro(op_to_primitive, 3) \
\
- macro(op_get_pnames, 3) \
- macro(op_next_pname, 4) \
+ macro(op_get_pnames, 6) \
+ macro(op_next_pname, 7) \
\
macro(op_push_scope, 2) \
macro(op_pop_scope, 1) \
@@ -166,7 +169,7 @@ namespace JSC {
macro(op_jsr, 3) \
macro(op_sret, 2) \
\
- macro(op_debug, 5) \
+ macro(op_debug, 4) \
macro(op_profile_will_call, 2) \
macro(op_profile_did_call, 2) \
\
@@ -193,8 +196,12 @@ namespace JSC {
#undef VERIFY_OPCODE_ID
#if HAVE(COMPUTED_GOTO)
+#if COMPILER(RVCT)
typedef void* Opcode;
#else
+ typedef const void* Opcode;
+#endif
+#else
typedef OpcodeID Opcode;
#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp
index 865c919..3f0babc 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.cpp
@@ -33,7 +33,7 @@
#include "Interpreter.h"
#include "Opcode.h"
-#if !PLATFORM(WIN_OS)
+#if !OS(WINDOWS)
#include <unistd.h>
#endif
@@ -91,7 +91,7 @@ void SamplingFlags::stop() {}
uint32_t SamplingFlags::s_flags = 1 << 15;
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
static void sleepForMicroseconds(unsigned us)
{
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h
index 711b086..c3e6247 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecode/SamplingTool.h
@@ -113,7 +113,11 @@ namespace JSC {
void sample(CodeBlock*, Instruction*);
+#if COMPILER(WINSCW) || COMPILER(ACC)
ScriptExecutable* m_executable;
+#else
+ RefPtr<ScriptExecutable> m_executable;
+#endif
CodeBlock* m_codeBlock;
int m_sampleCount;
int m_opcodeSampleCount;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 10a1136..b0a0877 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -534,7 +534,7 @@ PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, c
m_labelScopes.removeLast();
// Allocate new label scope.
- LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>(0)); // Only loops have continue targets.
+ LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
m_labelScopes.append(scope);
return &m_labelScopes.last();
}
@@ -608,14 +608,15 @@ void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
{
+ size_t begin = instructions().size();
emitOpcode(target->isForward() ? op_jmp : op_loop);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target)
{
- if (m_lastOpcodeID == op_less && !target->isForward()) {
+ if (m_lastOpcodeID == op_less) {
int dstIndex;
int src1Index;
int src2Index;
@@ -624,10 +625,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
rewindBinaryOp();
- emitOpcode(op_loop_if_less);
+
+ size_t begin = instructions().size();
+ emitOpcode(target->isForward() ? op_jless : op_loop_if_less);
instructions().append(src1Index);
instructions().append(src2Index);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
} else if (m_lastOpcodeID == op_lesseq && !target->isForward()) {
@@ -639,10 +642,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
rewindBinaryOp();
+
+ size_t begin = instructions().size();
emitOpcode(op_loop_if_lesseq);
instructions().append(src1Index);
instructions().append(src2Index);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
} else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
@@ -653,9 +658,11 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
rewindUnaryOp();
+
+ size_t begin = instructions().size();
emitOpcode(op_jeq_null);
instructions().append(srcIndex);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
} else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
@@ -666,24 +673,26 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
rewindUnaryOp();
+
+ size_t begin = instructions().size();
emitOpcode(op_jneq_null);
instructions().append(srcIndex);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
}
+ size_t begin = instructions().size();
+
emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
instructions().append(cond->index());
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target)
{
- ASSERT(target->isForward());
-
- if (m_lastOpcodeID == op_less) {
+ if (m_lastOpcodeID == op_less && target->isForward()) {
int dstIndex;
int src1Index;
int src2Index;
@@ -692,13 +701,15 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta
if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
rewindBinaryOp();
+
+ size_t begin = instructions().size();
emitOpcode(op_jnless);
instructions().append(src1Index);
instructions().append(src2Index);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
- } else if (m_lastOpcodeID == op_lesseq) {
+ } else if (m_lastOpcodeID == op_lesseq && target->isForward()) {
int dstIndex;
int src1Index;
int src2Index;
@@ -707,10 +718,12 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta
if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
rewindBinaryOp();
+
+ size_t begin = instructions().size();
emitOpcode(op_jnlesseq);
instructions().append(src1Index);
instructions().append(src2Index);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
} else if (m_lastOpcodeID == op_not) {
@@ -721,12 +734,14 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta
if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
rewindUnaryOp();
- emitOpcode(op_jtrue);
+
+ size_t begin = instructions().size();
+ emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
instructions().append(srcIndex);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
- } else if (m_lastOpcodeID == op_eq_null) {
+ } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
int dstIndex;
int srcIndex;
@@ -734,12 +749,14 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta
if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
rewindUnaryOp();
+
+ size_t begin = instructions().size();
emitOpcode(op_jneq_null);
instructions().append(srcIndex);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
- } else if (m_lastOpcodeID == op_neq_null) {
+ } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
int dstIndex;
int srcIndex;
@@ -747,34 +764,41 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta
if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
rewindUnaryOp();
+
+ size_t begin = instructions().size();
emitOpcode(op_jeq_null);
instructions().append(srcIndex);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
}
- emitOpcode(op_jfalse);
+ size_t begin = instructions().size();
+ emitOpcode(target->isForward() ? op_jfalse : op_loop_if_false);
instructions().append(cond->index());
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target)
{
+ size_t begin = instructions().size();
+
emitOpcode(op_jneq_ptr);
instructions().append(cond->index());
instructions().append(m_scopeChain->globalObject()->d()->callFunction);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target)
{
+ size_t begin = instructions().size();
+
emitOpcode(op_jneq_ptr);
instructions().append(cond->index());
instructions().append(m_scopeChain->globalObject()->d()->applyFunction);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
@@ -880,7 +904,7 @@ RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst
&& src1->isTemporary()
&& m_codeBlock->isConstantRegisterIndex(src2->index())
&& m_codeBlock->constantRegister(src2->index()).jsValue().isString()) {
- const UString& value = asString(m_codeBlock->constantRegister(src2->index()).jsValue())->value();
+ const UString& value = asString(m_codeBlock->constantRegister(src2->index()).jsValue())->tryGetValue();
if (value == "undefined") {
rewindUnaryOp();
emitOpcode(op_is_undefined);
@@ -1255,6 +1279,19 @@ RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base,
RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
{
+ for (size_t i = m_forInContextStack.size(); i > 0; i--) {
+ ForInContext& context = m_forInContextStack[i - 1];
+ if (context.propertyRegister == property) {
+ emitOpcode(op_get_by_pname);
+ instructions().append(dst->index());
+ instructions().append(base->index());
+ instructions().append(property->index());
+ instructions().append(context.expectedSubscriptRegister->index());
+ instructions().append(context.iterRegister->index());
+ instructions().append(context.indexRegister->index());
+ return dst;
+ }
+ }
emitOpcode(op_get_by_val);
instructions().append(dst->index());
instructions().append(base->index());
@@ -1598,7 +1635,7 @@ void BytecodeGenerator::emitPopScope()
m_dynamicScopeDepth--;
}
-void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine, int column)
+void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
{
if (!m_shouldEmitDebugHooks)
return;
@@ -1606,7 +1643,6 @@ void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, in
instructions().append(debugHookID);
instructions().append(firstLine);
instructions().append(lastLine);
- instructions().append(column);
}
void BytecodeGenerator::pushFinallyContext(Label* target, RegisterID* retAddrDst)
@@ -1719,6 +1755,8 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro
}
if (nNormalScopes) {
+ size_t begin = instructions().size();
+
// We need to remove a number of dynamic scopes to get to the next
// finally block
emitOpcode(op_jmp_scopes);
@@ -1727,14 +1765,14 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro
// If topScope == bottomScope then there isn't actually a finally block
// left to emit, so make the jmp_scopes jump directly to the target label
if (topScope == bottomScope) {
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
// Otherwise we just use jmp_scopes to pop a group of scopes and go
// to the next instruction
RefPtr<Label> nextInsn = newLabel();
- instructions().append(nextInsn->offsetFrom(instructions().size()));
+ instructions().append(nextInsn->bind(begin, instructions().size()));
emitLabel(nextInsn.get());
}
@@ -1759,27 +1797,47 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetSco
if (m_finallyDepth)
return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
+ size_t begin = instructions().size();
+
emitOpcode(op_jmp_scopes);
instructions().append(scopeDelta);
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return target;
}
-RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target)
+RegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget)
+{
+ size_t begin = instructions().size();
+
+ emitOpcode(op_get_pnames);
+ instructions().append(dst->index());
+ instructions().append(base->index());
+ instructions().append(i->index());
+ instructions().append(size->index());
+ instructions().append(breakTarget->bind(begin, instructions().size()));
+ return dst;
+}
+
+RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target)
{
+ size_t begin = instructions().size();
+
emitOpcode(op_next_pname);
instructions().append(dst->index());
+ instructions().append(base->index());
+ instructions().append(i->index());
+ instructions().append(size->index());
instructions().append(iter->index());
- instructions().append(target->offsetFrom(instructions().size()));
+ instructions().append(target->bind(begin, instructions().size()));
return dst;
}
RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
{
#if ENABLE(JIT)
- HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
+ HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
#else
- HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
+ HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
#endif
m_codeBlock->addExceptionHandler(info);
@@ -1799,9 +1857,11 @@ RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSV
PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally)
{
+ size_t begin = instructions().size();
+
emitOpcode(op_jsr);
instructions().append(retAddrDst->index());
- instructions().append(finally->offsetFrom(instructions().size()));
+ instructions().append(finally->bind(begin, instructions().size()));
emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it.
return finally;
}
@@ -1871,7 +1931,7 @@ static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32
// We're emitting this after the clause labels should have been fixed, so
// the labels should not be "forward" references
ASSERT(!labels[i]->isForward());
- jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress));
+ jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
}
}
@@ -1897,7 +1957,7 @@ static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32
// We're emitting this after the clause labels should have been fixed, so
// the labels should not be "forward" references
ASSERT(!labels[i]->isForward());
- jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress));
+ jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
}
}
@@ -1911,7 +1971,7 @@ static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t
ASSERT(nodes[i]->isString());
UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep();
OffsetLocation location;
- location.branchOffset = labels[i]->offsetFrom(switchAddress);
+ location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3);
jumpTable.offsetTable.add(clause, location);
}
}
@@ -1922,23 +1982,23 @@ void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, E
m_switchContextStack.removeLast();
if (switchInfo.switchType == SwitchInfo::SwitchImmediate) {
instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables();
- instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
+ instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable();
- prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max);
+ prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
} else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) {
instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables();
- instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
+ instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable();
- prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max);
+ prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
} else {
ASSERT(switchInfo.switchType == SwitchInfo::SwitchString);
instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables();
- instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
+ instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
- prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes);
+ prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes);
}
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index f614f0b..8b6a425 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -61,6 +61,13 @@ namespace JSC {
FinallyContext finallyContext;
};
+ struct ForInContext {
+ RefPtr<RegisterID> expectedSubscriptRegister;
+ RefPtr<RegisterID> iterRegister;
+ RefPtr<RegisterID> indexRegister;
+ RefPtr<RegisterID> propertyRegister;
+ };
+
class BytecodeGenerator : public FastAllocBase {
public:
typedef DeclarationStacks::VarStack VarStack;
@@ -185,6 +192,19 @@ namespace JSC {
return emitNode(0, n);
}
+ void emitNodeInConditionContext(ExpressionNode* n, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
+ {
+ if (!m_codeBlock->numberOfLineInfos() || m_codeBlock->lastLineInfo().lineNumber != n->lineNo()) {
+ LineInfo info = { instructions().size(), n->lineNo() };
+ m_codeBlock->addLineInfo(info);
+ }
+ if (m_emitNodeDepth >= s_maxEmitNodeDepth)
+ emitThrowExpressionTooDeepException();
+ ++m_emitNodeDepth;
+ n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMeansTrue);
+ --m_emitNodeDepth;
+ }
+
void emitExpressionInfo(unsigned divot, unsigned startOffset, unsigned endOffset)
{
divot -= m_codeBlock->sourceOffset();
@@ -312,8 +332,8 @@ namespace JSC {
PassRefPtr<Label> emitJumpSubroutine(RegisterID* retAddrDst, Label*);
void emitSubroutineReturn(RegisterID* retAddrSrc);
- RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base); }
- RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target);
+ RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget);
+ RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target);
RegisterID* emitCatch(RegisterID*, Label* start, Label* end);
void emitThrow(RegisterID* exc) { emitUnaryNoDstOp(op_throw, exc); }
@@ -323,7 +343,7 @@ namespace JSC {
RegisterID* emitPushScope(RegisterID* scope);
void emitPopScope();
- void emitDebugHook(DebugHookID, int firstLine, int lastLine, int column );
+ void emitDebugHook(DebugHookID, int firstLine, int lastLine);
int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; }
bool hasFinaliser() { return m_finallyDepth != 0; }
@@ -331,6 +351,17 @@ namespace JSC {
void pushFinallyContext(Label* target, RegisterID* returnAddrDst);
void popFinallyContext();
+ void pushOptimisedForIn(RegisterID* expectedBase, RegisterID* iter, RegisterID* index, RegisterID* propertyRegister)
+ {
+ ForInContext context = { expectedBase, iter, index, propertyRegister };
+ m_forInContextStack.append(context);
+ }
+
+ void popOptimisedForIn()
+ {
+ m_forInContextStack.removeLast();
+ }
+
LabelScope* breakTarget(const Identifier&);
LabelScope* continueTarget(const Identifier&);
@@ -467,6 +498,7 @@ namespace JSC {
Vector<ControlFlowContext> m_scopeContextStack;
Vector<SwitchInfo> m_switchContextStack;
+ Vector<ForInContext> m_forInContextStack;
int m_nextGlobalIndex;
int m_nextParameterIndex;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/Label.h b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/Label.h
index 0b3d038..8cab1db 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/Label.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/Label.h
@@ -51,19 +51,17 @@ namespace JSC {
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;
- }
+ for (unsigned i = 0; i < size; ++i)
+ m_codeBlock->instructions()[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first;
}
- int offsetFrom(int location) const
+ int bind(int opcode, int offset) const
{
if (m_location == invalidLocation) {
- m_unresolvedJumps.append(location);
+ m_unresolvedJumps.append(std::make_pair(opcode, offset));
return 0;
}
- return m_location - location;
+ return m_location - opcode;
}
void ref() { ++m_refCount; }
@@ -77,7 +75,7 @@ namespace JSC {
bool isForward() const { return m_location == invalidLocation; }
private:
- typedef Vector<int, 8> JumpVector;
+ typedef Vector<std::pair<int, int>, 8> JumpVector;
static const unsigned invalidLocation = UINT_MAX;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/NodesCodegen.cpp
new file mode 100644
index 0000000..64b059d
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -0,0 +1,2012 @@
+/*
+* 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, 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>
+*
+* 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 "NodeConstructors.h"
+
+#include "BytecodeGenerator.h"
+#include "CallFrame.h"
+#include "Debugger.h"
+#include "JIT.h"
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "JSStaticScopeObject.h"
+#include "LabelScope.h"
+#include "Lexer.h"
+#include "Operations.h"
+#include "Parser.h"
+#include "PropertyNameArray.h"
+#include "RegExpObject.h"
+#include "SamplingTool.h"
+#include <wtf/Assertions.h>
+#include <wtf/RefCountedLeakCounter.h>
+#include <wtf/Threading.h>
+
+using namespace WTF;
+
+namespace JSC {
+
+/*
+ Details of the emitBytecode function.
+
+ Return value: The register holding the production's value.
+ dst: An optional parameter specifying the most efficient destination at
+ which to store the production's value. The callee must honor dst.
+
+ The dst argument provides for a crude form of copy propagation. For example,
+
+ x = 1
+
+ becomes
+
+ load r[x], 1
+
+ instead of
+
+ load r0, 1
+ mov r[x], r0
+
+ because the assignment node, "x =", passes r[x] as dst to the number node, "1".
+*/
+
+// ------------------------------ ThrowableExpressionData --------------------------------
+
+static void substitute(UString& string, const UString& substring)
+{
+ int position = string.find("%s");
+ ASSERT(position != -1);
+ string = makeString(string.substr(0, position), substring, string.substr(position + 2));
+}
+
+RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message)
+{
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message));
+ generator.emitThrow(exception);
+ return exception;
+}
+
+RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const UString& label)
+{
+ UString message = messageTemplate;
+ substitute(message, label);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message));
+ generator.emitThrow(exception);
+ return exception;
+}
+
+inline RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const Identifier& label)
+{
+ return emitThrowError(generator, type, messageTemplate, label.ustring());
+}
+
+// ------------------------------ NullNode -------------------------------------
+
+RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (dst == generator.ignoredResult())
+ return 0;
+ return generator.emitLoad(dst, jsNull());
+}
+
+// ------------------------------ BooleanNode ----------------------------------
+
+RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (dst == generator.ignoredResult())
+ return 0;
+ return generator.emitLoad(dst, m_value);
+}
+
+// ------------------------------ NumberNode -----------------------------------
+
+RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (dst == generator.ignoredResult())
+ return 0;
+ return generator.emitLoad(dst, m_value);
+}
+
+// ------------------------------ StringNode -----------------------------------
+
+RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (dst == generator.ignoredResult())
+ return 0;
+ return generator.emitLoad(dst, m_value);
+}
+
+// ------------------------------ RegExpNode -----------------------------------
+
+RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern.ustring(), m_flags.ustring());
+ if (!regExp->isValid())
+ return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage());
+ if (dst == generator.ignoredResult())
+ return 0;
+ return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
+}
+
+// ------------------------------ ThisNode -------------------------------------
+
+RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (dst == generator.ignoredResult())
+ return 0;
+ return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
+}
+
+// ------------------------------ ResolveNode ----------------------------------
+
+bool ResolveNode::isPure(BytecodeGenerator& generator) const
+{
+ return generator.isLocal(m_ident);
+}
+
+RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (RegisterID* local = generator.registerFor(m_ident)) {
+ if (dst == generator.ignoredResult())
+ return 0;
+ return generator.moveToDestinationIfNeeded(dst, local);
+ }
+
+ generator.emitExpressionInfo(m_startOffset + m_ident.size(), m_ident.size(), 0);
+ return generator.emitResolve(generator.finalDestination(dst), m_ident);
+}
+
+// ------------------------------ ArrayNode ------------------------------------
+
+RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ // FIXME: Should we put all of this code into emitNewArray?
+
+ unsigned length = 0;
+ ElementNode* firstPutElement;
+ for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
+ if (firstPutElement->elision())
+ break;
+ ++length;
+ }
+
+ if (!firstPutElement && !m_elision)
+ return generator.emitNewArray(generator.finalDestination(dst), m_element);
+
+ RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element);
+
+ for (ElementNode* n = firstPutElement; n; n = n->next()) {
+ RegisterID* value = generator.emitNode(n->value());
+ length += n->elision();
+ generator.emitPutByIndex(array.get(), length++, value);
+ }
+
+ if (m_elision) {
+ RegisterID* value = generator.emitLoad(0, jsNumber(generator.globalData(), m_elision + length));
+ generator.emitPutById(array.get(), generator.propertyNames().length, value);
+ }
+
+ return generator.moveToDestinationIfNeeded(dst, array.get());
+}
+
+bool ArrayNode::isSimpleArray() const
+{
+ if (m_elision || m_optional)
+ return false;
+ for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
+ if (ptr->elision())
+ return false;
+ }
+ return true;
+}
+
+ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData) const
+{
+ ASSERT(!m_elision && !m_optional);
+ ElementNode* ptr = m_element;
+ if (!ptr)
+ return 0;
+ ArgumentListNode* head = new (globalData) ArgumentListNode(globalData, ptr->value());
+ ArgumentListNode* tail = head;
+ ptr = ptr->next();
+ for (; ptr; ptr = ptr->next()) {
+ ASSERT(!ptr->elision());
+ tail = new (globalData) ArgumentListNode(globalData, tail, ptr->value());
+ }
+ return head;
+}
+
+// ------------------------------ ObjectLiteralNode ----------------------------
+
+RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (!m_list) {
+ if (dst == generator.ignoredResult())
+ return 0;
+ return generator.emitNewObject(generator.finalDestination(dst));
+ }
+ return generator.emitNode(dst, m_list);
+}
+
+// ------------------------------ PropertyListNode -----------------------------
+
+RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> newObj = generator.tempDestination(dst);
+
+ generator.emitNewObject(newObj.get());
+
+ for (PropertyListNode* p = this; p; p = p->m_next) {
+ RegisterID* value = generator.emitNode(p->m_node->m_assign);
+
+ switch (p->m_node->m_type) {
+ case PropertyNode::Constant: {
+ generator.emitPutById(newObj.get(), p->m_node->name(), value);
+ break;
+ }
+ case PropertyNode::Getter: {
+ generator.emitPutGetter(newObj.get(), p->m_node->name(), value);
+ break;
+ }
+ case PropertyNode::Setter: {
+ generator.emitPutSetter(newObj.get(), p->m_node->name(), value);
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+
+ return generator.moveToDestinationIfNeeded(dst, newObj.get());
+}
+
+// ------------------------------ BracketAccessorNode --------------------------------
+
+RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
+ RegisterID* property = generator.emitNode(m_subscript);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
+}
+
+// ------------------------------ DotAccessorNode --------------------------------
+
+RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RegisterID* base = generator.emitNode(m_base);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
+}
+
+// ------------------------------ ArgumentListNode -----------------------------
+
+RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ ASSERT(m_expr);
+ return generator.emitNode(dst, m_expr);
+}
+
+// ------------------------------ NewExprNode ----------------------------------
+
+RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> func = generator.emitNode(m_expr);
+ return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args, divot(), startOffset(), endOffset());
+}
+
+// ------------------------------ EvalFunctionCallNode ----------------------------------
+
+RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> func = generator.tempDestination(dst);
+ RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
+ generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
+ return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+}
+
+// ------------------------------ FunctionCallValueNode ----------------------------------
+
+RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> func = generator.emitNode(m_expr);
+ RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
+ return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+}
+
+// ------------------------------ FunctionCallResolveNode ----------------------------------
+
+RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
+ RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
+ return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args, 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);
+ RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
+ return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ }
+
+ RefPtr<RegisterID> func = generator.newTemporary();
+ RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ int identifierStart = divot() - startOffset();
+ generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
+ generator.emitResolveWithBase(thisRegister.get(), func.get(), m_ident);
+ return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+}
+
+// ------------------------------ FunctionCallBracketNode ----------------------------------
+
+RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> base = generator.emitNode(m_base);
+ RegisterID* property = generator.emitNode(m_subscript);
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
+ RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
+ return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+}
+
+// ------------------------------ FunctionCallDotNode ----------------------------------
+
+RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> function = generator.tempDestination(dst);
+ RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ generator.emitNode(thisRegister.get(), m_base);
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ generator.emitMethodCheck();
+ generator.emitGetById(function.get(), thisRegister.get(), m_ident);
+ return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+}
+
+RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<Label> realCall = generator.newLabel();
+ RefPtr<Label> end = generator.newLabel();
+ RefPtr<RegisterID> base = generator.emitNode(m_base);
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
+ RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
+ generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
+ {
+ RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+ RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ ArgumentListNode* oldList = m_args->m_listNode;
+ if (m_args->m_listNode && m_args->m_listNode->m_expr) {
+ generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
+ m_args->m_listNode = m_args->m_listNode->m_next;
+ } else
+ generator.emitLoad(thisRegister.get(), jsNull());
+
+ generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ generator.emitJump(end.get());
+ m_args->m_listNode = oldList;
+ }
+ generator.emitLabel(realCall.get());
+ {
+ RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
+ generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ }
+ generator.emitLabel(end.get());
+ return finalDestination.get();
+}
+
+static bool areTrivialApplyArguments(ArgumentsNode* args)
+{
+ return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
+ || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
+}
+
+RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ // A few simple cases can be trivially handled as ordinary function calls.
+ // function.apply(), function.apply(arg) -> identical to function.call
+ // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
+ bool mayBeCall = areTrivialApplyArguments(m_args);
+
+ RefPtr<Label> realCall = generator.newLabel();
+ RefPtr<Label> end = generator.newLabel();
+ RefPtr<RegisterID> base = generator.emitNode(m_base);
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
+ RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
+ generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
+ {
+ if (mayBeCall) {
+ RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+ RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ ArgumentListNode* oldList = m_args->m_listNode;
+ if (m_args->m_listNode && m_args->m_listNode->m_expr) {
+ generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
+ m_args->m_listNode = m_args->m_listNode->m_next;
+ if (m_args->m_listNode) {
+ ASSERT(m_args->m_listNode->m_expr->isSimpleArray());
+ ASSERT(!m_args->m_listNode->m_next);
+ m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_expr)->toArgumentList(generator.globalData());
+ }
+ } else
+ generator.emitLoad(thisRegister.get(), jsNull());
+ generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ m_args->m_listNode = oldList;
+ } else {
+ ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
+ RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
+ RefPtr<RegisterID> argsCountRegister = generator.newTemporary();
+ RefPtr<RegisterID> thisRegister = generator.newTemporary();
+ RefPtr<RegisterID> argsRegister = generator.newTemporary();
+ generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
+ ArgumentListNode* args = m_args->m_listNode->m_next;
+ bool isArgumentsApply = false;
+ if (args->m_expr->isResolveNode()) {
+ ResolveNode* resolveNode = static_cast<ResolveNode*>(args->m_expr);
+ isArgumentsApply = generator.willResolveToArguments(resolveNode->identifier());
+ if (isArgumentsApply)
+ generator.emitMove(argsRegister.get(), generator.uncheckedRegisterForArguments());
+ }
+ if (!isArgumentsApply)
+ generator.emitNode(argsRegister.get(), args->m_expr);
+ while ((args = args->m_next))
+ generator.emitNode(args->m_expr);
+
+ generator.emitLoadVarargs(argsCountRegister.get(), argsRegister.get());
+ generator.emitCallVarargs(finalDestination.get(), realFunction.get(), thisRegister.get(), argsCountRegister.get(), divot(), startOffset(), endOffset());
+ }
+ generator.emitJump(end.get());
+ }
+ generator.emitLabel(realCall.get());
+ {
+ RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
+ generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+ }
+ generator.emitLabel(end.get());
+ return finalDestination.get();
+}
+
+// ------------------------------ PostfixResolveNode ----------------------------------
+
+static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
+{
+ return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
+}
+
+static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
+{
+ if (srcDst == dst)
+ return generator.emitToJSNumber(dst, srcDst);
+ return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
+}
+
+RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (RegisterID* local = generator.registerFor(m_ident)) {
+ if (generator.isLocalConstant(m_ident)) {
+ if (dst == generator.ignoredResult())
+ return 0;
+ return generator.emitToJSNumber(generator.finalDestination(dst), local);
+ }
+
+ if (dst == generator.ignoredResult())
+ return emitPreIncOrDec(generator, local, m_operator);
+ return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
+ }
+
+ int index = 0;
+ size_t depth = 0;
+ JSObject* globalObject = 0;
+ 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 == generator.ignoredResult()) {
+ oldValue = 0;
+ emitPreIncOrDec(generator, value.get(), m_operator);
+ } else {
+ oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
+ }
+ generator.emitPutScopedVar(depth, index, value.get(), globalObject);
+ return oldValue;
+ }
+
+ 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 == generator.ignoredResult()) {
+ oldValue = 0;
+ emitPreIncOrDec(generator, value.get(), m_operator);
+ } else {
+ oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
+ }
+ generator.emitPutById(base.get(), m_ident, value.get());
+ return oldValue;
+}
+
+// ------------------------------ PostfixBracketNode ----------------------------------
+
+RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> base = generator.emitNode(m_base);
+ RefPtr<RegisterID> property = generator.emitNode(m_subscript);
+
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
+ RegisterID* oldValue;
+ if (dst == generator.ignoredResult()) {
+ oldValue = 0;
+ if (m_operator == OpPlusPlus)
+ generator.emitPreInc(value.get());
+ else
+ generator.emitPreDec(value.get());
+ } else {
+ oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
+ }
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitPutByVal(base.get(), property.get(), value.get());
+ return oldValue;
+}
+
+// ------------------------------ PostfixDotNode ----------------------------------
+
+RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> base = generator.emitNode(m_base);
+
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
+ RegisterID* oldValue;
+ if (dst == generator.ignoredResult()) {
+ oldValue = 0;
+ if (m_operator == OpPlusPlus)
+ generator.emitPreInc(value.get());
+ else
+ generator.emitPreDec(value.get());
+ } else {
+ oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
+ }
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitPutById(base.get(), m_ident, value.get());
+ return oldValue;
+}
+
+// ------------------------------ PostfixErrorNode -----------------------------------
+
+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::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (generator.registerFor(m_ident))
+ return generator.emitLoad(generator.finalDestination(dst), false);
+
+ 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::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> r0 = generator.emitNode(m_base);
+ RegisterID* r1 = generator.emitNode(m_subscript);
+
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
+}
+
+// ------------------------------ DeleteDotNode -----------------------------------
+
+RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RegisterID* r0 = generator.emitNode(m_base);
+
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
+}
+
+// ------------------------------ DeleteValueNode -----------------------------------
+
+RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitNode(generator.ignoredResult(), m_expr);
+
+ // delete on a non-location expression ignores the value and returns true
+ return generator.emitLoad(generator.finalDestination(dst), true);
+}
+
+// ------------------------------ VoidNode -------------------------------------
+
+RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (dst == generator.ignoredResult()) {
+ generator.emitNode(generator.ignoredResult(), m_expr);
+ return 0;
+ }
+ RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
+ return generator.emitLoad(dst, jsUndefined());
+}
+
+// ------------------------------ TypeOfValueNode -----------------------------------
+
+RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (RegisterID* local = generator.registerFor(m_ident)) {
+ 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 == generator.ignoredResult())
+ return 0;
+ return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
+}
+
+// ------------------------------ TypeOfValueNode -----------------------------------
+
+RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (dst == generator.ignoredResult()) {
+ generator.emitNode(generator.ignoredResult(), m_expr);
+ return 0;
+ }
+ RefPtr<RegisterID> src = generator.emitNode(m_expr);
+ return generator.emitTypeOf(generator.finalDestination(dst), src.get());
+}
+
+// ------------------------------ PrefixResolveNode ----------------------------------
+
+RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (RegisterID* local = generator.registerFor(m_ident)) {
+ if (generator.isLocalConstant(m_ident)) {
+ if (dst == generator.ignoredResult())
+ return 0;
+ RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
+ return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
+ }
+
+ emitPreIncOrDec(generator, local, m_operator);
+ return generator.moveToDestinationIfNeeded(dst, local);
+ }
+
+ int index = 0;
+ size_t depth = 0;
+ JSObject* globalObject = 0;
+ if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
+ RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
+ emitPreIncOrDec(generator, propDst.get(), m_operator);
+ generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
+ return generator.moveToDestinationIfNeeded(dst, propDst.get());
+ }
+
+ 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);
+ generator.emitPutById(base.get(), m_ident, propDst.get());
+ return generator.moveToDestinationIfNeeded(dst, propDst.get());
+}
+
+// ------------------------------ PrefixBracketNode ----------------------------------
+
+RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> base = generator.emitNode(m_base);
+ RefPtr<RegisterID> property = generator.emitNode(m_subscript);
+ RefPtr<RegisterID> propDst = generator.tempDestination(dst);
+
+ generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
+ RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
+ if (m_operator == OpPlusPlus)
+ generator.emitPreInc(value);
+ else
+ generator.emitPreDec(value);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitPutByVal(base.get(), property.get(), value);
+ return generator.moveToDestinationIfNeeded(dst, propDst.get());
+}
+
+// ------------------------------ PrefixDotNode ----------------------------------
+
+RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> base = generator.emitNode(m_base);
+ RefPtr<RegisterID> propDst = generator.tempDestination(dst);
+
+ 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(divot(), startOffset(), endOffset());
+ generator.emitPutById(base.get(), m_ident, value);
+ return generator.moveToDestinationIfNeeded(dst, propDst.get());
+}
+
+// ------------------------------ PrefixErrorNode -----------------------------------
+
+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::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RegisterID* src = generator.emitNode(m_expr);
+ return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
+}
+
+
+// ------------------------------ LogicalNotNode -----------------------------------
+
+void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
+{
+ ASSERT(expr()->hasConditionContextCodegen());
+
+ // reverse the true and false targets
+ generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, !fallThroughMeansTrue);
+}
+
+
+// ------------------------------ Binary Operation Nodes -----------------------------------
+
+// BinaryOpNode::emitStrcat:
+//
+// This node generates an op_strcat operation. This opcode can handle concatenation of three or
+// more values, where we can determine a set of separate op_add operations would be operating on
+// string values.
+//
+// This function expects to be operating on a graph of AST nodes looking something like this:
+//
+// (a)... (b)
+// \ /
+// (+) (c)
+// \ /
+// [d] ((+))
+// \ /
+// [+=]
+//
+// The assignment operation is optional, if it exists the register holding the value on the
+// lefthand side of the assignment should be passing as the optional 'lhs' argument.
+//
+// The method should be called on the node at the root of the tree of regular binary add
+// operations (marked in the diagram with a double set of parentheses). This node must
+// be performing a string concatenation (determined by statically detecting that at least
+// one child must be a string).
+//
+// Since the minimum number of values being concatenated together is expected to be 3, if
+// a lhs to a concatenating assignment is not provided then the root add should have at
+// least one left child that is also an add that can be determined to be operating on strings.
+//
+RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
+{
+ ASSERT(isAdd());
+ ASSERT(resultDescriptor().definitelyIsString());
+
+ // Create a list of expressions for all the adds in the tree of nodes we can convert into
+ // a string concatenation. The rightmost node (c) is added first. The rightmost node is
+ // added first, and the leftmost child is never added, so the vector produced for the
+ // example above will be [ c, b ].
+ Vector<ExpressionNode*, 16> reverseExpressionList;
+ reverseExpressionList.append(m_expr2);
+
+ // Examine the left child of the add. So long as this is a string add, add its right-child
+ // to the list, and keep processing along the left fork.
+ ExpressionNode* leftMostAddChild = m_expr1;
+ while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
+ reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
+ leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
+ }
+
+ Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
+
+ // If there is an assignment, allocate a temporary to hold the lhs after conversion.
+ // We could possibly avoid this (the lhs is converted last anyway, we could let the
+ // op_strcat node handle its conversion if required).
+ if (lhs)
+ temporaryRegisters.append(generator.newTemporary());
+
+ // Emit code for the leftmost node ((a) in the example).
+ temporaryRegisters.append(generator.newTemporary());
+ RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
+ generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
+
+ // Note on ordering of conversions:
+ //
+ // We maintain the same ordering of conversions as we would see if the concatenations
+ // was performed as a sequence of adds (otherwise this optimization could change
+ // behaviour should an object have been provided a valueOf or toString method).
+ //
+ // Considering the above example, the sequnce of execution is:
+ // * evaluate operand (a)
+ // * evaluate operand (b)
+ // * convert (a) to primitive <- (this would be triggered by the first add)
+ // * convert (b) to primitive <- (ditto)
+ // * evaluate operand (c)
+ // * convert (c) to primitive <- (this would be triggered by the second add)
+ // And optionally, if there is an assignment:
+ // * convert (d) to primitive <- (this would be triggered by the assigning addition)
+ //
+ // As such we do not plant an op to convert the leftmost child now. Instead, use
+ // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
+ // once the second node has been generated. However, if the leftmost child is an
+ // immediate we can trivially determine that no conversion will be required.
+ // If this is the case
+ if (leftMostAddChild->isString())
+ leftMostAddChildTempRegister = 0;
+
+ while (reverseExpressionList.size()) {
+ ExpressionNode* node = reverseExpressionList.last();
+ reverseExpressionList.removeLast();
+
+ // Emit the code for the current node.
+ temporaryRegisters.append(generator.newTemporary());
+ generator.emitNode(temporaryRegisters.last().get(), node);
+
+ // On the first iteration of this loop, when we first reach this point we have just
+ // generated the second node, which means it is time to convert the leftmost operand.
+ if (leftMostAddChildTempRegister) {
+ generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
+ leftMostAddChildTempRegister = 0; // Only do this once.
+ }
+ // Plant a conversion for this node, if necessary.
+ if (!node->isString())
+ generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
+ }
+ ASSERT(temporaryRegisters.size() >= 3);
+
+ // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
+ // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
+ if (emitExpressionInfoForMe)
+ generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
+
+ // If there is an assignment convert the lhs now. This will also copy lhs to
+ // the temporary register we allocated for it.
+ if (lhs)
+ generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
+
+ return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
+}
+
+RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ OpcodeID opcodeID = this->opcodeID();
+
+ if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString())
+ return emitStrcat(generator, dst);
+
+ if (opcodeID == op_neq) {
+ if (m_expr1->isNull() || m_expr2->isNull()) {
+ RefPtr<RegisterID> src = generator.tempDestination(dst);
+ generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
+ return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
+ }
+ }
+
+ RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+ RegisterID* src2 = generator.emitNode(m_expr2);
+ return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
+}
+
+RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (m_expr1->isNull() || m_expr2->isNull()) {
+ RefPtr<RegisterID> src = generator.tempDestination(dst);
+ generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
+ return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
+ }
+
+ RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+ RegisterID* src2 = generator.emitNode(m_expr2);
+ return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+ RegisterID* src2 = generator.emitNode(m_expr2);
+ return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+ RegisterID* src2 = generator.emitNode(m_expr2);
+ return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));
+}
+
+RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+ RegisterID* src2 = generator.emitNode(m_expr2);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
+}
+
+RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+ RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
+
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitGetByIdExceptionInfo(op_instanceof);
+ RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
+
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
+}
+
+// ------------------------------ LogicalOpNode ----------------------------
+
+RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> temp = generator.tempDestination(dst);
+ RefPtr<Label> target = generator.newLabel();
+
+ generator.emitNode(temp.get(), m_expr1);
+ if (m_operator == OpLogicalAnd)
+ generator.emitJumpIfFalse(temp.get(), target.get());
+ else
+ generator.emitJumpIfTrue(temp.get(), target.get());
+ generator.emitNode(temp.get(), m_expr2);
+ generator.emitLabel(target.get());
+
+ return generator.moveToDestinationIfNeeded(dst, temp.get());
+}
+
+void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
+{
+ if (m_expr1->hasConditionContextCodegen()) {
+ RefPtr<Label> afterExpr1 = generator.newLabel();
+ if (m_operator == OpLogicalAnd)
+ generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, true);
+ else
+ generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), false);
+ generator.emitLabel(afterExpr1.get());
+ } else {
+ RegisterID* temp = generator.emitNode(m_expr1);
+ if (m_operator == OpLogicalAnd)
+ generator.emitJumpIfFalse(temp, falseTarget);
+ else
+ generator.emitJumpIfTrue(temp, trueTarget);
+ }
+
+ if (m_expr2->hasConditionContextCodegen())
+ generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMeansTrue);
+ else {
+ RegisterID* temp = generator.emitNode(m_expr2);
+ if (fallThroughMeansTrue)
+ generator.emitJumpIfFalse(temp, falseTarget);
+ else
+ generator.emitJumpIfTrue(temp, trueTarget);
+ }
+}
+
+// ------------------------------ ConditionalNode ------------------------------
+
+RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> newDst = generator.finalDestination(dst);
+ RefPtr<Label> beforeElse = generator.newLabel();
+ RefPtr<Label> afterElse = generator.newLabel();
+
+ if (m_logical->hasConditionContextCodegen()) {
+ RefPtr<Label> beforeThen = generator.newLabel();
+ generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), true);
+ generator.emitLabel(beforeThen.get());
+ } else {
+ RegisterID* cond = generator.emitNode(m_logical);
+ generator.emitJumpIfFalse(cond, beforeElse.get());
+ }
+
+ generator.emitNode(newDst.get(), m_expr1);
+ generator.emitJump(afterElse.get());
+
+ generator.emitLabel(beforeElse.get());
+ generator.emitNode(newDst.get(), m_expr2);
+
+ generator.emitLabel(afterElse.get());
+
+ return newDst.get();
+}
+
+// ------------------------------ ReadModifyResolveNode -----------------------------------
+
+// FIXME: should this be moved to be a method on BytecodeGenerator?
+static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0)
+{
+ OpcodeID opcodeID;
+ switch (oper) {
+ case OpMultEq:
+ opcodeID = op_mul;
+ break;
+ case OpDivEq:
+ opcodeID = op_div;
+ break;
+ case OpPlusEq:
+ if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString())
+ return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
+ opcodeID = op_add;
+ break;
+ case OpMinusEq:
+ opcodeID = op_sub;
+ break;
+ case OpLShift:
+ opcodeID = op_lshift;
+ break;
+ case OpRShift:
+ opcodeID = op_rshift;
+ break;
+ case OpURShift:
+ opcodeID = op_urshift;
+ break;
+ case OpAndEq:
+ opcodeID = op_bitand;
+ break;
+ case OpXOrEq:
+ opcodeID = op_bitxor;
+ break;
+ case OpOrEq:
+ opcodeID = op_bitor;
+ break;
+ case OpModEq:
+ opcodeID = op_mod;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return dst;
+ }
+
+ RegisterID* src2 = generator.emitNode(m_right);
+
+ // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
+ // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
+ if (emitExpressionInfoForMe)
+ generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
+
+ return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
+}
+
+RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (RegisterID* local = generator.registerFor(m_ident)) {
+ if (generator.isLocalConstant(m_ident)) {
+ return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+ }
+
+ if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
+ RefPtr<RegisterID> result = generator.newTemporary();
+ generator.emitMove(result.get(), local);
+ emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+ generator.emitMove(local, result.get());
+ return generator.moveToDestinationIfNeeded(dst, result.get());
+ }
+
+ RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+ return generator.moveToDestinationIfNeeded(dst, result);
+ }
+
+ int index = 0;
+ size_t depth = 0;
+ JSObject* globalObject = 0;
+ if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
+ RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
+ RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+ generator.emitPutScopedVar(depth, index, result, globalObject);
+ return result;
+ }
+
+ RefPtr<RegisterID> src1 = generator.tempDestination(dst);
+ generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0);
+ RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
+ RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
+ return generator.emitPutById(base.get(), m_ident, result);
+}
+
+// ------------------------------ AssignResolveNode -----------------------------------
+
+RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (RegisterID* local = generator.registerFor(m_ident)) {
+ if (generator.isLocalConstant(m_ident))
+ return generator.emitNode(dst, m_right);
+
+ RegisterID* result = generator.emitNode(local, m_right);
+ return generator.moveToDestinationIfNeeded(dst, result);
+ }
+
+ int index = 0;
+ size_t depth = 0;
+ JSObject* globalObject = 0;
+ if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
+ if (dst == generator.ignoredResult())
+ dst = 0;
+ RegisterID* value = generator.emitNode(dst, m_right);
+ generator.emitPutScopedVar(depth, index, value, globalObject);
+ return value;
+ }
+
+ RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
+ if (dst == generator.ignoredResult())
+ dst = 0;
+ RegisterID* value = generator.emitNode(dst, m_right);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitPutById(base.get(), m_ident, value);
+}
+
+// ------------------------------ AssignDotNode -----------------------------------
+
+RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
+ RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
+ RegisterID* result = generator.emitNode(value.get(), m_right);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitPutById(base.get(), m_ident, result);
+ return generator.moveToDestinationIfNeeded(dst, result);
+}
+
+// ------------------------------ ReadModifyDotNode -----------------------------------
+
+RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
+
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
+ RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ return generator.emitPutById(base.get(), m_ident, updatedValue);
+}
+
+// ------------------------------ AssignErrorNode -----------------------------------
+
+RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+ return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
+}
+
+// ------------------------------ AssignBracketNode -----------------------------------
+
+RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
+ RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
+ RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
+ RegisterID* result = generator.emitNode(value.get(), m_right);
+
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitPutByVal(base.get(), property.get(), result);
+ return generator.moveToDestinationIfNeeded(dst, result);
+}
+
+// ------------------------------ ReadModifyBracketNode -----------------------------------
+
+RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
+ RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
+
+ generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+ RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
+ RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitPutByVal(base.get(), property.get(), updatedValue);
+
+ return updatedValue;
+}
+
+// ------------------------------ CommaNode ------------------------------------
+
+RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ ASSERT(m_expressions.size() > 1);
+ for (size_t i = 0; i < m_expressions.size() - 1; i++)
+ generator.emitNode(generator.ignoredResult(), m_expressions[i]);
+ return generator.emitNode(dst, m_expressions.last());
+}
+
+// ------------------------------ ConstDeclNode ------------------------------------
+
+RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
+{
+ if (RegisterID* local = generator.constRegisterFor(m_ident)) {
+ if (!m_init)
+ return local;
+
+ return generator.emitNode(local, m_init);
+ }
+
+ if (generator.codeType() != EvalCode) {
+ if (m_init)
+ return generator.emitNode(m_init);
+ else
+ return generator.emitResolve(generator.newTemporary(), m_ident);
+ }
+ // FIXME: While this code should only be hit in eval code, it will potentially
+ // assign to the wrong base if m_ident exists in an intervening dynamic scope.
+ RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
+ RegisterID* value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
+ return generator.emitPutById(base.get(), m_ident, value);
+}
+
+RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+ RegisterID* result = 0;
+ for (ConstDeclNode* n = this; n; n = n->m_next)
+ result = n->emitCodeSingle(generator);
+
+ return result;
+}
+
+// ------------------------------ ConstStatementNode -----------------------------
+
+RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ return generator.emitNode(m_next);
+}
+
+// ------------------------------ SourceElements -------------------------------
+
+
+inline StatementNode* SourceElements::lastStatement() const
+{
+ size_t size = m_statements.size();
+ return size ? m_statements[size - 1] : 0;
+}
+
+inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ size_t size = m_statements.size();
+ for (size_t i = 0; i < size; ++i)
+ generator.emitNode(dst, m_statements[i]);
+}
+
+// ------------------------------ BlockNode ------------------------------------
+
+inline StatementNode* BlockNode::lastStatement() const
+{
+ return m_statements ? m_statements->lastStatement() : 0;
+}
+
+RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (m_statements)
+ m_statements->emitBytecode(generator, dst);
+ return 0;
+}
+
+// ------------------------------ EmptyStatementNode ---------------------------
+
+RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ return dst;
+}
+
+// ------------------------------ DebuggerStatementNode ---------------------------
+
+RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
+ return dst;
+}
+
+// ------------------------------ ExprStatementNode ----------------------------
+
+RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ ASSERT(m_expr);
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ return generator.emitNode(dst, m_expr);
+}
+
+// ------------------------------ VarStatementNode ----------------------------
+
+RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+ ASSERT(m_expr);
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ return generator.emitNode(m_expr);
+}
+
+// ------------------------------ IfNode ---------------------------------------
+
+RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ RefPtr<Label> afterThen = generator.newLabel();
+
+ if (m_condition->hasConditionContextCodegen()) {
+ RefPtr<Label> beforeThen = generator.newLabel();
+ generator.emitNodeInConditionContext(m_condition, beforeThen.get(), afterThen.get(), true);
+ generator.emitLabel(beforeThen.get());
+ } else {
+ RegisterID* cond = generator.emitNode(m_condition);
+ generator.emitJumpIfFalse(cond, afterThen.get());
+ }
+
+ generator.emitNode(dst, m_ifBlock);
+ generator.emitLabel(afterThen.get());
+
+ // FIXME: This should return the last statement executed so that it can be returned as a Completion.
+ return 0;
+}
+
+// ------------------------------ IfElseNode ---------------------------------------
+
+RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ RefPtr<Label> beforeElse = generator.newLabel();
+ RefPtr<Label> afterElse = generator.newLabel();
+
+ if (m_condition->hasConditionContextCodegen()) {
+ RefPtr<Label> beforeThen = generator.newLabel();
+ generator.emitNodeInConditionContext(m_condition, beforeThen.get(), beforeElse.get(), true);
+ generator.emitLabel(beforeThen.get());
+ } else {
+ RegisterID* cond = generator.emitNode(m_condition);
+ generator.emitJumpIfFalse(cond, beforeElse.get());
+ }
+
+ generator.emitNode(dst, m_ifBlock);
+ generator.emitJump(afterElse.get());
+
+ generator.emitLabel(beforeElse.get());
+
+ generator.emitNode(dst, m_elseBlock);
+
+ generator.emitLabel(afterElse.get());
+
+ // FIXME: This should return the last statement executed so that it can be returned as a Completion.
+ return 0;
+}
+
+// ------------------------------ DoWhileNode ----------------------------------
+
+RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+
+ RefPtr<Label> topOfLoop = generator.newLabel();
+ generator.emitLabel(topOfLoop.get());
+
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
+
+ generator.emitLabel(scope->continueTarget());
+#ifndef QT_BUILD_SCRIPT_LIB
+ generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
+#endif
+ if (m_expr->hasConditionContextCodegen())
+ generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
+ else {
+ RegisterID* cond = generator.emitNode(m_expr);
+ generator.emitJumpIfTrue(cond, topOfLoop.get());
+ }
+
+ generator.emitLabel(scope->breakTarget());
+ return result.get();
+}
+
+// ------------------------------ WhileNode ------------------------------------
+
+RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+
+#ifdef QT_BUILD_SCRIPT_LIB
+ generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
+#endif
+ generator.emitJump(scope->continueTarget());
+
+ RefPtr<Label> topOfLoop = generator.newLabel();
+ generator.emitLabel(topOfLoop.get());
+
+ generator.emitNode(dst, m_statement);
+
+ generator.emitLabel(scope->continueTarget());
+#ifndef QT_BUILD_SCRIPT_LIB
+ generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
+#endif
+
+ if (m_expr->hasConditionContextCodegen())
+ generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
+ else {
+ RegisterID* cond = generator.emitNode(m_expr);
+ generator.emitJumpIfTrue(cond, topOfLoop.get());
+ }
+
+ generator.emitLabel(scope->breakTarget());
+
+ // FIXME: This should return the last statement executed so that it can be returned as a Completion
+ return 0;
+}
+
+// ------------------------------ ForNode --------------------------------------
+
+RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
+
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ if (m_expr1)
+ generator.emitNode(generator.ignoredResult(), m_expr1);
+
+ RefPtr<Label> condition = generator.newLabel();
+ generator.emitJump(condition.get());
+
+ RefPtr<Label> topOfLoop = generator.newLabel();
+ generator.emitLabel(topOfLoop.get());
+
+ RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
+
+ generator.emitLabel(scope->continueTarget());
+#ifndef QT_BUILD_SCRIPT_LIB
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+#endif
+ if (m_expr3)
+ generator.emitNode(generator.ignoredResult(), m_expr3);
+
+ generator.emitLabel(condition.get());
+ if (m_expr2) {
+ if (m_expr2->hasConditionContextCodegen())
+ generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), false);
+ else {
+ RegisterID* cond = generator.emitNode(m_expr2);
+ generator.emitJumpIfTrue(cond, topOfLoop.get());
+ }
+ } else
+ generator.emitJump(topOfLoop.get());
+
+ generator.emitLabel(scope->breakTarget());
+ return result.get();
+}
+
+// ------------------------------ ForInNode ------------------------------------
+
+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.");
+
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ if (m_init)
+ generator.emitNode(generator.ignoredResult(), m_init);
+
+ RefPtr<RegisterID> base = generator.newTemporary();
+ generator.emitNode(base.get(), m_expr);
+ RefPtr<RegisterID> i = generator.newTemporary();
+ RefPtr<RegisterID> size = generator.newTemporary();
+ RefPtr<RegisterID> expectedSubscript;
+ RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget());
+ generator.emitJump(scope->continueTarget());
+
+ RefPtr<Label> loopStart = generator.newLabel();
+ generator.emitLabel(loopStart.get());
+
+ RegisterID* propertyName;
+ bool optimizedForinAccess = false;
+ if (m_lexpr->isResolveNode()) {
+ const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
+ propertyName = generator.registerFor(ident);
+ if (!propertyName) {
+ propertyName = generator.newTemporary();
+ RefPtr<RegisterID> protect = propertyName;
+ RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
+
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitPutById(base, ident, propertyName);
+ } else {
+ expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName);
+ generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName);
+ optimizedForinAccess = true;
+ }
+ } else if (m_lexpr->isDotAccessorNode()) {
+ DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
+ const Identifier& ident = assignNode->identifier();
+ propertyName = generator.newTemporary();
+ RefPtr<RegisterID> protect = propertyName;
+ RegisterID* base = generator.emitNode(assignNode->base());
+
+ generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
+ generator.emitPutById(base, ident, propertyName);
+ } else {
+ ASSERT(m_lexpr->isBracketAccessorNode());
+ BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
+ propertyName = generator.newTemporary();
+ RefPtr<RegisterID> protect = propertyName;
+ RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
+ RegisterID* subscript = generator.emitNode(assignNode->subscript());
+
+ generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
+ generator.emitPutByVal(base.get(), subscript, propertyName);
+ }
+
+ generator.emitNode(dst, m_statement);
+
+ if (optimizedForinAccess)
+ generator.popOptimisedForIn();
+
+ generator.emitLabel(scope->continueTarget());
+ generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get());
+#ifndef QT_BUILD_SCRIPT_LIB
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+#endif
+ generator.emitLabel(scope->breakTarget());
+ return dst;
+}
+
+// ------------------------------ ContinueNode ---------------------------------
+
+// ECMA 12.7
+RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ LabelScope* scope = generator.continueTarget(m_ident);
+
+ if (!scope)
+ return m_ident.isEmpty()
+ ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
+ : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
+
+ generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
+ return dst;
+}
+
+// ------------------------------ BreakNode ------------------------------------
+
+// ECMA 12.8
+RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ LabelScope* scope = generator.breakTarget(m_ident);
+
+ if (!scope)
+ return m_ident.isEmpty()
+ ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
+ : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
+
+ generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
+ return dst;
+}
+
+// ------------------------------ ReturnNode -----------------------------------
+
+RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ if (generator.codeType() != FunctionCode)
+ return emitThrowError(generator, SyntaxError, "Invalid return statement.");
+
+ if (dst == generator.ignoredResult())
+ dst = 0;
+ RegisterID* r0 = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
+ RefPtr<RegisterID> returnRegister;
+ if (generator.scopeDepth()) {
+ RefPtr<Label> l0 = generator.newLabel();
+ if (generator.hasFinaliser() && !r0->isTemporary()) {
+ returnRegister = generator.emitMove(generator.newTemporary(), r0);
+ r0 = returnRegister.get();
+ }
+ generator.emitJumpScopes(l0.get(), 0);
+ generator.emitLabel(l0.get());
+ }
+ generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
+ return generator.emitReturn(r0);
+}
+
+// ------------------------------ WithNode -------------------------------------
+
+RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ RefPtr<RegisterID> scope = generator.newTemporary();
+ generator.emitNode(scope.get(), m_expr); // scope must be protected until popped
+ generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
+ generator.emitPushScope(scope.get());
+ RegisterID* result = generator.emitNode(dst, m_statement);
+ generator.emitPopScope();
+ return result;
+}
+
+// ------------------------------ CaseClauseNode --------------------------------
+
+inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (m_statements)
+ m_statements->emitBytecode(generator, dst);
+}
+
+// ------------------------------ CaseBlockNode --------------------------------
+
+enum SwitchKind {
+ SwitchUnset = 0,
+ SwitchNumber = 1,
+ SwitchString = 2,
+ SwitchNeither = 3
+};
+
+static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
+{
+ for (; list; list = list->getNext()) {
+ ExpressionNode* clauseExpression = list->getClause()->expr();
+ literalVector.append(clauseExpression);
+ if (clauseExpression->isNumber()) {
+ double value = static_cast<NumberNode*>(clauseExpression)->value();
+ int32_t intVal = static_cast<int32_t>(value);
+ if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
+ typeForTable = SwitchNeither;
+ break;
+ }
+ if (intVal < min_num)
+ min_num = intVal;
+ if (intVal > max_num)
+ max_num = intVal;
+ typeForTable = SwitchNumber;
+ continue;
+ }
+ if (clauseExpression->isString()) {
+ if (typeForTable & ~SwitchString) {
+ typeForTable = SwitchNeither;
+ break;
+ }
+ const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
+ if (singleCharacterSwitch &= value.size() == 1) {
+ int32_t intVal = value.rep()->data()[0];
+ if (intVal < min_num)
+ min_num = intVal;
+ if (intVal > max_num)
+ max_num = intVal;
+ }
+ typeForTable = SwitchString;
+ continue;
+ }
+ typeForTable = SwitchNeither;
+ break;
+ }
+}
+
+SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
+{
+ SwitchKind typeForTable = SwitchUnset;
+ bool singleCharacterSwitch = true;
+
+ processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
+ processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
+
+ if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
+ return SwitchInfo::SwitchNone;
+
+ if (typeForTable == SwitchNumber) {
+ int32_t range = max_num - min_num;
+ if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
+ return SwitchInfo::SwitchImmediate;
+ return SwitchInfo::SwitchNone;
+ }
+
+ ASSERT(typeForTable == SwitchString);
+
+ if (singleCharacterSwitch) {
+ int32_t range = max_num - min_num;
+ if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
+ return SwitchInfo::SwitchCharacter;
+ }
+
+ return SwitchInfo::SwitchString;
+}
+
+RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
+{
+ 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();
+ SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
+
+ if (switchType != SwitchInfo::SwitchNone) {
+ // Prepare the various labels
+ for (uint32_t i = 0; i < literalVector.size(); i++)
+ labelVector.append(generator.newLabel());
+ defaultLabel = generator.newLabel();
+ generator.beginSwitch(switchExpression, switchType);
+ } else {
+ // Setup jumps
+ for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
+ RefPtr<RegisterID> clauseVal = generator.newTemporary();
+ generator.emitNode(clauseVal.get(), list->getClause()->expr());
+ generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
+ labelVector.append(generator.newLabel());
+ generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
+ }
+
+ for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
+ RefPtr<RegisterID> clauseVal = generator.newTemporary();
+ generator.emitNode(clauseVal.get(), list->getClause()->expr());
+ generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
+ labelVector.append(generator.newLabel());
+ generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
+ }
+ defaultLabel = generator.newLabel();
+ generator.emitJump(defaultLabel.get());
+ }
+
+ RegisterID* result = 0;
+
+ size_t i = 0;
+ for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
+ generator.emitLabel(labelVector[i++].get());
+ list->getClause()->emitBytecode(generator, dst);
+ }
+
+ if (m_defaultClause) {
+ generator.emitLabel(defaultLabel.get());
+ m_defaultClause->emitBytecode(generator, dst);
+ }
+
+ for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
+ generator.emitLabel(labelVector[i++].get());
+ list->getClause()->emitBytecode(generator, dst);
+ }
+ if (!m_defaultClause)
+ generator.emitLabel(defaultLabel.get());
+
+ ASSERT(i == labelVector.size());
+ if (switchType != SwitchInfo::SwitchNone) {
+ ASSERT(labelVector.size() == literalVector.size());
+ generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
+ }
+ return result;
+}
+
+// ------------------------------ SwitchNode -----------------------------------
+
+RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
+
+ RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
+ RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
+
+ generator.emitLabel(scope->breakTarget());
+ return r1;
+}
+
+// ------------------------------ LabelNode ------------------------------------
+
+RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ if (generator.breakTarget(m_name))
+ return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
+
+ RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
+ RegisterID* r0 = generator.emitNode(dst, m_statement);
+
+ generator.emitLabel(scope->breakTarget());
+ return r0;
+}
+
+// ------------------------------ ThrowNode ------------------------------------
+
+RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
+ if (dst == generator.ignoredResult())
+ dst = 0;
+ RefPtr<RegisterID> expr = generator.emitNode(m_expr);
+ generator.emitExpressionInfo(divot(), startOffset(), endOffset());
+ generator.emitThrow(expr.get());
+ return 0;
+}
+
+// ------------------------------ TryNode --------------------------------------
+
+RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ // NOTE: The catch and finally blocks must be labeled explicitly, so the
+ // optimizer knows they may be jumped to from anywhere.
+
+#ifndef QT_BUILD_SCRIPT_LIB
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+#endif
+
+ RefPtr<Label> tryStartLabel = generator.newLabel();
+ RefPtr<Label> finallyStart;
+ RefPtr<RegisterID> finallyReturnAddr;
+ if (m_finallyBlock) {
+ finallyStart = generator.newLabel();
+ finallyReturnAddr = generator.newTemporary();
+ generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
+ }
+
+ generator.emitLabel(tryStartLabel.get());
+ generator.emitNode(dst, m_tryBlock);
+
+ if (m_catchBlock) {
+ RefPtr<Label> catchEndLabel = generator.newLabel();
+
+ // Normal path: jump over the catch block.
+ generator.emitJump(catchEndLabel.get());
+
+ // Uncaught exception path: the catch block.
+ RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
+ RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
+ if (m_catchHasEval) {
+ RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
+ generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
+ generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get());
+ generator.emitPushScope(exceptionRegister.get());
+ } else
+ generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
+ generator.emitNode(dst, m_catchBlock);
+ generator.emitPopScope();
+ generator.emitLabel(catchEndLabel.get());
+ }
+
+ if (m_finallyBlock) {
+ generator.popFinallyContext();
+ // there may be important registers live at the time we jump
+ // to a finally block (such as for a return or throw) so we
+ // ref the highest register ever used as a conservative
+ // approach to not clobbering anything important
+ RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
+ RefPtr<Label> finallyEndLabel = generator.newLabel();
+
+ // Normal path: invoke the finally block, then jump over it.
+ generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
+ generator.emitJump(finallyEndLabel.get());
+
+ // Uncaught exception path: invoke the finally block, then re-throw the exception.
+ RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
+ RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
+ generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
+ generator.emitThrow(tempExceptionRegister.get());
+
+ // The finally block.
+ generator.emitLabel(finallyStart.get());
+ generator.emitNode(dst, m_finallyBlock);
+ generator.emitSubroutineReturn(finallyReturnAddr.get());
+
+ generator.emitLabel(finallyEndLabel.get());
+ }
+
+ return dst;
+}
+
+// ------------------------------ ScopeNode -----------------------------
+
+inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (m_data->m_statements)
+ m_data->m_statements->emitBytecode(generator, dst);
+}
+
+// ------------------------------ ProgramNode -----------------------------
+
+RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+ generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
+
+ RefPtr<RegisterID> dstRegister = generator.newTemporary();
+ generator.emitLoad(dstRegister.get(), jsUndefined());
+ emitStatementsBytecode(generator, dstRegister.get());
+
+ generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
+ generator.emitEnd(dstRegister.get());
+ return 0;
+}
+
+// ------------------------------ EvalNode -----------------------------
+
+RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+ generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
+
+ RefPtr<RegisterID> dstRegister = generator.newTemporary();
+ generator.emitLoad(dstRegister.get(), jsUndefined());
+ emitStatementsBytecode(generator, dstRegister.get());
+
+ generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine());
+ generator.emitEnd(dstRegister.get());
+ return 0;
+}
+
+// ------------------------------ FunctionBodyNode -----------------------------
+
+RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
+{
+ generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
+ emitStatementsBytecode(generator, generator.ignoredResult());
+ StatementNode* singleStatement = this->singleStatement();
+ if (singleStatement && singleStatement->isBlock()) {
+ StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
+ if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
+ return 0;
+ }
+
+ RegisterID* r0 = generator.emitLoad(0, jsUndefined());
+ generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
+ generator.emitReturn(r0);
+ return 0;
+}
+
+// ------------------------------ FuncDeclNode ---------------------------------
+
+RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ if (dst == generator.ignoredResult())
+ dst = 0;
+ return dst;
+}
+
+// ------------------------------ FuncExprNode ---------------------------------
+
+RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+ return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
+}
+
+} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/config.h b/src/3rdparty/javascriptcore/JavaScriptCore/config.h
index 5e70265..d5fdfe9 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/config.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/config.h
@@ -25,26 +25,26 @@
#include <wtf/Platform.h>
-#if !defined(JS_EXPORTDATA)
-#if PLATFORM(WIN_OS) && !defined(BUILDING_WX__) && !COMPILER(GCC)
+#if OS(WINDOWS) && !defined(BUILDING_WX__) && !COMPILER(GCC)
#if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
#define JS_EXPORTDATA __declspec(dllexport)
#else
#define JS_EXPORTDATA __declspec(dllimport)
#endif
+#define JS_EXPORTCLASS JS_EXPORTDATA
#else
#define JS_EXPORTDATA
-#endif
+#define JS_EXPORTCLASS
#endif
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
// If we don't define these, they get defined in windef.h.
// We want to use std::min and std::max
#define max max
#define min min
-#if !COMPILER(MSVC7) && !PLATFORM(WINCE)
+#if !COMPILER(MSVC7) && !OS(WINCE)
// We need to define this before the first #include of stdlib.h or it won't contain rand_s.
#ifndef _CRT_RAND_S
#define _CRT_RAND_S
@@ -53,13 +53,12 @@
#endif
-#if PLATFORM(FREEBSD) || PLATFORM(OPENBSD)
+#if OS(FREEBSD) || OS(OPENBSD)
#define HAVE_PTHREAD_NP_H 1
#endif
/* FIXME: if all platforms have these, do they really need #defines? */
#define HAVE_STDINT_H 1
-#define HAVE_STRING_H 1
#define WTF_CHANGES 1
@@ -76,3 +75,15 @@
#include <wtf/DisallowCType.h>
#endif
+#if PLATFORM(CHROMIUM)
+#if !defined(WTF_USE_V8)
+#define WTF_USE_V8 1
+#endif
+#endif /* PLATFORM(CHROMIUM) */
+
+#if !defined(WTF_USE_V8)
+#define WTF_USE_V8 0
+#endif /* !defined(WTF_USE_V8) */
+
+/* Using V8 implies not using JSC and vice versa */
+#define WTF_USE_JSC !WTF_USE_V8
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp
index db02329..1d2e4fb 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.cpp
@@ -67,8 +67,9 @@ void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
FunctionExecutableSet functionExecutables;
SourceProviderMap sourceProviders;
- Heap::iterator heapEnd = globalData->heap.primaryHeapEnd();
- for (Heap::iterator it = globalData->heap.primaryHeapBegin(); it != heapEnd; ++it) {
+ LiveObjectIterator it = globalData->heap.primaryHeapBegin();
+ LiveObjectIterator heapEnd = globalData->heap.primaryHeapEnd();
+ for ( ; it != heapEnd; ++it) {
if (!(*it)->inherits(&JSFunction::info))
continue;
@@ -100,12 +101,12 @@ JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSG
{
CallFrame* globalCallFrame = globalObject->globalExec();
- EvalExecutable eval(globalCallFrame, makeSource(script));
- JSObject* error = eval.compile(globalCallFrame, globalCallFrame->scopeChain());
+ RefPtr<EvalExecutable> eval = EvalExecutable::create(globalCallFrame, makeSource(script));
+ JSObject* error = eval->compile(globalCallFrame, globalCallFrame->scopeChain());
if (error)
return error;
- return globalObject->globalData()->interpreter->execute(&eval, globalCallFrame, globalObject, globalCallFrame->scopeChain(), &exception);
+ return globalObject->globalData()->interpreter->execute(eval.get(), globalCallFrame, globalObject, globalCallFrame->scopeChain(), &exception);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.h b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.h
index 811818d..3725478 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/Debugger.h
@@ -47,8 +47,7 @@ namespace JSC {
{
UNUSED_PARAM(id);
};
- virtual void scriptLoad(QT_PREPEND_NAMESPACE(qint64) id,
- const UString &program,
+ virtual void scriptLoad(QT_PREPEND_NAMESPACE(qint64) id, const UString &program,
const UString &fileName, int baseLineNumber)
{
UNUSED_PARAM(id);
@@ -90,14 +89,14 @@ namespace JSC {
#endif
virtual void sourceParsed(ExecState*, const SourceCode&, int errorLineNumber, const UString& errorMessage) = 0;
- virtual void exception(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
- virtual void atStatement(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber, int column) = 0;
+ virtual void exception(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber, bool hasHandler) = 0;
+ virtual void atStatement(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
virtual void callEvent(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
virtual void returnEvent(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
virtual void willExecuteProgram(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
virtual void didExecuteProgram(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
- virtual void didReachBreakpoint(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber, int column) = 0;
+ virtual void didReachBreakpoint(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0;
void recompileAllJSFunctions(JSGlobalData*);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.cpp
index fa41374..0444d23 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.cpp
@@ -66,19 +66,19 @@ void DebuggerActivation::putWithAttributes(ExecState* exec, const Identifier& pr
m_activation->putWithAttributes(exec, propertyName, value, attributes);
}
-bool DebuggerActivation::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+bool DebuggerActivation::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
- return m_activation->deleteProperty(exec, propertyName, checkDontDelete);
+ return m_activation->deleteProperty(exec, propertyName);
}
-void DebuggerActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable)
+void DebuggerActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
- m_activation->getPropertyNames(exec, propertyNames);
+ m_activation->getPropertyNames(exec, propertyNames, mode);
}
-bool DebuggerActivation::getPropertyAttributes(JSC::ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
+bool DebuggerActivation::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
- return m_activation->getPropertyAttributes(exec, propertyName, attributes);
+ return m_activation->getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
void DebuggerActivation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.h b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.h
index 9bb1acd..354fcb8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerActivation.h
@@ -41,9 +41,9 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
- virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
- virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false);
- virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+ virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
+ virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes);
virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes);
virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName);
@@ -51,9 +51,12 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | JSObject::StructureFlags;
+
private:
JSActivation* m_activation;
};
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp
index 88b14e6..c6b4223 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/debugger/DebuggerCallFrame.cpp
@@ -44,7 +44,7 @@ const UString* DebuggerCallFrame::functionName() const
JSFunction* function = asFunction(m_callFrame->callee());
if (!function)
return 0;
- return &function->name(&m_callFrame->globalData());
+ return &function->name(m_callFrame);
}
UString DebuggerCallFrame::calculatedFunctionName() const
@@ -55,7 +55,7 @@ UString DebuggerCallFrame::calculatedFunctionName() const
JSFunction* function = asFunction(m_callFrame->callee());
if (!function)
return 0;
- return function->calculatedDisplayName(&m_callFrame->globalData());
+ return function->calculatedDisplayName(m_callFrame);
}
DebuggerCallFrame::Type DebuggerCallFrame::type() const
@@ -79,12 +79,12 @@ JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) c
if (!m_callFrame->codeBlock())
return JSValue();
- EvalExecutable eval(m_callFrame, makeSource(script));
- JSObject* error = eval.compile(m_callFrame, m_callFrame->scopeChain());
+ RefPtr<EvalExecutable> eval = EvalExecutable::create(m_callFrame, makeSource(script));
+ JSObject* error = eval->compile(m_callFrame, m_callFrame->scopeChain());
if (error)
return error;
- return m_callFrame->scopeChain()->globalData->interpreter->execute(&eval, m_callFrame, thisObject(), m_callFrame->scopeChain(), &exception);
+ return m_callFrame->scopeChain()->globalData->interpreter->execute(eval.get(), m_callFrame, thisObject(), m_callFrame->scopeChain(), &exception);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/ArrayPrototype.lut.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/ArrayPrototype.lut.h
index 5732add..860176e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/ArrayPrototype.lut.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/ArrayPrototype.lut.h
@@ -1,4 +1,4 @@
-// Automatically generated from ../runtime/ArrayPrototype.cpp using JavaScriptCore/create_hash_table. DO NOT EDIT!
+// Automatically generated from runtime/ArrayPrototype.cpp using /home/khansen/dev/qtwebkit-qtscript-integration/JavaScriptCore/create_hash_table. DO NOT EDIT!
#include "Lookup.h"
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/DatePrototype.lut.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/DatePrototype.lut.h
index 8b1c735..395669a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/DatePrototype.lut.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/DatePrototype.lut.h
@@ -1,4 +1,4 @@
-// Automatically generated from ../runtime/DatePrototype.cpp using JavaScriptCore/create_hash_table. DO NOT EDIT!
+// Automatically generated from runtime/DatePrototype.cpp using /home/khansen/dev/qtwebkit-qtscript-integration/JavaScriptCore/create_hash_table. DO NOT EDIT!
#include "Lookup.h"
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h
new file mode 100644
index 0000000..ef77e19
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/GeneratedJITStubs_RVCT.h
@@ -0,0 +1,1199 @@
+extern "C" EncodedJSValue JITStubThunked_op_convert_this(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_convert_this(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_convert_this
+ str lr, [sp, #32]
+ bl JITStubThunked_op_convert_this
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_end(STUB_ARGS_DECLARATION);
+__asm void cti_op_end(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_end
+ str lr, [sp, #32]
+ bl JITStubThunked_op_end
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_add(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_add(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_add
+ str lr, [sp, #32]
+ bl JITStubThunked_op_add
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_pre_inc(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_pre_inc(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_pre_inc
+ str lr, [sp, #32]
+ bl JITStubThunked_op_pre_inc
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" int JITStubThunked_timeout_check(STUB_ARGS_DECLARATION);
+__asm int cti_timeout_check(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_timeout_check
+ str lr, [sp, #32]
+ bl JITStubThunked_timeout_check
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_register_file_check(STUB_ARGS_DECLARATION);
+__asm void cti_register_file_check(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_register_file_check
+ str lr, [sp, #32]
+ bl JITStubThunked_register_file_check
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" int JITStubThunked_op_loop_if_lesseq(STUB_ARGS_DECLARATION);
+__asm int cti_op_loop_if_lesseq(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_loop_if_lesseq
+ str lr, [sp, #32]
+ bl JITStubThunked_op_loop_if_lesseq
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_new_object(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_new_object(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_new_object
+ str lr, [sp, #32]
+ bl JITStubThunked_op_new_object
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_put_by_id_generic(STUB_ARGS_DECLARATION);
+__asm void cti_op_put_by_id_generic(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_put_by_id_generic
+ str lr, [sp, #32]
+ bl JITStubThunked_op_put_by_id_generic
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_id_generic(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_id_generic(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_id_generic
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_id_generic
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_put_by_id(STUB_ARGS_DECLARATION);
+__asm void cti_op_put_by_id(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_put_by_id
+ str lr, [sp, #32]
+ bl JITStubThunked_op_put_by_id
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_put_by_id_fail(STUB_ARGS_DECLARATION);
+__asm void cti_op_put_by_id_fail(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_put_by_id_fail
+ str lr, [sp, #32]
+ bl JITStubThunked_op_put_by_id_fail
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_put_by_id_transition_realloc
+ str lr, [sp, #32]
+ bl JITStubThunked_op_put_by_id_transition_realloc
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_id_method_check(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_id_method_check(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_id_method_check
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_id_method_check
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_id(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_id(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_id
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_id
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_id_self_fail(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_id_self_fail(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_id_self_fail
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_id_self_fail
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_id_proto_list(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_id_proto_list(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_id_proto_list
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_id_proto_list
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_id_proto_list_full(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_id_proto_list_full(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_id_proto_list_full
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_id_proto_list_full
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_id_proto_fail(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_id_proto_fail(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_id_proto_fail
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_id_proto_fail
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_id_array_fail(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_id_array_fail(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_id_array_fail
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_id_array_fail
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_id_string_fail(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_id_string_fail(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_id_string_fail
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_id_string_fail
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_instanceof(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_instanceof(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_instanceof
+ str lr, [sp, #32]
+ bl JITStubThunked_op_instanceof
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_del_by_id(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_del_by_id(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_del_by_id
+ str lr, [sp, #32]
+ bl JITStubThunked_op_del_by_id
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_mul(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_mul(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_mul
+ str lr, [sp, #32]
+ bl JITStubThunked_op_mul
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_new_func(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_new_func(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_new_func
+ str lr, [sp, #32]
+ bl JITStubThunked_op_new_func
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void* JITStubThunked_op_call_JSFunction(STUB_ARGS_DECLARATION);
+__asm void* cti_op_call_JSFunction(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_call_JSFunction
+ str lr, [sp, #32]
+ bl JITStubThunked_op_call_JSFunction
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" VoidPtrPair JITStubThunked_op_call_arityCheck(STUB_ARGS_DECLARATION);
+__asm VoidPtrPair cti_op_call_arityCheck(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_call_arityCheck
+ str lr, [sp, #32]
+ bl JITStubThunked_op_call_arityCheck
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void* JITStubThunked_vm_lazyLinkCall(STUB_ARGS_DECLARATION);
+__asm void* cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_vm_lazyLinkCall
+ str lr, [sp, #32]
+ bl JITStubThunked_vm_lazyLinkCall
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_push_activation(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_push_activation(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_push_activation
+ str lr, [sp, #32]
+ bl JITStubThunked_op_push_activation
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_call_NotJSFunction(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_call_NotJSFunction
+ str lr, [sp, #32]
+ bl JITStubThunked_op_call_NotJSFunction
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_create_arguments(STUB_ARGS_DECLARATION);
+__asm void cti_op_create_arguments(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_create_arguments
+ str lr, [sp, #32]
+ bl JITStubThunked_op_create_arguments
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_create_arguments_no_params(STUB_ARGS_DECLARATION);
+__asm void cti_op_create_arguments_no_params(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_create_arguments_no_params
+ str lr, [sp, #32]
+ bl JITStubThunked_op_create_arguments_no_params
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_tear_off_activation(STUB_ARGS_DECLARATION);
+__asm void cti_op_tear_off_activation(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_tear_off_activation
+ str lr, [sp, #32]
+ bl JITStubThunked_op_tear_off_activation
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_tear_off_arguments(STUB_ARGS_DECLARATION);
+__asm void cti_op_tear_off_arguments(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_tear_off_arguments
+ str lr, [sp, #32]
+ bl JITStubThunked_op_tear_off_arguments
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_profile_will_call(STUB_ARGS_DECLARATION);
+__asm void cti_op_profile_will_call(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_profile_will_call
+ str lr, [sp, #32]
+ bl JITStubThunked_op_profile_will_call
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_profile_did_call(STUB_ARGS_DECLARATION);
+__asm void cti_op_profile_did_call(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_profile_did_call
+ str lr, [sp, #32]
+ bl JITStubThunked_op_profile_did_call
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_ret_scopeChain(STUB_ARGS_DECLARATION);
+__asm void cti_op_ret_scopeChain(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_ret_scopeChain
+ str lr, [sp, #32]
+ bl JITStubThunked_op_ret_scopeChain
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_new_array(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_new_array(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_new_array
+ str lr, [sp, #32]
+ bl JITStubThunked_op_new_array
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_resolve(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_resolve(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_resolve
+ str lr, [sp, #32]
+ bl JITStubThunked_op_resolve
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_construct_JSConstruct(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_construct_JSConstruct(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_construct_JSConstruct
+ str lr, [sp, #32]
+ bl JITStubThunked_op_construct_JSConstruct
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_construct_NotJSConstruct
+ str lr, [sp, #32]
+ bl JITStubThunked_op_construct_NotJSConstruct
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_val(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_val(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_val
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_val
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_val_string(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_val_string(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_val_string
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_val_string
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_get_by_val_byte_array(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_get_by_val_byte_array(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_by_val_byte_array
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_by_val_byte_array
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_sub(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_sub(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_sub
+ str lr, [sp, #32]
+ bl JITStubThunked_op_sub
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_put_by_val(STUB_ARGS_DECLARATION);
+__asm void cti_op_put_by_val(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_put_by_val
+ str lr, [sp, #32]
+ bl JITStubThunked_op_put_by_val
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_put_by_val_byte_array(STUB_ARGS_DECLARATION);
+__asm void cti_op_put_by_val_byte_array(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_put_by_val_byte_array
+ str lr, [sp, #32]
+ bl JITStubThunked_op_put_by_val_byte_array
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_lesseq(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_lesseq(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_lesseq
+ str lr, [sp, #32]
+ bl JITStubThunked_op_lesseq
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" int JITStubThunked_op_load_varargs(STUB_ARGS_DECLARATION);
+__asm int cti_op_load_varargs(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_load_varargs
+ str lr, [sp, #32]
+ bl JITStubThunked_op_load_varargs
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_negate(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_negate(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_negate
+ str lr, [sp, #32]
+ bl JITStubThunked_op_negate
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_resolve_base(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_resolve_base(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_resolve_base
+ str lr, [sp, #32]
+ bl JITStubThunked_op_resolve_base
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_resolve_skip(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_resolve_skip(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_resolve_skip
+ str lr, [sp, #32]
+ bl JITStubThunked_op_resolve_skip
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_resolve_global(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_resolve_global(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_resolve_global
+ str lr, [sp, #32]
+ bl JITStubThunked_op_resolve_global
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_div(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_div(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_div
+ str lr, [sp, #32]
+ bl JITStubThunked_op_div
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_pre_dec(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_pre_dec(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_pre_dec
+ str lr, [sp, #32]
+ bl JITStubThunked_op_pre_dec
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" int JITStubThunked_op_jless(STUB_ARGS_DECLARATION);
+__asm int cti_op_jless(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_jless
+ str lr, [sp, #32]
+ bl JITStubThunked_op_jless
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" int JITStubThunked_op_jlesseq(STUB_ARGS_DECLARATION);
+__asm int cti_op_jlesseq(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_jlesseq
+ str lr, [sp, #32]
+ bl JITStubThunked_op_jlesseq
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_not(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_not(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_not
+ str lr, [sp, #32]
+ bl JITStubThunked_op_not
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" int JITStubThunked_op_jtrue(STUB_ARGS_DECLARATION);
+__asm int cti_op_jtrue(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_jtrue
+ str lr, [sp, #32]
+ bl JITStubThunked_op_jtrue
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_post_inc(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_post_inc(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_post_inc
+ str lr, [sp, #32]
+ bl JITStubThunked_op_post_inc
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" int JITStubThunked_op_eq(STUB_ARGS_DECLARATION);
+__asm int cti_op_eq(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_eq
+ str lr, [sp, #32]
+ bl JITStubThunked_op_eq
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" int JITStubThunked_op_eq_strings(STUB_ARGS_DECLARATION);
+__asm int cti_op_eq_strings(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_eq_strings
+ str lr, [sp, #32]
+ bl JITStubThunked_op_eq_strings
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_lshift(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_lshift(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_lshift
+ str lr, [sp, #32]
+ bl JITStubThunked_op_lshift
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_bitand(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_bitand(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_bitand
+ str lr, [sp, #32]
+ bl JITStubThunked_op_bitand
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_rshift(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_rshift(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_rshift
+ str lr, [sp, #32]
+ bl JITStubThunked_op_rshift
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_bitnot(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_bitnot(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_bitnot
+ str lr, [sp, #32]
+ bl JITStubThunked_op_bitnot
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_resolve_with_base(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_resolve_with_base(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_resolve_with_base
+ str lr, [sp, #32]
+ bl JITStubThunked_op_resolve_with_base
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_new_func_exp(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_new_func_exp(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_new_func_exp
+ str lr, [sp, #32]
+ bl JITStubThunked_op_new_func_exp
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_mod(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_mod(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_mod
+ str lr, [sp, #32]
+ bl JITStubThunked_op_mod
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_less(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_less(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_less
+ str lr, [sp, #32]
+ bl JITStubThunked_op_less
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_post_dec(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_post_dec(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_post_dec
+ str lr, [sp, #32]
+ bl JITStubThunked_op_post_dec
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_urshift(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_urshift(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_urshift
+ str lr, [sp, #32]
+ bl JITStubThunked_op_urshift
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_bitxor(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_bitxor(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_bitxor
+ str lr, [sp, #32]
+ bl JITStubThunked_op_bitxor
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_new_regexp(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_new_regexp(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_new_regexp
+ str lr, [sp, #32]
+ bl JITStubThunked_op_new_regexp
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_bitor(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_bitor(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_bitor
+ str lr, [sp, #32]
+ bl JITStubThunked_op_bitor
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_call_eval(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_call_eval(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_call_eval
+ str lr, [sp, #32]
+ bl JITStubThunked_op_call_eval
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_throw(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_throw(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_throw
+ str lr, [sp, #32]
+ bl JITStubThunked_op_throw
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSPropertyNameIterator* JITStubThunked_op_get_pnames(STUB_ARGS_DECLARATION);
+__asm JSPropertyNameIterator* cti_op_get_pnames(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_get_pnames
+ str lr, [sp, #32]
+ bl JITStubThunked_op_get_pnames
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" int JITStubThunked_has_property(STUB_ARGS_DECLARATION);
+__asm int cti_has_property(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_has_property
+ str lr, [sp, #32]
+ bl JITStubThunked_has_property
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_push_scope(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_push_scope(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_push_scope
+ str lr, [sp, #32]
+ bl JITStubThunked_op_push_scope
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_pop_scope(STUB_ARGS_DECLARATION);
+__asm void cti_op_pop_scope(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_pop_scope
+ str lr, [sp, #32]
+ bl JITStubThunked_op_pop_scope
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_typeof(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_typeof(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_typeof
+ str lr, [sp, #32]
+ bl JITStubThunked_op_typeof
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_is_undefined(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_is_undefined(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_is_undefined
+ str lr, [sp, #32]
+ bl JITStubThunked_op_is_undefined
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_is_boolean(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_is_boolean(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_is_boolean
+ str lr, [sp, #32]
+ bl JITStubThunked_op_is_boolean
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_is_number(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_is_number(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_is_number
+ str lr, [sp, #32]
+ bl JITStubThunked_op_is_number
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_is_string(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_is_string(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_is_string
+ str lr, [sp, #32]
+ bl JITStubThunked_op_is_string
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_is_object(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_is_object(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_is_object
+ str lr, [sp, #32]
+ bl JITStubThunked_op_is_object
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_is_function(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_is_function(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_is_function
+ str lr, [sp, #32]
+ bl JITStubThunked_op_is_function
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_stricteq(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_stricteq(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_stricteq
+ str lr, [sp, #32]
+ bl JITStubThunked_op_stricteq
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_to_primitive(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_to_primitive(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_to_primitive
+ str lr, [sp, #32]
+ bl JITStubThunked_op_to_primitive
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_strcat(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_strcat(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_strcat
+ str lr, [sp, #32]
+ bl JITStubThunked_op_strcat
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_nstricteq(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_nstricteq(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_nstricteq
+ str lr, [sp, #32]
+ bl JITStubThunked_op_nstricteq
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_to_jsnumber(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_to_jsnumber(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_to_jsnumber
+ str lr, [sp, #32]
+ bl JITStubThunked_op_to_jsnumber
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_in(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_in(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_in
+ str lr, [sp, #32]
+ bl JITStubThunked_op_in
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_push_new_scope(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_push_new_scope(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_push_new_scope
+ str lr, [sp, #32]
+ bl JITStubThunked_op_push_new_scope
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_jmp_scopes(STUB_ARGS_DECLARATION);
+__asm void cti_op_jmp_scopes(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_jmp_scopes
+ str lr, [sp, #32]
+ bl JITStubThunked_op_jmp_scopes
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_put_by_index(STUB_ARGS_DECLARATION);
+__asm void cti_op_put_by_index(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_put_by_index
+ str lr, [sp, #32]
+ bl JITStubThunked_op_put_by_index
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void* JITStubThunked_op_switch_imm(STUB_ARGS_DECLARATION);
+__asm void* cti_op_switch_imm(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_switch_imm
+ str lr, [sp, #32]
+ bl JITStubThunked_op_switch_imm
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void* JITStubThunked_op_switch_char(STUB_ARGS_DECLARATION);
+__asm void* cti_op_switch_char(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_switch_char
+ str lr, [sp, #32]
+ bl JITStubThunked_op_switch_char
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void* JITStubThunked_op_switch_string(STUB_ARGS_DECLARATION);
+__asm void* cti_op_switch_string(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_switch_string
+ str lr, [sp, #32]
+ bl JITStubThunked_op_switch_string
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_op_del_by_val(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_op_del_by_val(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_del_by_val
+ str lr, [sp, #32]
+ bl JITStubThunked_op_del_by_val
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_put_getter(STUB_ARGS_DECLARATION);
+__asm void cti_op_put_getter(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_put_getter
+ str lr, [sp, #32]
+ bl JITStubThunked_op_put_getter
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_put_setter(STUB_ARGS_DECLARATION);
+__asm void cti_op_put_setter(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_put_setter
+ str lr, [sp, #32]
+ bl JITStubThunked_op_put_setter
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" JSObject* JITStubThunked_op_new_error(STUB_ARGS_DECLARATION);
+__asm JSObject* cti_op_new_error(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_new_error
+ str lr, [sp, #32]
+ bl JITStubThunked_op_new_error
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_debug(STUB_ARGS_DECLARATION);
+__asm void cti_op_debug(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_debug
+ str lr, [sp, #32]
+ bl JITStubThunked_op_debug
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_debug_catch(STUB_ARGS_DECLARATION);
+__asm void cti_op_debug_catch(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_debug_catch
+ str lr, [sp, #32]
+ bl JITStubThunked_op_debug_catch
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" void JITStubThunked_op_debug_return(STUB_ARGS_DECLARATION);
+__asm void cti_op_debug_return(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_op_debug_return
+ str lr, [sp, #32]
+ bl JITStubThunked_op_debug_return
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_vm_throw(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_vm_throw(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_vm_throw
+ str lr, [sp, #32]
+ bl JITStubThunked_vm_throw
+ ldr lr, [sp, #32]
+ bx lr
+}
+
+extern "C" EncodedJSValue JITStubThunked_to_object(STUB_ARGS_DECLARATION);
+__asm EncodedJSValue cti_to_object(STUB_ARGS_DECLARATION)
+{
+ ARM
+ IMPORT JITStubThunked_to_object
+ str lr, [sp, #32]
+ bl JITStubThunked_to_object
+ ldr lr, [sp, #32]
+ bx lr
+}
+
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.cpp
index f1fa708..6ac1b9b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.cpp
@@ -208,7 +208,7 @@
/* Copy the first part of user declarations. */
-#line 3 "../parser/Grammar.y"
+#line 3 "parser/Grammar.y"
/*
@@ -236,6 +236,7 @@
#include "JSObject.h"
#include "JSString.h"
+#include "Lexer.h"
#include "NodeConstructors.h"
#include "NodeInfo.h"
#include <stdlib.h>
@@ -251,13 +252,12 @@
// Default values for bison.
#define YYDEBUG 0 // Set to 1 to debug a parse error.
#define jscyydebug 0 // Set to 1 to debug a parse error.
-#if !PLATFORM(DARWIN)
+#if !OS(DARWIN)
// Avoid triggering warnings in older bison by not setting this on the Darwin platform.
// FIXME: Is this still needed?
#define YYERROR_VERBOSE
#endif
-int jscyylex(void* lvalp, void* llocp, void* globalPtr);
int jscyyerror(const char*);
static inline bool allowAutomaticSemicolon(JSC::Lexer&, int);
@@ -372,7 +372,7 @@ static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserAr
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 146 "../parser/Grammar.y"
+#line 146 "parser/Grammar.y"
{
int intValue;
double doubleValue;
@@ -405,7 +405,7 @@ typedef union YYSTYPE
Operator op;
}
/* Line 187 of yacc.c. */
-#line 409 "JavaScriptCore/tmp/../generated/Grammar.tab.c"
+#line 409 "generated/Grammar.tab.c"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -427,12 +427,12 @@ typedef struct YYLTYPE
/* Copy the second part of user declarations. */
-#line 178 "../parser/Grammar.y"
+#line 178 "parser/Grammar.y"
template <typename T> inline void setStatementLocation(StatementNode* statement, const T& start, const T& end)
{
- statement->setLoc(start.first_line, end.last_line, start.first_column);
+ statement->setLoc(start.first_line, end.last_line);
}
static inline void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end)
@@ -443,7 +443,7 @@ static inline void setExceptionLocation(ThrowableExpressionData* node, unsigned
/* Line 216 of yacc.c. */
-#line 447 "JavaScriptCore/tmp/../generated/Grammar.tab.c"
+#line 447 "generated/Grammar.tab.c"
#ifdef short
# undef short
@@ -3010,32 +3010,32 @@ yyreduce:
switch (yyn)
{
case 2:
-#line 293 "../parser/Grammar.y"
+#line 293 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NullNode(GLOBAL_DATA), 0, 1); ;}
break;
case 3:
-#line 294 "../parser/Grammar.y"
+#line 294 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BooleanNode(GLOBAL_DATA, true), 0, 1); ;}
break;
case 4:
-#line 295 "../parser/Grammar.y"
+#line 295 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BooleanNode(GLOBAL_DATA, false), 0, 1); ;}
break;
case 5:
-#line 296 "../parser/Grammar.y"
+#line 296 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeNumberNode(GLOBAL_DATA, (yyvsp[(1) - (1)].doubleValue)), 0, 1); ;}
break;
case 6:
-#line 297 "../parser/Grammar.y"
+#line 297 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StringNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident)), 0, 1); ;}
break;
case 7:
-#line 298 "../parser/Grammar.y"
+#line 298 "parser/Grammar.y"
{
Lexer& l = *GLOBAL_DATA->lexer;
const Identifier* pattern;
@@ -3050,7 +3050,7 @@ yyreduce:
break;
case 8:
-#line 309 "../parser/Grammar.y"
+#line 309 "parser/Grammar.y"
{
Lexer& l = *GLOBAL_DATA->lexer;
const Identifier* pattern;
@@ -3065,27 +3065,27 @@ yyreduce:
break;
case 9:
-#line 323 "../parser/Grammar.y"
+#line 323 "parser/Grammar.y"
{ (yyval.propertyNode) = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 10:
-#line 324 "../parser/Grammar.y"
+#line 324 "parser/Grammar.y"
{ (yyval.propertyNode) = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 11:
-#line 325 "../parser/Grammar.y"
+#line 325 "parser/Grammar.y"
{ (yyval.propertyNode) = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, (yyvsp[(1) - (3)].doubleValue), (yyvsp[(3) - (3)].expressionNode).m_node, PropertyNode::Constant), (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 12:
-#line 326 "../parser/Grammar.y"
+#line 326 "parser/Grammar.y"
{ (yyval.propertyNode) = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (7)].ident), *(yyvsp[(2) - (7)].ident), 0, (yyvsp[(6) - (7)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), ClosureFeature, 0); setStatementLocation((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); if (!(yyval.propertyNode).m_node) YYABORT; ;}
break;
case 13:
-#line 328 "../parser/Grammar.y"
+#line 328 "parser/Grammar.y"
{
(yyval.propertyNode) = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(GLOBAL_DATA, *(yyvsp[(1) - (8)].ident), *(yyvsp[(2) - (8)].ident), (yyvsp[(4) - (8)].parameterList).m_node.head, (yyvsp[(7) - (8)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line)), (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0);
if ((yyvsp[(4) - (8)].parameterList).m_features & ArgumentsFeature)
@@ -3097,7 +3097,7 @@ yyreduce:
break;
case 14:
-#line 339 "../parser/Grammar.y"
+#line 339 "parser/Grammar.y"
{ (yyval.propertyList).m_node.head = new (GLOBAL_DATA) PropertyListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].propertyNode).m_node);
(yyval.propertyList).m_node.tail = (yyval.propertyList).m_node.head;
(yyval.propertyList).m_features = (yyvsp[(1) - (1)].propertyNode).m_features;
@@ -3105,7 +3105,7 @@ yyreduce:
break;
case 15:
-#line 343 "../parser/Grammar.y"
+#line 343 "parser/Grammar.y"
{ (yyval.propertyList).m_node.head = (yyvsp[(1) - (3)].propertyList).m_node.head;
(yyval.propertyList).m_node.tail = new (GLOBAL_DATA) PropertyListNode(GLOBAL_DATA, (yyvsp[(3) - (3)].propertyNode).m_node, (yyvsp[(1) - (3)].propertyList).m_node.tail);
(yyval.propertyList).m_features = (yyvsp[(1) - (3)].propertyList).m_features | (yyvsp[(3) - (3)].propertyNode).m_features;
@@ -3113,52 +3113,52 @@ yyreduce:
break;
case 17:
-#line 351 "../parser/Grammar.y"
+#line 351 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA), 0, 0); ;}
break;
case 18:
-#line 352 "../parser/Grammar.y"
+#line 352 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA, (yyvsp[(2) - (3)].propertyList).m_node.head), (yyvsp[(2) - (3)].propertyList).m_features, (yyvsp[(2) - (3)].propertyList).m_numConstants); ;}
break;
case 19:
-#line 354 "../parser/Grammar.y"
+#line 354 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA, (yyvsp[(2) - (4)].propertyList).m_node.head), (yyvsp[(2) - (4)].propertyList).m_features, (yyvsp[(2) - (4)].propertyList).m_numConstants); ;}
break;
case 20:
-#line 358 "../parser/Grammar.y"
+#line 358 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ThisNode(GLOBAL_DATA), ThisFeature, 0); ;}
break;
case 23:
-#line 361 "../parser/Grammar.y"
+#line 361 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident), (yylsp[(1) - (1)]).first_column), (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); ;}
break;
case 24:
-#line 362 "../parser/Grammar.y"
+#line 362 "parser/Grammar.y"
{ (yyval.expressionNode) = (yyvsp[(2) - (3)].expressionNode); ;}
break;
case 25:
-#line 366 "../parser/Grammar.y"
+#line 366 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, (yyvsp[(2) - (3)].intValue)), 0, (yyvsp[(2) - (3)].intValue) ? 1 : 0); ;}
break;
case 26:
-#line 367 "../parser/Grammar.y"
+#line 367 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, (yyvsp[(2) - (3)].elementList).m_node.head), (yyvsp[(2) - (3)].elementList).m_features, (yyvsp[(2) - (3)].elementList).m_numConstants); ;}
break;
case 27:
-#line 368 "../parser/Grammar.y"
+#line 368 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, (yyvsp[(4) - (5)].intValue), (yyvsp[(2) - (5)].elementList).m_node.head), (yyvsp[(2) - (5)].elementList).m_features, (yyvsp[(4) - (5)].intValue) ? (yyvsp[(2) - (5)].elementList).m_numConstants + 1 : (yyvsp[(2) - (5)].elementList).m_numConstants); ;}
break;
case 28:
-#line 372 "../parser/Grammar.y"
+#line 372 "parser/Grammar.y"
{ (yyval.elementList).m_node.head = new (GLOBAL_DATA) ElementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].intValue), (yyvsp[(2) - (2)].expressionNode).m_node);
(yyval.elementList).m_node.tail = (yyval.elementList).m_node.head;
(yyval.elementList).m_features = (yyvsp[(2) - (2)].expressionNode).m_features;
@@ -3166,7 +3166,7 @@ yyreduce:
break;
case 29:
-#line 377 "../parser/Grammar.y"
+#line 377 "parser/Grammar.y"
{ (yyval.elementList).m_node.head = (yyvsp[(1) - (4)].elementList).m_node.head;
(yyval.elementList).m_node.tail = new (GLOBAL_DATA) ElementNode(GLOBAL_DATA, (yyvsp[(1) - (4)].elementList).m_node.tail, (yyvsp[(3) - (4)].intValue), (yyvsp[(4) - (4)].expressionNode).m_node);
(yyval.elementList).m_features = (yyvsp[(1) - (4)].elementList).m_features | (yyvsp[(4) - (4)].expressionNode).m_features;
@@ -3174,27 +3174,27 @@ yyreduce:
break;
case 30:
-#line 384 "../parser/Grammar.y"
+#line 384 "parser/Grammar.y"
{ (yyval.intValue) = 0; ;}
break;
case 32:
-#line 389 "../parser/Grammar.y"
+#line 389 "parser/Grammar.y"
{ (yyval.intValue) = 1; ;}
break;
case 33:
-#line 390 "../parser/Grammar.y"
+#line 390 "parser/Grammar.y"
{ (yyval.intValue) = (yyvsp[(1) - (2)].intValue) + 1; ;}
break;
case 35:
-#line 395 "../parser/Grammar.y"
+#line 395 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>((yyvsp[(1) - (1)].funcExprNode).m_node, (yyvsp[(1) - (1)].funcExprNode).m_features, (yyvsp[(1) - (1)].funcExprNode).m_numConstants); ;}
break;
case 36:
-#line 396 "../parser/Grammar.y"
+#line 396 "parser/Grammar.y"
{ BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (4)].expressionNode).m_features | (yyvsp[(3) - (4)].expressionNode).m_features, (yyvsp[(1) - (4)].expressionNode).m_numConstants + (yyvsp[(3) - (4)].expressionNode).m_numConstants);
@@ -3202,7 +3202,7 @@ yyreduce:
break;
case 37:
-#line 400 "../parser/Grammar.y"
+#line 400 "parser/Grammar.y"
{ DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident));
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants);
@@ -3210,7 +3210,7 @@ yyreduce:
break;
case 38:
-#line 404 "../parser/Grammar.y"
+#line 404 "parser/Grammar.y"
{ NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].argumentsNode).m_node);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(2) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].argumentsNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].argumentsNode).m_numConstants);
@@ -3218,7 +3218,7 @@ yyreduce:
break;
case 40:
-#line 412 "../parser/Grammar.y"
+#line 412 "parser/Grammar.y"
{ BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (4)].expressionNode).m_features | (yyvsp[(3) - (4)].expressionNode).m_features, (yyvsp[(1) - (4)].expressionNode).m_numConstants + (yyvsp[(3) - (4)].expressionNode).m_numConstants);
@@ -3226,7 +3226,7 @@ yyreduce:
break;
case 41:
-#line 416 "../parser/Grammar.y"
+#line 416 "parser/Grammar.y"
{ DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident));
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants);
@@ -3234,7 +3234,7 @@ yyreduce:
break;
case 42:
-#line 420 "../parser/Grammar.y"
+#line 420 "parser/Grammar.y"
{ NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].argumentsNode).m_node);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(2) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].argumentsNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].argumentsNode).m_numConstants);
@@ -3242,7 +3242,7 @@ yyreduce:
break;
case 44:
-#line 428 "../parser/Grammar.y"
+#line 428 "parser/Grammar.y"
{ NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node);
setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants);
@@ -3250,7 +3250,7 @@ yyreduce:
break;
case 46:
-#line 436 "../parser/Grammar.y"
+#line 436 "parser/Grammar.y"
{ NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node);
setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants);
@@ -3258,17 +3258,17 @@ yyreduce:
break;
case 47:
-#line 443 "../parser/Grammar.y"
+#line 443 "parser/Grammar.y"
{ (yyval.expressionNode) = makeFunctionCallNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;}
break;
case 48:
-#line 444 "../parser/Grammar.y"
+#line 444 "parser/Grammar.y"
{ (yyval.expressionNode) = makeFunctionCallNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;}
break;
case 49:
-#line 445 "../parser/Grammar.y"
+#line 445 "parser/Grammar.y"
{ BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (4)].expressionNode).m_features | (yyvsp[(3) - (4)].expressionNode).m_features, (yyvsp[(1) - (4)].expressionNode).m_numConstants + (yyvsp[(3) - (4)].expressionNode).m_numConstants);
@@ -3276,24 +3276,24 @@ yyreduce:
break;
case 50:
-#line 449 "../parser/Grammar.y"
+#line 449 "parser/Grammar.y"
{ DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident));
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants); ;}
break;
case 51:
-#line 455 "../parser/Grammar.y"
+#line 455 "parser/Grammar.y"
{ (yyval.expressionNode) = makeFunctionCallNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;}
break;
case 52:
-#line 456 "../parser/Grammar.y"
+#line 456 "parser/Grammar.y"
{ (yyval.expressionNode) = makeFunctionCallNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode), (yyvsp[(2) - (2)].argumentsNode), (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column); ;}
break;
case 53:
-#line 457 "../parser/Grammar.y"
+#line 457 "parser/Grammar.y"
{ BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_node, (yyvsp[(3) - (4)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (4)]).first_column, (yylsp[(1) - (4)]).last_column, (yylsp[(4) - (4)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (4)].expressionNode).m_features | (yyvsp[(3) - (4)].expressionNode).m_features, (yyvsp[(1) - (4)].expressionNode).m_numConstants + (yyvsp[(3) - (4)].expressionNode).m_numConstants);
@@ -3301,7 +3301,7 @@ yyreduce:
break;
case 54:
-#line 461 "../parser/Grammar.y"
+#line 461 "parser/Grammar.y"
{ DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, *(yyvsp[(3) - (3)].ident));
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(1) - (3)]).last_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants);
@@ -3309,17 +3309,17 @@ yyreduce:
break;
case 55:
-#line 468 "../parser/Grammar.y"
+#line 468 "parser/Grammar.y"
{ (yyval.argumentsNode) = createNodeInfo<ArgumentsNode*>(new (GLOBAL_DATA) ArgumentsNode(GLOBAL_DATA), 0, 0); ;}
break;
case 56:
-#line 469 "../parser/Grammar.y"
+#line 469 "parser/Grammar.y"
{ (yyval.argumentsNode) = createNodeInfo<ArgumentsNode*>(new (GLOBAL_DATA) ArgumentsNode(GLOBAL_DATA, (yyvsp[(2) - (3)].argumentList).m_node.head), (yyvsp[(2) - (3)].argumentList).m_features, (yyvsp[(2) - (3)].argumentList).m_numConstants); ;}
break;
case 57:
-#line 473 "../parser/Grammar.y"
+#line 473 "parser/Grammar.y"
{ (yyval.argumentList).m_node.head = new (GLOBAL_DATA) ArgumentListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].expressionNode).m_node);
(yyval.argumentList).m_node.tail = (yyval.argumentList).m_node.head;
(yyval.argumentList).m_features = (yyvsp[(1) - (1)].expressionNode).m_features;
@@ -3327,7 +3327,7 @@ yyreduce:
break;
case 58:
-#line 477 "../parser/Grammar.y"
+#line 477 "parser/Grammar.y"
{ (yyval.argumentList).m_node.head = (yyvsp[(1) - (3)].argumentList).m_node.head;
(yyval.argumentList).m_node.tail = new (GLOBAL_DATA) ArgumentListNode(GLOBAL_DATA, (yyvsp[(1) - (3)].argumentList).m_node.tail, (yyvsp[(3) - (3)].expressionNode).m_node);
(yyval.argumentList).m_features = (yyvsp[(1) - (3)].argumentList).m_features | (yyvsp[(3) - (3)].expressionNode).m_features;
@@ -3335,528 +3335,528 @@ yyreduce:
break;
case 64:
-#line 495 "../parser/Grammar.y"
+#line 495 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;}
break;
case 65:
-#line 496 "../parser/Grammar.y"
+#line 496 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;}
break;
case 67:
-#line 501 "../parser/Grammar.y"
+#line 501 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;}
break;
case 68:
-#line 502 "../parser/Grammar.y"
+#line 502 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePostfixNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(1) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (2)].expressionNode).m_numConstants); ;}
break;
case 69:
-#line 506 "../parser/Grammar.y"
+#line 506 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeDeleteNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).last_column, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 70:
-#line 507 "../parser/Grammar.y"
+#line 507 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) VoidNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants + 1); ;}
break;
case 71:
-#line 508 "../parser/Grammar.y"
+#line 508 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeTypeOfNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 72:
-#line 509 "../parser/Grammar.y"
+#line 509 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 73:
-#line 510 "../parser/Grammar.y"
+#line 510 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpPlusPlus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 74:
-#line 511 "../parser/Grammar.y"
+#line 511 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 75:
-#line 512 "../parser/Grammar.y"
+#line 512 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node, OpMinusMinus, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column), (yyvsp[(2) - (2)].expressionNode).m_features | AssignFeature, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 76:
-#line 513 "../parser/Grammar.y"
+#line 513 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 77:
-#line 514 "../parser/Grammar.y"
+#line 514 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeNegateNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 78:
-#line 515 "../parser/Grammar.y"
+#line 515 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeBitwiseNotNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 79:
-#line 516 "../parser/Grammar.y"
+#line 516 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalNotNode(GLOBAL_DATA, (yyvsp[(2) - (2)].expressionNode).m_node), (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 85:
-#line 530 "../parser/Grammar.y"
+#line 530 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeMultNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 86:
-#line 531 "../parser/Grammar.y"
+#line 531 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeDivNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 87:
-#line 532 "../parser/Grammar.y"
+#line 532 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ModNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 89:
-#line 538 "../parser/Grammar.y"
+#line 538 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeMultNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 90:
-#line 540 "../parser/Grammar.y"
+#line 540 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeDivNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 91:
-#line 542 "../parser/Grammar.y"
+#line 542 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ModNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 93:
-#line 547 "../parser/Grammar.y"
+#line 547 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeAddNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 94:
-#line 548 "../parser/Grammar.y"
+#line 548 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeSubNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 96:
-#line 554 "../parser/Grammar.y"
+#line 554 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeAddNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 97:
-#line 556 "../parser/Grammar.y"
+#line 556 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeSubNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 99:
-#line 561 "../parser/Grammar.y"
+#line 561 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeLeftShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 100:
-#line 562 "../parser/Grammar.y"
+#line 562 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 101:
-#line 563 "../parser/Grammar.y"
+#line 563 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnsignedRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 103:
-#line 568 "../parser/Grammar.y"
+#line 568 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeLeftShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 104:
-#line 569 "../parser/Grammar.y"
+#line 569 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 105:
-#line 570 "../parser/Grammar.y"
+#line 570 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnsignedRightShiftNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 107:
-#line 575 "../parser/Grammar.y"
+#line 575 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 108:
-#line 576 "../parser/Grammar.y"
+#line 576 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 109:
-#line 577 "../parser/Grammar.y"
+#line 577 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 110:
-#line 578 "../parser/Grammar.y"
+#line 578 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 111:
-#line 579 "../parser/Grammar.y"
+#line 579 "parser/Grammar.y"
{ InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 112:
-#line 582 "../parser/Grammar.y"
+#line 582 "parser/Grammar.y"
{ InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 114:
-#line 589 "../parser/Grammar.y"
+#line 589 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 115:
-#line 590 "../parser/Grammar.y"
+#line 590 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 116:
-#line 591 "../parser/Grammar.y"
+#line 591 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 117:
-#line 592 "../parser/Grammar.y"
+#line 592 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 118:
-#line 594 "../parser/Grammar.y"
+#line 594 "parser/Grammar.y"
{ InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 120:
-#line 601 "../parser/Grammar.y"
+#line 601 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 121:
-#line 602 "../parser/Grammar.y"
+#line 602 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 122:
-#line 603 "../parser/Grammar.y"
+#line 603 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 123:
-#line 604 "../parser/Grammar.y"
+#line 604 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 124:
-#line 606 "../parser/Grammar.y"
+#line 606 "parser/Grammar.y"
{ InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 125:
-#line 610 "../parser/Grammar.y"
+#line 610 "parser/Grammar.y"
{ InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(3) - (3)]).first_column, (yylsp[(3) - (3)]).last_column);
(yyval.expressionNode) = createNodeInfo<ExpressionNode*>(node, (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 127:
-#line 617 "../parser/Grammar.y"
+#line 617 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 128:
-#line 618 "../parser/Grammar.y"
+#line 618 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 129:
-#line 619 "../parser/Grammar.y"
+#line 619 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 130:
-#line 620 "../parser/Grammar.y"
+#line 620 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 132:
-#line 626 "../parser/Grammar.y"
+#line 626 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 133:
-#line 628 "../parser/Grammar.y"
+#line 628 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 134:
-#line 630 "../parser/Grammar.y"
+#line 630 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 135:
-#line 632 "../parser/Grammar.y"
+#line 632 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 137:
-#line 638 "../parser/Grammar.y"
+#line 638 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 138:
-#line 639 "../parser/Grammar.y"
+#line 639 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 139:
-#line 641 "../parser/Grammar.y"
+#line 641 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 140:
-#line 643 "../parser/Grammar.y"
+#line 643 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 142:
-#line 648 "../parser/Grammar.y"
+#line 648 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 144:
-#line 654 "../parser/Grammar.y"
+#line 654 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 146:
-#line 659 "../parser/Grammar.y"
+#line 659 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 148:
-#line 664 "../parser/Grammar.y"
+#line 664 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 150:
-#line 670 "../parser/Grammar.y"
+#line 670 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 152:
-#line 676 "../parser/Grammar.y"
+#line 676 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 154:
-#line 681 "../parser/Grammar.y"
+#line 681 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 156:
-#line 687 "../parser/Grammar.y"
+#line 687 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 158:
-#line 693 "../parser/Grammar.y"
+#line 693 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 160:
-#line 698 "../parser/Grammar.y"
+#line 698 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 162:
-#line 704 "../parser/Grammar.y"
+#line 704 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 164:
-#line 710 "../parser/Grammar.y"
+#line 710 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalAnd), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 166:
-#line 715 "../parser/Grammar.y"
+#line 715 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 168:
-#line 721 "../parser/Grammar.y"
+#line 721 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 170:
-#line 726 "../parser/Grammar.y"
+#line 726 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node, OpLogicalOr), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 172:
-#line 732 "../parser/Grammar.y"
+#line 732 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;}
break;
case 174:
-#line 738 "../parser/Grammar.y"
+#line 738 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;}
break;
case 176:
-#line 744 "../parser/Grammar.y"
+#line 744 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, (yyvsp[(1) - (5)].expressionNode).m_node, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].expressionNode).m_node), (yyvsp[(1) - (5)].expressionNode).m_features | (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].expressionNode).m_features, (yyvsp[(1) - (5)].expressionNode).m_numConstants + (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].expressionNode).m_numConstants); ;}
break;
case 178:
-#line 750 "../parser/Grammar.y"
+#line 750 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature,
(yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants);
;}
break;
case 180:
-#line 758 "../parser/Grammar.y"
+#line 758 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature,
(yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants);
;}
break;
case 182:
-#line 766 "../parser/Grammar.y"
+#line 766 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(makeAssignNode(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].expressionNode).m_node, (yyvsp[(1) - (3)].expressionNode).m_features & AssignFeature, (yyvsp[(3) - (3)].expressionNode).m_features & AssignFeature,
(yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).first_column + 1, (yylsp[(3) - (3)]).last_column), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features | AssignFeature, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants);
;}
break;
case 183:
-#line 772 "../parser/Grammar.y"
+#line 772 "parser/Grammar.y"
{ (yyval.op) = OpEqual; ;}
break;
case 184:
-#line 773 "../parser/Grammar.y"
+#line 773 "parser/Grammar.y"
{ (yyval.op) = OpPlusEq; ;}
break;
case 185:
-#line 774 "../parser/Grammar.y"
+#line 774 "parser/Grammar.y"
{ (yyval.op) = OpMinusEq; ;}
break;
case 186:
-#line 775 "../parser/Grammar.y"
+#line 775 "parser/Grammar.y"
{ (yyval.op) = OpMultEq; ;}
break;
case 187:
-#line 776 "../parser/Grammar.y"
+#line 776 "parser/Grammar.y"
{ (yyval.op) = OpDivEq; ;}
break;
case 188:
-#line 777 "../parser/Grammar.y"
+#line 777 "parser/Grammar.y"
{ (yyval.op) = OpLShift; ;}
break;
case 189:
-#line 778 "../parser/Grammar.y"
+#line 778 "parser/Grammar.y"
{ (yyval.op) = OpRShift; ;}
break;
case 190:
-#line 779 "../parser/Grammar.y"
+#line 779 "parser/Grammar.y"
{ (yyval.op) = OpURShift; ;}
break;
case 191:
-#line 780 "../parser/Grammar.y"
+#line 780 "parser/Grammar.y"
{ (yyval.op) = OpAndEq; ;}
break;
case 192:
-#line 781 "../parser/Grammar.y"
+#line 781 "parser/Grammar.y"
{ (yyval.op) = OpXOrEq; ;}
break;
case 193:
-#line 782 "../parser/Grammar.y"
+#line 782 "parser/Grammar.y"
{ (yyval.op) = OpOrEq; ;}
break;
case 194:
-#line 783 "../parser/Grammar.y"
+#line 783 "parser/Grammar.y"
{ (yyval.op) = OpModEq; ;}
break;
case 196:
-#line 788 "../parser/Grammar.y"
+#line 788 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 198:
-#line 793 "../parser/Grammar.y"
+#line 793 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 200:
-#line 798 "../parser/Grammar.y"
+#line 798 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, (yyvsp[(1) - (3)].expressionNode).m_node, (yyvsp[(3) - (3)].expressionNode).m_node), (yyvsp[(1) - (3)].expressionNode).m_features | (yyvsp[(3) - (3)].expressionNode).m_features, (yyvsp[(1) - (3)].expressionNode).m_numConstants + (yyvsp[(3) - (3)].expressionNode).m_numConstants); ;}
break;
case 218:
-#line 822 "../parser/Grammar.y"
+#line 822 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;}
break;
case 219:
-#line 824 "../parser/Grammar.y"
+#line 824 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, (yyvsp[(2) - (3)].sourceElements).m_node), (yyvsp[(2) - (3)].sourceElements).m_varDeclarations, (yyvsp[(2) - (3)].sourceElements).m_funcDeclarations, (yyvsp[(2) - (3)].sourceElements).m_features, (yyvsp[(2) - (3)].sourceElements).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;}
break;
case 220:
-#line 829 "../parser/Grammar.y"
+#line 829 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].varDeclList).m_node), (yyvsp[(2) - (3)].varDeclList).m_varDeclarations, (yyvsp[(2) - (3)].varDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].varDeclList).m_features, (yyvsp[(2) - (3)].varDeclList).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;}
break;
case 221:
-#line 831 "../parser/Grammar.y"
+#line 831 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(makeVarStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].varDeclList).m_node), (yyvsp[(2) - (3)].varDeclList).m_varDeclarations, (yyvsp[(2) - (3)].varDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].varDeclList).m_features, (yyvsp[(2) - (3)].varDeclList).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)]));
AUTO_SEMICOLON; ;}
break;
case 222:
-#line 837 "../parser/Grammar.y"
+#line 837 "parser/Grammar.y"
{ (yyval.varDeclList).m_node = 0;
(yyval.varDeclList).m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>;
appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(1) - (1)].ident), 0);
@@ -3867,7 +3867,7 @@ yyreduce:
break;
case 223:
-#line 844 "../parser/Grammar.y"
+#line 844 "parser/Grammar.y"
{ AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node, (yyvsp[(2) - (2)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column);
(yyval.varDeclList).m_node = node;
@@ -3880,7 +3880,7 @@ yyreduce:
break;
case 224:
-#line 854 "../parser/Grammar.y"
+#line 854 "parser/Grammar.y"
{ (yyval.varDeclList).m_node = (yyvsp[(1) - (3)].varDeclList).m_node;
(yyval.varDeclList).m_varDeclarations = (yyvsp[(1) - (3)].varDeclList).m_varDeclarations;
appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(3) - (3)].ident), 0);
@@ -3891,7 +3891,7 @@ yyreduce:
break;
case 225:
-#line 862 "../parser/Grammar.y"
+#line 862 "parser/Grammar.y"
{ AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *(yyvsp[(3) - (4)].ident), (yyvsp[(4) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column);
(yyval.varDeclList).m_node = combineCommaNodes(GLOBAL_DATA, (yyvsp[(1) - (4)].varDeclList).m_node, node);
@@ -3904,7 +3904,7 @@ yyreduce:
break;
case 226:
-#line 874 "../parser/Grammar.y"
+#line 874 "parser/Grammar.y"
{ (yyval.varDeclList).m_node = 0;
(yyval.varDeclList).m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>;
appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(1) - (1)].ident), 0);
@@ -3915,7 +3915,7 @@ yyreduce:
break;
case 227:
-#line 881 "../parser/Grammar.y"
+#line 881 "parser/Grammar.y"
{ AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node, (yyvsp[(2) - (2)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(2) - (2)]).first_column + 1, (yylsp[(2) - (2)]).last_column);
(yyval.varDeclList).m_node = node;
@@ -3928,7 +3928,7 @@ yyreduce:
break;
case 228:
-#line 891 "../parser/Grammar.y"
+#line 891 "parser/Grammar.y"
{ (yyval.varDeclList).m_node = (yyvsp[(1) - (3)].varDeclList).m_node;
(yyval.varDeclList).m_varDeclarations = (yyvsp[(1) - (3)].varDeclList).m_varDeclarations;
appendToVarDeclarationList(GLOBAL_DATA, (yyval.varDeclList).m_varDeclarations, *(yyvsp[(3) - (3)].ident), 0);
@@ -3939,7 +3939,7 @@ yyreduce:
break;
case 229:
-#line 899 "../parser/Grammar.y"
+#line 899 "parser/Grammar.y"
{ AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *(yyvsp[(3) - (4)].ident), (yyvsp[(4) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].expressionNode).m_features & AssignFeature);
setExceptionLocation(node, (yylsp[(3) - (4)]).first_column, (yylsp[(4) - (4)]).first_column + 1, (yylsp[(4) - (4)]).last_column);
(yyval.varDeclList).m_node = combineCommaNodes(GLOBAL_DATA, (yyvsp[(1) - (4)].varDeclList).m_node, node);
@@ -3952,19 +3952,19 @@ yyreduce:
break;
case 230:
-#line 911 "../parser/Grammar.y"
+#line 911 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].constDeclList).m_node.head), (yyvsp[(2) - (3)].constDeclList).m_varDeclarations, (yyvsp[(2) - (3)].constDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].constDeclList).m_features, (yyvsp[(2) - (3)].constDeclList).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;}
break;
case 231:
-#line 914 "../parser/Grammar.y"
+#line 914 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, (yyvsp[(2) - (3)].constDeclList).m_node.head), (yyvsp[(2) - (3)].constDeclList).m_varDeclarations, (yyvsp[(2) - (3)].constDeclList).m_funcDeclarations, (yyvsp[(2) - (3)].constDeclList).m_features, (yyvsp[(2) - (3)].constDeclList).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;}
break;
case 232:
-#line 919 "../parser/Grammar.y"
+#line 919 "parser/Grammar.y"
{ (yyval.constDeclList).m_node.head = (yyvsp[(1) - (1)].constDeclNode).m_node;
(yyval.constDeclList).m_node.tail = (yyval.constDeclList).m_node.head;
(yyval.constDeclList).m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>;
@@ -3976,7 +3976,7 @@ yyreduce:
break;
case 233:
-#line 928 "../parser/Grammar.y"
+#line 928 "parser/Grammar.y"
{ (yyval.constDeclList).m_node.head = (yyvsp[(1) - (3)].constDeclList).m_node.head;
(yyvsp[(1) - (3)].constDeclList).m_node.tail->m_next = (yyvsp[(3) - (3)].constDeclNode).m_node;
(yyval.constDeclList).m_node.tail = (yyvsp[(3) - (3)].constDeclNode).m_node;
@@ -3988,50 +3988,50 @@ yyreduce:
break;
case 234:
-#line 939 "../parser/Grammar.y"
+#line 939 "parser/Grammar.y"
{ (yyval.constDeclNode) = createNodeInfo<ConstDeclNode*>(new (GLOBAL_DATA) ConstDeclNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident), 0), (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); ;}
break;
case 235:
-#line 940 "../parser/Grammar.y"
+#line 940 "parser/Grammar.y"
{ (yyval.constDeclNode) = createNodeInfo<ConstDeclNode*>(new (GLOBAL_DATA) ConstDeclNode(GLOBAL_DATA, *(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].expressionNode).m_node), ((*(yyvsp[(1) - (2)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | (yyvsp[(2) - (2)].expressionNode).m_features, (yyvsp[(2) - (2)].expressionNode).m_numConstants); ;}
break;
case 236:
-#line 944 "../parser/Grammar.y"
+#line 944 "parser/Grammar.y"
{ (yyval.expressionNode) = (yyvsp[(2) - (2)].expressionNode); ;}
break;
case 237:
-#line 948 "../parser/Grammar.y"
+#line 948 "parser/Grammar.y"
{ (yyval.expressionNode) = (yyvsp[(2) - (2)].expressionNode); ;}
break;
case 238:
-#line 952 "../parser/Grammar.y"
+#line 952 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) EmptyStatementNode(GLOBAL_DATA), 0, 0, 0, 0); ;}
break;
case 239:
-#line 956 "../parser/Grammar.y"
+#line 956 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node), 0, 0, (yyvsp[(1) - (2)].expressionNode).m_features, (yyvsp[(1) - (2)].expressionNode).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;}
break;
case 240:
-#line 958 "../parser/Grammar.y"
+#line 958 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, (yyvsp[(1) - (2)].expressionNode).m_node), 0, 0, (yyvsp[(1) - (2)].expressionNode).m_features, (yyvsp[(1) - (2)].expressionNode).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;}
break;
case 241:
-#line 964 "../parser/Grammar.y"
+#line 964 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;}
break;
case 242:
-#line 967 "../parser/Grammar.y"
+#line 967 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfElseNode(GLOBAL_DATA, (yyvsp[(3) - (7)].expressionNode).m_node, (yyvsp[(5) - (7)].statementNode).m_node, (yyvsp[(7) - (7)].statementNode).m_node),
mergeDeclarationLists((yyvsp[(5) - (7)].statementNode).m_varDeclarations, (yyvsp[(7) - (7)].statementNode).m_varDeclarations),
mergeDeclarationLists((yyvsp[(5) - (7)].statementNode).m_funcDeclarations, (yyvsp[(7) - (7)].statementNode).m_funcDeclarations),
@@ -4041,25 +4041,25 @@ yyreduce:
break;
case 243:
-#line 976 "../parser/Grammar.y"
+#line 976 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node), (yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(2) - (7)].statementNode).m_funcDeclarations, (yyvsp[(2) - (7)].statementNode).m_features | (yyvsp[(5) - (7)].expressionNode).m_features, (yyvsp[(2) - (7)].statementNode).m_numConstants + (yyvsp[(5) - (7)].expressionNode).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;}
break;
case 244:
-#line 978 "../parser/Grammar.y"
+#line 978 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node), (yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(2) - (7)].statementNode).m_funcDeclarations, (yyvsp[(2) - (7)].statementNode).m_features | (yyvsp[(5) - (7)].expressionNode).m_features, (yyvsp[(2) - (7)].statementNode).m_numConstants + (yyvsp[(5) - (7)].expressionNode).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); ;}
break;
case 245:
-#line 980 "../parser/Grammar.y"
+#line 980 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WhileNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node), (yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;}
break;
case 246:
-#line 983 "../parser/Grammar.y"
+#line 983 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, (yyvsp[(3) - (9)].expressionNode).m_node, (yyvsp[(5) - (9)].expressionNode).m_node, (yyvsp[(7) - (9)].expressionNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node, false), (yyvsp[(9) - (9)].statementNode).m_varDeclarations, (yyvsp[(9) - (9)].statementNode).m_funcDeclarations,
(yyvsp[(3) - (9)].expressionNode).m_features | (yyvsp[(5) - (9)].expressionNode).m_features | (yyvsp[(7) - (9)].expressionNode).m_features | (yyvsp[(9) - (9)].statementNode).m_features,
(yyvsp[(3) - (9)].expressionNode).m_numConstants + (yyvsp[(5) - (9)].expressionNode).m_numConstants + (yyvsp[(7) - (9)].expressionNode).m_numConstants + (yyvsp[(9) - (9)].statementNode).m_numConstants);
@@ -4068,7 +4068,7 @@ yyreduce:
break;
case 247:
-#line 989 "../parser/Grammar.y"
+#line 989 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, (yyvsp[(4) - (10)].varDeclList).m_node, (yyvsp[(6) - (10)].expressionNode).m_node, (yyvsp[(8) - (10)].expressionNode).m_node, (yyvsp[(10) - (10)].statementNode).m_node, true),
mergeDeclarationLists((yyvsp[(4) - (10)].varDeclList).m_varDeclarations, (yyvsp[(10) - (10)].statementNode).m_varDeclarations),
mergeDeclarationLists((yyvsp[(4) - (10)].varDeclList).m_funcDeclarations, (yyvsp[(10) - (10)].statementNode).m_funcDeclarations),
@@ -4078,7 +4078,7 @@ yyreduce:
break;
case 248:
-#line 996 "../parser/Grammar.y"
+#line 996 "parser/Grammar.y"
{
ForInNode* node = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, (yyvsp[(3) - (7)].expressionNode).m_node, (yyvsp[(5) - (7)].expressionNode).m_node, (yyvsp[(7) - (7)].statementNode).m_node);
setExceptionLocation(node, (yylsp[(3) - (7)]).first_column, (yylsp[(3) - (7)]).last_column, (yylsp[(5) - (7)]).last_column);
@@ -4090,7 +4090,7 @@ yyreduce:
break;
case 249:
-#line 1005 "../parser/Grammar.y"
+#line 1005 "parser/Grammar.y"
{ ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *(yyvsp[(4) - (8)].ident), 0, (yyvsp[(6) - (8)].expressionNode).m_node, (yyvsp[(8) - (8)].statementNode).m_node, (yylsp[(5) - (8)]).first_column, (yylsp[(5) - (8)]).first_column - (yylsp[(4) - (8)]).first_column, (yylsp[(6) - (8)]).last_column - (yylsp[(5) - (8)]).first_column);
setExceptionLocation(forIn, (yylsp[(4) - (8)]).first_column, (yylsp[(5) - (8)]).first_column + 1, (yylsp[(6) - (8)]).last_column);
appendToVarDeclarationList(GLOBAL_DATA, (yyvsp[(8) - (8)].statementNode).m_varDeclarations, *(yyvsp[(4) - (8)].ident), DeclarationStacks::HasInitializer);
@@ -4099,7 +4099,7 @@ yyreduce:
break;
case 250:
-#line 1011 "../parser/Grammar.y"
+#line 1011 "parser/Grammar.y"
{ ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *(yyvsp[(4) - (9)].ident), (yyvsp[(5) - (9)].expressionNode).m_node, (yyvsp[(7) - (9)].expressionNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node, (yylsp[(5) - (9)]).first_column, (yylsp[(5) - (9)]).first_column - (yylsp[(4) - (9)]).first_column, (yylsp[(5) - (9)]).last_column - (yylsp[(5) - (9)]).first_column);
setExceptionLocation(forIn, (yylsp[(4) - (9)]).first_column, (yylsp[(6) - (9)]).first_column + 1, (yylsp[(7) - (9)]).last_column);
appendToVarDeclarationList(GLOBAL_DATA, (yyvsp[(9) - (9)].statementNode).m_varDeclarations, *(yyvsp[(4) - (9)].ident), DeclarationStacks::HasInitializer);
@@ -4110,17 +4110,17 @@ yyreduce:
break;
case 251:
-#line 1021 "../parser/Grammar.y"
+#line 1021 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(0, 0, 0); ;}
break;
case 253:
-#line 1026 "../parser/Grammar.y"
+#line 1026 "parser/Grammar.y"
{ (yyval.expressionNode) = createNodeInfo<ExpressionNode*>(0, 0, 0); ;}
break;
case 255:
-#line 1031 "../parser/Grammar.y"
+#line 1031 "parser/Grammar.y"
{ ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA);
setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0);
@@ -4128,7 +4128,7 @@ yyreduce:
break;
case 256:
-#line 1035 "../parser/Grammar.y"
+#line 1035 "parser/Grammar.y"
{ ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA);
setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0);
@@ -4136,7 +4136,7 @@ yyreduce:
break;
case 257:
-#line 1039 "../parser/Grammar.y"
+#line 1039 "parser/Grammar.y"
{ ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident));
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0);
@@ -4144,7 +4144,7 @@ yyreduce:
break;
case 258:
-#line 1043 "../parser/Grammar.y"
+#line 1043 "parser/Grammar.y"
{ ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident));
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0);
@@ -4152,82 +4152,82 @@ yyreduce:
break;
case 259:
-#line 1050 "../parser/Grammar.y"
+#line 1050 "parser/Grammar.y"
{ BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA);
setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;}
break;
case 260:
-#line 1053 "../parser/Grammar.y"
+#line 1053 "parser/Grammar.y"
{ BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA);
setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA), 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;}
break;
case 261:
-#line 1056 "../parser/Grammar.y"
+#line 1056 "parser/Grammar.y"
{ BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident));
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;}
break;
case 262:
-#line 1059 "../parser/Grammar.y"
+#line 1059 "parser/Grammar.y"
{ BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident));
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *(yyvsp[(2) - (3)].ident)), 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;}
break;
case 263:
-#line 1065 "../parser/Grammar.y"
+#line 1065 "parser/Grammar.y"
{ ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0);
setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;}
break;
case 264:
-#line 1068 "../parser/Grammar.y"
+#line 1068 "parser/Grammar.y"
{ ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0);
setExceptionLocation(node, (yylsp[(1) - (2)]).first_column, (yylsp[(1) - (2)]).last_column, (yylsp[(1) - (2)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;}
break;
case 265:
-#line 1071 "../parser/Grammar.y"
+#line 1071 "parser/Grammar.y"
{ ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); ;}
break;
case 266:
-#line 1074 "../parser/Grammar.y"
+#line 1074 "parser/Grammar.y"
{ ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; ;}
break;
case 267:
-#line 1080 "../parser/Grammar.y"
+#line 1080 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WithNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].statementNode).m_node, (yylsp[(3) - (5)]).last_column, (yylsp[(3) - (5)]).last_column - (yylsp[(3) - (5)]).first_column),
(yyvsp[(5) - (5)].statementNode).m_varDeclarations, (yyvsp[(5) - (5)].statementNode).m_funcDeclarations, (yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].statementNode).m_features | WithFeature, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].statementNode).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;}
break;
case 268:
-#line 1086 "../parser/Grammar.y"
+#line 1086 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) SwitchNode(GLOBAL_DATA, (yyvsp[(3) - (5)].expressionNode).m_node, (yyvsp[(5) - (5)].caseBlockNode).m_node), (yyvsp[(5) - (5)].caseBlockNode).m_varDeclarations, (yyvsp[(5) - (5)].caseBlockNode).m_funcDeclarations,
(yyvsp[(3) - (5)].expressionNode).m_features | (yyvsp[(5) - (5)].caseBlockNode).m_features, (yyvsp[(3) - (5)].expressionNode).m_numConstants + (yyvsp[(5) - (5)].caseBlockNode).m_numConstants);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); ;}
break;
case 269:
-#line 1092 "../parser/Grammar.y"
+#line 1092 "parser/Grammar.y"
{ (yyval.caseBlockNode) = createNodeDeclarationInfo<CaseBlockNode*>(new (GLOBAL_DATA) CaseBlockNode(GLOBAL_DATA, (yyvsp[(2) - (3)].clauseList).m_node.head, 0, 0), (yyvsp[(2) - (3)].clauseList).m_varDeclarations, (yyvsp[(2) - (3)].clauseList).m_funcDeclarations, (yyvsp[(2) - (3)].clauseList).m_features, (yyvsp[(2) - (3)].clauseList).m_numConstants); ;}
break;
case 270:
-#line 1094 "../parser/Grammar.y"
+#line 1094 "parser/Grammar.y"
{ (yyval.caseBlockNode) = createNodeDeclarationInfo<CaseBlockNode*>(new (GLOBAL_DATA) CaseBlockNode(GLOBAL_DATA, (yyvsp[(2) - (5)].clauseList).m_node.head, (yyvsp[(3) - (5)].caseClauseNode).m_node, (yyvsp[(4) - (5)].clauseList).m_node.head),
mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (5)].clauseList).m_varDeclarations, (yyvsp[(3) - (5)].caseClauseNode).m_varDeclarations), (yyvsp[(4) - (5)].clauseList).m_varDeclarations),
mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (5)].clauseList).m_funcDeclarations, (yyvsp[(3) - (5)].caseClauseNode).m_funcDeclarations), (yyvsp[(4) - (5)].clauseList).m_funcDeclarations),
@@ -4236,12 +4236,12 @@ yyreduce:
break;
case 271:
-#line 1102 "../parser/Grammar.y"
+#line 1102 "parser/Grammar.y"
{ (yyval.clauseList).m_node.head = 0; (yyval.clauseList).m_node.tail = 0; (yyval.clauseList).m_varDeclarations = 0; (yyval.clauseList).m_funcDeclarations = 0; (yyval.clauseList).m_features = 0; (yyval.clauseList).m_numConstants = 0; ;}
break;
case 273:
-#line 1107 "../parser/Grammar.y"
+#line 1107 "parser/Grammar.y"
{ (yyval.clauseList).m_node.head = new (GLOBAL_DATA) ClauseListNode(GLOBAL_DATA, (yyvsp[(1) - (1)].caseClauseNode).m_node);
(yyval.clauseList).m_node.tail = (yyval.clauseList).m_node.head;
(yyval.clauseList).m_varDeclarations = (yyvsp[(1) - (1)].caseClauseNode).m_varDeclarations;
@@ -4251,7 +4251,7 @@ yyreduce:
break;
case 274:
-#line 1113 "../parser/Grammar.y"
+#line 1113 "parser/Grammar.y"
{ (yyval.clauseList).m_node.head = (yyvsp[(1) - (2)].clauseList).m_node.head;
(yyval.clauseList).m_node.tail = new (GLOBAL_DATA) ClauseListNode(GLOBAL_DATA, (yyvsp[(1) - (2)].clauseList).m_node.tail, (yyvsp[(2) - (2)].caseClauseNode).m_node);
(yyval.clauseList).m_varDeclarations = mergeDeclarationLists((yyvsp[(1) - (2)].clauseList).m_varDeclarations, (yyvsp[(2) - (2)].caseClauseNode).m_varDeclarations);
@@ -4262,34 +4262,34 @@ yyreduce:
break;
case 275:
-#line 1123 "../parser/Grammar.y"
+#line 1123 "parser/Grammar.y"
{ (yyval.caseClauseNode) = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node), 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); ;}
break;
case 276:
-#line 1124 "../parser/Grammar.y"
+#line 1124 "parser/Grammar.y"
{ (yyval.caseClauseNode) = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, (yyvsp[(2) - (4)].expressionNode).m_node, (yyvsp[(4) - (4)].sourceElements).m_node), (yyvsp[(4) - (4)].sourceElements).m_varDeclarations, (yyvsp[(4) - (4)].sourceElements).m_funcDeclarations, (yyvsp[(2) - (4)].expressionNode).m_features | (yyvsp[(4) - (4)].sourceElements).m_features, (yyvsp[(2) - (4)].expressionNode).m_numConstants + (yyvsp[(4) - (4)].sourceElements).m_numConstants); ;}
break;
case 277:
-#line 1128 "../parser/Grammar.y"
+#line 1128 "parser/Grammar.y"
{ (yyval.caseClauseNode) = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, 0), 0, 0, 0, 0); ;}
break;
case 278:
-#line 1129 "../parser/Grammar.y"
+#line 1129 "parser/Grammar.y"
{ (yyval.caseClauseNode) = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, 0, (yyvsp[(3) - (3)].sourceElements).m_node), (yyvsp[(3) - (3)].sourceElements).m_varDeclarations, (yyvsp[(3) - (3)].sourceElements).m_funcDeclarations, (yyvsp[(3) - (3)].sourceElements).m_features, (yyvsp[(3) - (3)].sourceElements).m_numConstants); ;}
break;
case 279:
-#line 1133 "../parser/Grammar.y"
+#line 1133 "parser/Grammar.y"
{ LabelNode* node = new (GLOBAL_DATA) LabelNode(GLOBAL_DATA, *(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].statementNode).m_node);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, (yyvsp[(3) - (3)].statementNode).m_varDeclarations, (yyvsp[(3) - (3)].statementNode).m_funcDeclarations, (yyvsp[(3) - (3)].statementNode).m_features, (yyvsp[(3) - (3)].statementNode).m_numConstants); ;}
break;
case 280:
-#line 1139 "../parser/Grammar.y"
+#line 1139 "parser/Grammar.y"
{ ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)]));
@@ -4297,7 +4297,7 @@ yyreduce:
break;
case 281:
-#line 1143 "../parser/Grammar.y"
+#line 1143 "parser/Grammar.y"
{ ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, (yyvsp[(2) - (3)].expressionNode).m_node);
setExceptionLocation(node, (yylsp[(1) - (3)]).first_column, (yylsp[(2) - (3)]).last_column, (yylsp[(2) - (3)]).last_column);
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, (yyvsp[(2) - (3)].expressionNode).m_features, (yyvsp[(2) - (3)].expressionNode).m_numConstants); setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON;
@@ -4305,7 +4305,7 @@ yyreduce:
break;
case 282:
-#line 1150 "../parser/Grammar.y"
+#line 1150 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, (yyvsp[(2) - (4)].statementNode).m_node, GLOBAL_DATA->propertyNames->nullIdentifier, false, 0, (yyvsp[(4) - (4)].statementNode).m_node),
mergeDeclarationLists((yyvsp[(2) - (4)].statementNode).m_varDeclarations, (yyvsp[(4) - (4)].statementNode).m_varDeclarations),
mergeDeclarationLists((yyvsp[(2) - (4)].statementNode).m_funcDeclarations, (yyvsp[(4) - (4)].statementNode).m_funcDeclarations),
@@ -4315,7 +4315,7 @@ yyreduce:
break;
case 283:
-#line 1156 "../parser/Grammar.y"
+#line 1156 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, (yyvsp[(2) - (7)].statementNode).m_node, *(yyvsp[(5) - (7)].ident), ((yyvsp[(7) - (7)].statementNode).m_features & EvalFeature) != 0, (yyvsp[(7) - (7)].statementNode).m_node, 0),
mergeDeclarationLists((yyvsp[(2) - (7)].statementNode).m_varDeclarations, (yyvsp[(7) - (7)].statementNode).m_varDeclarations),
mergeDeclarationLists((yyvsp[(2) - (7)].statementNode).m_funcDeclarations, (yyvsp[(7) - (7)].statementNode).m_funcDeclarations),
@@ -4325,7 +4325,7 @@ yyreduce:
break;
case 284:
-#line 1163 "../parser/Grammar.y"
+#line 1163 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, (yyvsp[(2) - (9)].statementNode).m_node, *(yyvsp[(5) - (9)].ident), ((yyvsp[(7) - (9)].statementNode).m_features & EvalFeature) != 0, (yyvsp[(7) - (9)].statementNode).m_node, (yyvsp[(9) - (9)].statementNode).m_node),
mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (9)].statementNode).m_varDeclarations, (yyvsp[(7) - (9)].statementNode).m_varDeclarations), (yyvsp[(9) - (9)].statementNode).m_varDeclarations),
mergeDeclarationLists(mergeDeclarationLists((yyvsp[(2) - (9)].statementNode).m_funcDeclarations, (yyvsp[(7) - (9)].statementNode).m_funcDeclarations), (yyvsp[(9) - (9)].statementNode).m_funcDeclarations),
@@ -4335,24 +4335,24 @@ yyreduce:
break;
case 285:
-#line 1172 "../parser/Grammar.y"
+#line 1172 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); ;}
break;
case 286:
-#line 1174 "../parser/Grammar.y"
+#line 1174 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0);
setStatementLocation((yyval.statementNode).m_node, (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; ;}
break;
case 287:
-#line 1179 "../parser/Grammar.y"
+#line 1179 "parser/Grammar.y"
{ (yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) FuncDeclNode(GLOBAL_DATA, *(yyvsp[(2) - (7)].ident), (yyvsp[(6) - (7)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*(yyvsp[(2) - (7)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); setStatementLocation((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); (yyval.statementNode).m_funcDeclarations->data.append(static_cast<FuncDeclNode*>((yyval.statementNode).m_node)->body()); ;}
break;
case 288:
-#line 1181 "../parser/Grammar.y"
+#line 1181 "parser/Grammar.y"
{
(yyval.statementNode) = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) FuncDeclNode(GLOBAL_DATA, *(yyvsp[(2) - (8)].ident), (yyvsp[(7) - (8)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line), (yyvsp[(4) - (8)].parameterList).m_node.head), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*(yyvsp[(2) - (8)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0);
if ((yyvsp[(4) - (8)].parameterList).m_features & ArgumentsFeature)
@@ -4363,12 +4363,12 @@ yyreduce:
break;
case 289:
-#line 1191 "../parser/Grammar.y"
+#line 1191 "parser/Grammar.y"
{ (yyval.funcExprNode) = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, (yyvsp[(5) - (6)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(4) - (6)].intValue), (yyvsp[(6) - (6)].intValue), (yylsp[(4) - (6)]).first_line)), ClosureFeature, 0); setStatementLocation((yyvsp[(5) - (6)].functionBodyNode), (yylsp[(4) - (6)]), (yylsp[(6) - (6)])); ;}
break;
case 290:
-#line 1193 "../parser/Grammar.y"
+#line 1193 "parser/Grammar.y"
{
(yyval.funcExprNode) = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, (yyvsp[(6) - (7)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line), (yyvsp[(3) - (7)].parameterList).m_node.head), (yyvsp[(3) - (7)].parameterList).m_features | ClosureFeature, 0);
if ((yyvsp[(3) - (7)].parameterList).m_features & ArgumentsFeature)
@@ -4378,12 +4378,12 @@ yyreduce:
break;
case 291:
-#line 1199 "../parser/Grammar.y"
+#line 1199 "parser/Grammar.y"
{ (yyval.funcExprNode) = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, *(yyvsp[(2) - (7)].ident), (yyvsp[(6) - (7)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(5) - (7)].intValue), (yyvsp[(7) - (7)].intValue), (yylsp[(5) - (7)]).first_line)), ClosureFeature, 0); setStatementLocation((yyvsp[(6) - (7)].functionBodyNode), (yylsp[(5) - (7)]), (yylsp[(7) - (7)])); ;}
break;
case 292:
-#line 1201 "../parser/Grammar.y"
+#line 1201 "parser/Grammar.y"
{
(yyval.funcExprNode) = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, *(yyvsp[(2) - (8)].ident), (yyvsp[(7) - (8)].functionBodyNode), GLOBAL_DATA->lexer->sourceCode((yyvsp[(6) - (8)].intValue), (yyvsp[(8) - (8)].intValue), (yylsp[(6) - (8)]).first_line), (yyvsp[(4) - (8)].parameterList).m_node.head), (yyvsp[(4) - (8)].parameterList).m_features | ClosureFeature, 0);
if ((yyvsp[(4) - (8)].parameterList).m_features & ArgumentsFeature)
@@ -4393,42 +4393,42 @@ yyreduce:
break;
case 293:
-#line 1210 "../parser/Grammar.y"
+#line 1210 "parser/Grammar.y"
{ (yyval.parameterList).m_node.head = new (GLOBAL_DATA) ParameterNode(GLOBAL_DATA, *(yyvsp[(1) - (1)].ident));
(yyval.parameterList).m_features = (*(yyvsp[(1) - (1)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0;
(yyval.parameterList).m_node.tail = (yyval.parameterList).m_node.head; ;}
break;
case 294:
-#line 1213 "../parser/Grammar.y"
+#line 1213 "parser/Grammar.y"
{ (yyval.parameterList).m_node.head = (yyvsp[(1) - (3)].parameterList).m_node.head;
(yyval.parameterList).m_features = (yyvsp[(1) - (3)].parameterList).m_features | ((*(yyvsp[(3) - (3)].ident) == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0);
(yyval.parameterList).m_node.tail = new (GLOBAL_DATA) ParameterNode(GLOBAL_DATA, (yyvsp[(1) - (3)].parameterList).m_node.tail, *(yyvsp[(3) - (3)].ident)); ;}
break;
case 295:
-#line 1219 "../parser/Grammar.y"
+#line 1219 "parser/Grammar.y"
{ (yyval.functionBodyNode) = FunctionBodyNode::create(GLOBAL_DATA); ;}
break;
case 296:
-#line 1220 "../parser/Grammar.y"
+#line 1220 "parser/Grammar.y"
{ (yyval.functionBodyNode) = FunctionBodyNode::create(GLOBAL_DATA); ;}
break;
case 297:
-#line 1224 "../parser/Grammar.y"
+#line 1224 "parser/Grammar.y"
{ GLOBAL_DATA->parser->didFinishParsing(new (GLOBAL_DATA) SourceElements(GLOBAL_DATA), 0, 0, NoFeatures, (yylsp[(0) - (0)]).last_line, 0); ;}
break;
case 298:
-#line 1225 "../parser/Grammar.y"
+#line 1225 "parser/Grammar.y"
{ GLOBAL_DATA->parser->didFinishParsing((yyvsp[(1) - (1)].sourceElements).m_node, (yyvsp[(1) - (1)].sourceElements).m_varDeclarations, (yyvsp[(1) - (1)].sourceElements).m_funcDeclarations, (yyvsp[(1) - (1)].sourceElements).m_features,
(yylsp[(1) - (1)]).last_line, (yyvsp[(1) - (1)].sourceElements).m_numConstants); ;}
break;
case 299:
-#line 1230 "../parser/Grammar.y"
+#line 1230 "parser/Grammar.y"
{ (yyval.sourceElements).m_node = new (GLOBAL_DATA) SourceElements(GLOBAL_DATA);
(yyval.sourceElements).m_node->append((yyvsp[(1) - (1)].statementNode).m_node);
(yyval.sourceElements).m_varDeclarations = (yyvsp[(1) - (1)].statementNode).m_varDeclarations;
@@ -4439,7 +4439,7 @@ yyreduce:
break;
case 300:
-#line 1237 "../parser/Grammar.y"
+#line 1237 "parser/Grammar.y"
{ (yyval.sourceElements).m_node->append((yyvsp[(2) - (2)].statementNode).m_node);
(yyval.sourceElements).m_varDeclarations = mergeDeclarationLists((yyvsp[(1) - (2)].sourceElements).m_varDeclarations, (yyvsp[(2) - (2)].statementNode).m_varDeclarations);
(yyval.sourceElements).m_funcDeclarations = mergeDeclarationLists((yyvsp[(1) - (2)].sourceElements).m_funcDeclarations, (yyvsp[(2) - (2)].statementNode).m_funcDeclarations);
@@ -4449,188 +4449,188 @@ yyreduce:
break;
case 304:
-#line 1251 "../parser/Grammar.y"
+#line 1251 "parser/Grammar.y"
{ ;}
break;
case 305:
-#line 1252 "../parser/Grammar.y"
+#line 1252 "parser/Grammar.y"
{ ;}
break;
case 306:
-#line 1253 "../parser/Grammar.y"
+#line 1253 "parser/Grammar.y"
{ if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; ;}
break;
case 307:
-#line 1254 "../parser/Grammar.y"
+#line 1254 "parser/Grammar.y"
{ if (!GLOBAL_DATA->lexer->skipRegExp()) YYABORT; ;}
break;
case 308:
-#line 1258 "../parser/Grammar.y"
+#line 1258 "parser/Grammar.y"
{ ;}
break;
case 309:
-#line 1259 "../parser/Grammar.y"
+#line 1259 "parser/Grammar.y"
{ ;}
break;
case 310:
-#line 1260 "../parser/Grammar.y"
+#line 1260 "parser/Grammar.y"
{ ;}
break;
case 311:
-#line 1261 "../parser/Grammar.y"
+#line 1261 "parser/Grammar.y"
{ if (*(yyvsp[(1) - (7)].ident) != "get" && *(yyvsp[(1) - (7)].ident) != "set") YYABORT; ;}
break;
case 312:
-#line 1262 "../parser/Grammar.y"
+#line 1262 "parser/Grammar.y"
{ if (*(yyvsp[(1) - (8)].ident) != "get" && *(yyvsp[(1) - (8)].ident) != "set") YYABORT; ;}
break;
case 316:
-#line 1272 "../parser/Grammar.y"
+#line 1272 "parser/Grammar.y"
{ ;}
break;
case 317:
-#line 1273 "../parser/Grammar.y"
+#line 1273 "parser/Grammar.y"
{ ;}
break;
case 318:
-#line 1275 "../parser/Grammar.y"
+#line 1275 "parser/Grammar.y"
{ ;}
break;
case 322:
-#line 1282 "../parser/Grammar.y"
+#line 1282 "parser/Grammar.y"
{ ;}
break;
case 517:
-#line 1650 "../parser/Grammar.y"
+#line 1650 "parser/Grammar.y"
{ ;}
break;
case 518:
-#line 1651 "../parser/Grammar.y"
+#line 1651 "parser/Grammar.y"
{ ;}
break;
case 520:
-#line 1656 "../parser/Grammar.y"
+#line 1656 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 521:
-#line 1660 "../parser/Grammar.y"
+#line 1660 "parser/Grammar.y"
{ ;}
break;
case 522:
-#line 1661 "../parser/Grammar.y"
+#line 1661 "parser/Grammar.y"
{ ;}
break;
case 525:
-#line 1667 "../parser/Grammar.y"
+#line 1667 "parser/Grammar.y"
{ ;}
break;
case 526:
-#line 1668 "../parser/Grammar.y"
+#line 1668 "parser/Grammar.y"
{ ;}
break;
case 530:
-#line 1675 "../parser/Grammar.y"
+#line 1675 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 533:
-#line 1684 "../parser/Grammar.y"
+#line 1684 "parser/Grammar.y"
{ ;}
break;
case 534:
-#line 1685 "../parser/Grammar.y"
+#line 1685 "parser/Grammar.y"
{ ;}
break;
case 539:
-#line 1702 "../parser/Grammar.y"
+#line 1702 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 555:
-#line 1733 "../parser/Grammar.y"
+#line 1733 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 557:
-#line 1735 "../parser/Grammar.y"
+#line 1735 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 559:
-#line 1740 "../parser/Grammar.y"
+#line 1740 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 561:
-#line 1742 "../parser/Grammar.y"
+#line 1742 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 563:
-#line 1747 "../parser/Grammar.y"
+#line 1747 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 565:
-#line 1749 "../parser/Grammar.y"
+#line 1749 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 568:
-#line 1761 "../parser/Grammar.y"
+#line 1761 "parser/Grammar.y"
{ ;}
break;
case 569:
-#line 1762 "../parser/Grammar.y"
+#line 1762 "parser/Grammar.y"
{ ;}
break;
case 578:
-#line 1786 "../parser/Grammar.y"
+#line 1786 "parser/Grammar.y"
{ ;}
break;
case 580:
-#line 1791 "../parser/Grammar.y"
+#line 1791 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 585:
-#line 1802 "../parser/Grammar.y"
+#line 1802 "parser/Grammar.y"
{ AUTO_SEMICOLON; ;}
break;
case 592:
-#line 1818 "../parser/Grammar.y"
+#line 1818 "parser/Grammar.y"
{ ;}
break;
/* Line 1267 of yacc.c. */
-#line 4634 "JavaScriptCore/tmp/../generated/Grammar.tab.c"
+#line 4634 "generated/Grammar.tab.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -4850,7 +4850,7 @@ yyreturn:
}
-#line 1834 "../parser/Grammar.y"
+#line 1834 "parser/Grammar.y"
#undef GLOBAL_DATA
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.h
index 1fdb035..43a605a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/Grammar.h
@@ -174,7 +174,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 146 "../parser/Grammar.y"
+#line 146 "parser/Grammar.y"
{
int intValue;
double doubleValue;
@@ -207,7 +207,7 @@ typedef union YYSTYPE
Operator op;
}
/* Line 1489 of yacc.c. */
-#line 211 "JavaScriptCore/tmp/../generated/Grammar.tab.h"
+#line 211 "generated/Grammar.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/JSONObject.lut.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/JSONObject.lut.h
index a9b1631..f1a8210 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/JSONObject.lut.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/JSONObject.lut.h
@@ -1,4 +1,4 @@
-// Automatically generated from ../runtime/JSONObject.cpp using JavaScriptCore/create_hash_table. DO NOT EDIT!
+// Automatically generated from runtime/JSONObject.cpp using /home/khansen/dev/qtwebkit-qtscript-integration/JavaScriptCore/create_hash_table. DO NOT EDIT!
#include "Lookup.h"
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/Lexer.lut.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/Lexer.lut.h
index 95c33b6..107d98a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/Lexer.lut.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/Lexer.lut.h
@@ -1,4 +1,4 @@
-// Automatically generated from ../parser/Keywords.table using JavaScriptCore/create_hash_table. DO NOT EDIT!
+// Automatically generated from parser/Keywords.table using /home/khansen/dev/qtwebkit-qtscript-integration/JavaScriptCore/create_hash_table. DO NOT EDIT!
#include "Lookup.h"
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/MathObject.lut.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/MathObject.lut.h
index 9cb0ee2..becbb8c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/MathObject.lut.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/MathObject.lut.h
@@ -1,4 +1,4 @@
-// Automatically generated from ../runtime/MathObject.cpp using JavaScriptCore/create_hash_table. DO NOT EDIT!
+// Automatically generated from runtime/MathObject.cpp using /home/khansen/dev/qtwebkit-qtscript-integration/JavaScriptCore/create_hash_table. DO NOT EDIT!
#include "Lookup.h"
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/NumberConstructor.lut.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/NumberConstructor.lut.h
index 6285d62..9d754c7 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/NumberConstructor.lut.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/NumberConstructor.lut.h
@@ -1,4 +1,4 @@
-// Automatically generated from ../runtime/NumberConstructor.cpp using JavaScriptCore/create_hash_table. DO NOT EDIT!
+// Automatically generated from runtime/NumberConstructor.cpp using /home/khansen/dev/qtwebkit-qtscript-integration/JavaScriptCore/create_hash_table. DO NOT EDIT!
#include "Lookup.h"
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/RegExpConstructor.lut.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/RegExpConstructor.lut.h
index a3f15b3..c5fe7ad 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/RegExpConstructor.lut.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/RegExpConstructor.lut.h
@@ -1,4 +1,4 @@
-// Automatically generated from ../runtime/RegExpConstructor.cpp using JavaScriptCore/create_hash_table. DO NOT EDIT!
+// Automatically generated from runtime/RegExpConstructor.cpp using /home/khansen/dev/qtwebkit-qtscript-integration/JavaScriptCore/create_hash_table. DO NOT EDIT!
#include "Lookup.h"
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/RegExpObject.lut.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/RegExpObject.lut.h
index 8c87f16..2d684ae 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/RegExpObject.lut.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/RegExpObject.lut.h
@@ -1,4 +1,4 @@
-// Automatically generated from ../runtime/RegExpObject.cpp using JavaScriptCore/create_hash_table. DO NOT EDIT!
+// Automatically generated from runtime/RegExpObject.cpp using /home/khansen/dev/qtwebkit-qtscript-integration/JavaScriptCore/create_hash_table. DO NOT EDIT!
#include "Lookup.h"
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/generated/StringPrototype.lut.h b/src/3rdparty/javascriptcore/JavaScriptCore/generated/StringPrototype.lut.h
index f912298..c5dd4f0 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/generated/StringPrototype.lut.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/generated/StringPrototype.lut.h
@@ -1,10 +1,10 @@
-// Automatically generated from ../runtime/StringPrototype.cpp using JavaScriptCore/create_hash_table. DO NOT EDIT!
+// Automatically generated from runtime/StringPrototype.cpp using /home/khansen/dev/qtwebkit-qtscript-integration/JavaScriptCore/create_hash_table. DO NOT EDIT!
#include "Lookup.h"
namespace JSC {
-static const struct HashTableValue stringTableValues[33] = {
+static const struct HashTableValue stringTableValues[36] = {
{ "toString", DontEnum|Function, (intptr_t)stringProtoFuncToString, (intptr_t)0 },
{ "valueOf", DontEnum|Function, (intptr_t)stringProtoFuncToString, (intptr_t)0 },
{ "charAt", DontEnum|Function, (intptr_t)stringProtoFuncCharAt, (intptr_t)1 },
@@ -37,9 +37,12 @@ static const struct HashTableValue stringTableValues[33] = {
{ "fontsize", DontEnum|Function, (intptr_t)stringProtoFuncFontsize, (intptr_t)1 },
{ "anchor", DontEnum|Function, (intptr_t)stringProtoFuncAnchor, (intptr_t)1 },
{ "link", DontEnum|Function, (intptr_t)stringProtoFuncLink, (intptr_t)1 },
+ { "trim", DontEnum|Function, (intptr_t)stringProtoFuncTrim, (intptr_t)0 },
+ { "trimLeft", DontEnum|Function, (intptr_t)stringProtoFuncTrimLeft, (intptr_t)0 },
+ { "trimRight", DontEnum|Function, (intptr_t)stringProtoFuncTrimRight, (intptr_t)0 },
{ 0, 0, 0, 0 }
};
extern JSC_CONST_HASHTABLE HashTable stringTable =
- { 71, 63, stringTableValues, 0 };
+ { 133, 127, stringTableValues, 0 };
} // namespace
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CachedCall.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CachedCall.h
index b9fa484..eb48a03 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CachedCall.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CachedCall.h
@@ -38,7 +38,7 @@ namespace JSC {
: m_valid(false)
, m_interpreter(callFrame->interpreter())
, m_exception(exception)
- , m_globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : function->scope().node()->globalObject())
+ , m_globalObjectScope(callFrame, function->scope().globalObject())
{
ASSERT(!function->isHostFunction());
m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argCount, function->scope().node(), exception);
@@ -52,7 +52,14 @@ namespace JSC {
}
void setThis(JSValue v) { m_closure.setArgument(0, v); }
void setArgument(int n, JSValue v) { m_closure.setArgument(n + 1, v); }
- CallFrame* newCallFrame() { return m_closure.newCallFrame; }
+
+ CallFrame* newCallFrame(ExecState* exec)
+ {
+ CallFrame* callFrame = m_closure.newCallFrame;
+ callFrame->setScopeChain(exec->scopeChain());
+ return callFrame;
+ }
+
~CachedCall()
{
if (m_valid)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrame.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrame.h
index b04e1c1..6432f99 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrame.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/CallFrame.h
@@ -39,7 +39,11 @@ namespace JSC {
public:
JSObject* callee() const { return this[RegisterFile::Callee].object(); }
CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); }
- ScopeChainNode* scopeChain() const { return this[RegisterFile::ScopeChain].Register::scopeChain(); }
+ ScopeChainNode* scopeChain() const
+ {
+ ASSERT(this[RegisterFile::ScopeChain].Register::scopeChain());
+ return this[RegisterFile::ScopeChain].Register::scopeChain();
+ }
int argumentCount() const { return this[RegisterFile::ArgumentCount].i(); }
JSValue thisValue();
@@ -51,14 +55,14 @@ namespace JSC {
// Differs from dynamicGlobalObject() during function calls across web browser frames.
JSGlobalObject* lexicalGlobalObject() const
{
- return scopeChain()->globalObject();
+ return scopeChain()->globalObject;
}
// Differs from lexicalGlobalObject because this will have DOM window shell rather than
// the actual DOM window, which can't be "this" for security reasons.
JSObject* globalThisValue() const
{
- return scopeChain()->globalThisObject();
+ return scopeChain()->globalThis;
}
// FIXME: Elsewhere, we use JSGlobalData* rather than JSGlobalData&.
@@ -66,6 +70,7 @@ namespace JSC {
// or a pointer everywhere.
JSGlobalData& globalData() const
{
+ ASSERT(scopeChain()->globalData);
return *scopeChain()->globalData;
}
@@ -105,9 +110,9 @@ namespace JSC {
Arguments* optionalCalleeArguments() const { return this[RegisterFile::OptionalCalleeArguments].arguments(); }
Instruction* returnPC() const { return this[RegisterFile::ReturnPC].vPC(); }
- void setCalleeArguments(JSValue arguments) { this[RegisterFile::OptionalCalleeArguments] = arguments; }
- void setCallerFrame(CallFrame* callerFrame) { this[RegisterFile::CallerFrame] = callerFrame; }
- void setScopeChain(ScopeChainNode* scopeChain) { this[RegisterFile::ScopeChain] = scopeChain; }
+ void setCalleeArguments(JSValue arguments) { static_cast<Register*>(this)[RegisterFile::OptionalCalleeArguments] = arguments; }
+ void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
+ void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; }
ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain,
CallFrame* callerFrame, int returnValueRegister, int argc, JSObject* callee)
@@ -117,8 +122,8 @@ namespace JSC {
setCodeBlock(codeBlock);
setScopeChain(scopeChain);
setCallerFrame(callerFrame);
- this[RegisterFile::ReturnPC] = vPC; // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*.
- this[RegisterFile::ReturnValueRegister] = Register::withInt(returnValueRegister);
+ static_cast<Register*>(this)[RegisterFile::ReturnPC] = vPC; // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*.
+ static_cast<Register*>(this)[RegisterFile::ReturnValueRegister] = Register::withInt(returnValueRegister);
setArgumentCount(argc); // original argument count (for the sake of the "arguments" object)
setCallee(callee);
setCalleeArguments(JSValue());
@@ -135,9 +140,9 @@ namespace JSC {
CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); }
private:
- void setArgumentCount(int count) { this[RegisterFile::ArgumentCount] = Register::withInt(count); }
- void setCallee(JSObject* callee) { this[RegisterFile::Callee] = callee; }
- void setCodeBlock(CodeBlock* codeBlock) { this[RegisterFile::CodeBlock] = codeBlock; }
+ void setArgumentCount(int count) { static_cast<Register*>(this)[RegisterFile::ArgumentCount] = Register::withInt(count); }
+ void setCallee(JSObject* callee) { static_cast<Register*>(this)[RegisterFile::Callee] = callee; }
+ void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[RegisterFile::CodeBlock] = codeBlock; }
static const intptr_t HostCallFrameFlag = 1;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp
index 4f00b2b..2164b1d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.cpp
@@ -95,8 +95,8 @@ static int depth(CodeBlock* codeBlock, ScopeChain& sc)
#if USE(INTERPRETER)
NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
{
- int dst = (vPC + 1)->u.operand;
- int property = (vPC + 2)->u.operand;
+ int dst = vPC[1].u.operand;
+ int property = vPC[2].u.operand;
ScopeChainNode* scopeChain = callFrame->scopeChain();
ScopeChainIterator iter = scopeChain->begin();
@@ -125,9 +125,9 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP
{
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 dst = vPC[1].u.operand;
+ int property = vPC[2].u.operand;
+ int skip = vPC[3].u.operand + codeBlock->needsFullScopeChain();
ScopeChainNode* scopeChain = callFrame->scopeChain();
ScopeChainIterator iter = scopeChain->begin();
@@ -156,12 +156,12 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP
NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
{
- int dst = (vPC + 1)->u.operand;
- JSGlobalObject* globalObject = static_cast<JSGlobalObject*>((vPC + 2)->u.jsCell);
+ int dst = vPC[1].u.operand;
+ JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(vPC[2].u.jsCell);
ASSERT(globalObject->isGlobalObject());
- int property = (vPC + 3)->u.operand;
- Structure* structure = (vPC + 4)->u.structure;
- int offset = (vPC + 5)->u.operand;
+ int property = vPC[3].u.operand;
+ Structure* structure = vPC[4].u.structure;
+ int offset = vPC[5].u.operand;
if (structure == globalObject->structure()) {
callFrame->r(dst) = JSValue(globalObject->getDirectOffset(offset));
@@ -196,16 +196,16 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC)
{
- int dst = (vPC + 1)->u.operand;
- int property = (vPC + 2)->u.operand;
+ int dst = vPC[1].u.operand;
+ int property = vPC[2].u.operand;
callFrame->r(dst) = JSValue(JSC::resolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain()));
}
NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
{
- int baseDst = (vPC + 1)->u.operand;
- int propDst = (vPC + 2)->u.operand;
- int property = (vPC + 3)->u.operand;
+ int baseDst = vPC[1].u.operand;
+ int propDst = vPC[2].u.operand;
+ int property = vPC[3].u.operand;
ScopeChainNode* scopeChain = callFrame->scopeChain();
ScopeChainIterator iter = scopeChain->begin();
@@ -237,51 +237,6 @@ NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Inst
return false;
}
-NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
-{
- int baseDst = (vPC + 1)->u.operand;
- int funcDst = (vPC + 2)->u.operand;
- int property = (vPC + 3)->u.operand;
-
- ScopeChainNode* scopeChain = callFrame->scopeChain();
- ScopeChainIterator iter = scopeChain->begin();
- ScopeChainIterator end = scopeChain->end();
-
- // FIXME: add scopeDepthIsZero optimization
-
- ASSERT(iter != end);
-
- CodeBlock* codeBlock = callFrame->codeBlock();
- Identifier& ident = codeBlock->identifier(property);
- JSObject* base;
- do {
- base = *iter;
- PropertySlot slot(base);
- if (base->getPropertySlot(callFrame, ident, slot)) {
- // ECMA 11.2.3 says that if we hit an activation the this value should be null.
- // However, section 10.2.3 says that in the case where the value provided
- // by the caller is null, the global object should be used. It also says
- // that the section does not apply to internal functions, but for simplicity
- // of implementation we use the global object anyway here. This guarantees
- // that in host objects you always get a valid object for this.
- // We also handle wrapper substitution for the global object at the same time.
- JSObject* thisObj = base->toThisObject(callFrame);
- JSValue result = slot.getValue(callFrame, ident);
- exceptionValue = callFrame->globalData().exception;
- if (exceptionValue)
- return false;
-
- callFrame->r(baseDst) = JSValue(thisObj);
- callFrame->r(funcDst) = JSValue(result);
- return true;
- }
- ++iter;
- } while (iter != end);
-
- exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);
- return false;
-}
-
#endif // USE(INTERPRETER)
ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc)
@@ -349,7 +304,7 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r
if (!program.isString())
return program;
- UString programSource = asString(program)->value();
+ UString programSource = asString(program)->value(callFrame);
LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON);
if (JSValue parsedObject = preparser.tryLiteralParse())
@@ -367,10 +322,19 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r
}
Interpreter::Interpreter()
- : m_sampler(0)
+ : m_sampleEntryDepth(0)
, m_reentryDepth(0)
{
+#if HAVE(COMPUTED_GOTO)
privateExecute(InitializeAndReturn, 0, 0, 0);
+
+ for (int i = 0; i < numOpcodeIDs; ++i)
+ m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
+#endif // HAVE(COMPUTED_GOTO)
+
+#if ENABLE(OPCODE_SAMPLING)
+ enableSampler();
+#endif
}
#ifndef NDEBUG
@@ -389,7 +353,7 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
printf("-----------------------------------------------------------------------------\n");
CodeBlock* codeBlock = callFrame->codeBlock();
- RegisterFile* registerFile = &callFrame->scopeChain()->globalObject()->globalData()->interpreter->registerFile();
+ RegisterFile* registerFile = &callFrame->scopeChain()->globalObject->globalData()->interpreter->registerFile();
const Register* it;
const Register* end;
JSValue v;
@@ -577,7 +541,8 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
if (debugger) {
DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
- debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset));
+ bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
+ debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset), hasHandler);
}
// If we throw in the middle of a call instruction, we need to notify
@@ -587,7 +552,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
#if !ENABLE(JIT)
if (isCallBytecode(codeBlock->instructions()[bytecodeOffset].u.opcode))
profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 2].u.operand).jsValue());
- else if (codeBlock->instructions()[bytecodeOffset + 8].u.opcode == getOpcode(op_construct))
+ else if (codeBlock->instructions().size() > (bytecodeOffset + 8) && codeBlock->instructions()[bytecodeOffset + 8].u.opcode == getOpcode(op_construct))
profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 10].u.operand).jsValue());
#else
int functionRegisterIndex;
@@ -659,7 +624,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
return jsNull();
}
- DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject());
+ DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
JSGlobalObject* lastGlobalObject = m_registerFile.globalObject();
JSGlobalObject* globalObject = callFrame->dynamicGlobalObject();
@@ -678,7 +643,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
JSValue result;
{
- SamplingTool::CallRecord callRecord(m_sampler);
+ SamplingTool::CallRecord callRecord(m_sampler.get());
m_reentryDepth++;
#if ENABLE(JIT)
@@ -719,7 +684,7 @@ JSValue Interpreter::execute(FunctionExecutable* functionExecutable, CallFrame*
return jsNull();
}
- DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
+ DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
CallFrame* newCallFrame = CallFrame::create(oldEnd);
size_t dst = 0;
@@ -744,7 +709,7 @@ JSValue Interpreter::execute(FunctionExecutable* functionExecutable, CallFrame*
JSValue result;
{
- SamplingTool::CallRecord callRecord(m_sampler);
+ SamplingTool::CallRecord callRecord(m_sampler.get());
m_reentryDepth++;
#if ENABLE(JIT)
@@ -812,7 +777,7 @@ JSValue Interpreter::execute(CallFrameClosure& closure, JSValue* exception)
JSValue result;
{
- SamplingTool::CallRecord callRecord(m_sampler);
+ SamplingTool::CallRecord callRecord(m_sampler.get());
m_reentryDepth++;
#if ENABLE(JIT)
@@ -849,7 +814,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
}
}
- DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
+ DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
EvalCodeBlock* codeBlock = &eval->bytecode(callFrame, scopeChain);
@@ -914,7 +879,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
JSValue result;
{
- SamplingTool::CallRecord callRecord(m_sampler);
+ SamplingTool::CallRecord callRecord(m_sampler.get());
m_reentryDepth++;
#if ENABLE(JIT)
@@ -932,7 +897,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
return result;
}
-NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine, int column)
+NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine)
{
Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
if (!debugger)
@@ -946,7 +911,7 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
return;
case WillExecuteStatement:
- debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine, column);
+ debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
return;
case WillExecuteProgram:
debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
@@ -955,7 +920,7 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
return;
case DidReachBreakpoint:
- debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine, column);
+ debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
return;
}
}
@@ -963,10 +928,10 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
#if USE(INTERPRETER)
NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
{
- int dst = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
CodeBlock* codeBlock = callFrame->codeBlock();
- Identifier& property = codeBlock->identifier((++vPC)->u.operand);
- JSValue value = callFrame->r((++vPC)->u.operand).jsValue();
+ Identifier& property = codeBlock->identifier(vPC[2].u.operand);
+ JSValue value = callFrame->r(vPC[3].u.operand).jsValue();
JSObject* scope = new (callFrame) JSStaticScopeObject(callFrame, property, value, DontDelete);
callFrame->r(dst) = JSValue(scope);
@@ -1018,22 +983,20 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock*
return;
}
- StructureChain* protoChain = structure->prototypeChain(callFrame);
- if (!protoChain->isCacheable()) {
- vPC[0] = getOpcode(op_put_by_id_generic);
- return;
- }
-
// Structure transition, cache transition info
if (slot.type() == PutPropertySlot::NewProperty) {
if (structure->isDictionary()) {
vPC[0] = getOpcode(op_put_by_id_generic);
return;
}
+
+ // put_by_id_transition checks the prototype chain for setters.
+ normalizePrototypeChain(callFrame, baseCell);
+
vPC[0] = getOpcode(op_put_by_id_transition);
vPC[4] = structure->previousID();
vPC[5] = structure;
- vPC[6] = protoChain;
+ vPC[6] = structure->prototypeChain(callFrame);
vPC[7] = slot.cachedOffset();
codeBlock->refStructures(vPC);
return;
@@ -1111,41 +1074,46 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
return;
}
+ if (structure->isDictionary()) {
+ vPC[0] = getOpcode(op_get_by_id_generic);
+ return;
+ }
+
if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
ASSERT(slot.slotBase().isObject());
JSObject* baseObject = asObject(slot.slotBase());
+ size_t offset = slot.cachedOffset();
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
- if (baseObject->structure()->isDictionary())
- baseObject->setStructure(Structure::fromDictionaryTransition(baseObject->structure()));
+ if (baseObject->structure()->isDictionary()) {
+ baseObject->flattenDictionaryObject();
+ offset = baseObject->structure()->get(propertyName);
+ }
+
+ ASSERT(!baseObject->structure()->isUncacheableDictionary());
vPC[0] = getOpcode(op_get_by_id_proto);
vPC[5] = baseObject->structure();
- vPC[6] = slot.cachedOffset();
+ vPC[6] = offset;
codeBlock->refStructures(vPC);
return;
}
- size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot);
+ size_t offset = slot.cachedOffset();
+ size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
if (!count) {
vPC[0] = getOpcode(op_get_by_id_generic);
return;
}
- StructureChain* protoChain = structure->prototypeChain(callFrame);
- if (!protoChain->isCacheable()) {
- vPC[0] = getOpcode(op_get_by_id_generic);
- return;
- }
-
vPC[0] = getOpcode(op_get_by_id_chain);
vPC[4] = structure;
- vPC[5] = protoChain;
+ vPC[5] = structure->prototypeChain(callFrame);
vPC[6] = count;
- vPC[7] = slot.cachedOffset();
+ vPC[7] = offset;
codeBlock->refStructures(vPC);
}
@@ -1162,16 +1130,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
{
// One-time initialization of our address tables. We have to put this code
// here because our labels are only in scope inside this function.
- if (flag == InitializeAndReturn) {
+ if (UNLIKELY(flag == InitializeAndReturn)) {
#if HAVE(COMPUTED_GOTO)
- #define ADD_BYTECODE(id, length) m_opcodeTable[id] = &&id;
- FOR_EACH_OPCODE_ID(ADD_BYTECODE);
- #undef ADD_BYTECODE
-
- #define ADD_OPCODE_ID(id, length) m_opcodeIDTable.add(&&id, id);
- FOR_EACH_OPCODE_ID(ADD_OPCODE_ID);
- #undef ADD_OPCODE_ID
- ASSERT(m_opcodeIDTable.size() == numOpcodeIDs);
+ #define LIST_OPCODE_LABEL(id, length) &&id,
+ static Opcode labels[] = { FOR_EACH_OPCODE_ID(LIST_OPCODE_LABEL) };
+ for (size_t i = 0; i < sizeof(labels) / sizeof(Opcode); ++i)
+ m_opcodeTable[i] = labels[i];
+ #undef LIST_OPCODE_LABEL
#endif // HAVE(COMPUTED_GOTO)
return JSValue();
}
@@ -1249,10 +1214,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Constructs a new empty Object instance using the original
constructor, and puts the result in register dst.
*/
- int dst = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
callFrame->r(dst) = JSValue(constructEmptyObject(callFrame));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_new_object);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_new_array) {
@@ -1263,13 +1228,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
The array will contain argCount elements with values
taken from registers starting at register firstArg.
*/
- int dst = (++vPC)->u.operand;
- int firstArg = (++vPC)->u.operand;
- int argCount = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int firstArg = vPC[2].u.operand;
+ int argCount = vPC[3].u.operand;
ArgList args(callFrame->registers() + firstArg, argCount);
callFrame->r(dst) = JSValue(constructArray(callFrame, args));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_new_array);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_new_regexp) {
@@ -1279,11 +1244,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
constructor from regexp regExp, and puts the result in
register dst.
*/
- int dst = (++vPC)->u.operand;
- int regExp = (++vPC)->u.operand;
- callFrame->r(dst) = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject()->regExpStructure(), callFrame->codeBlock()->regexp(regExp)));
+ int dst = vPC[1].u.operand;
+ int regExp = vPC[2].u.operand;
+ callFrame->r(dst) = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject->regExpStructure(), callFrame->codeBlock()->regexp(regExp)));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_new_regexp);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_mov) {
@@ -1291,11 +1256,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Copies register src to register dst.
*/
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
callFrame->r(dst) = callFrame->r(src);
- ++vPC;
+ vPC += OPCODE_LENGTH(op_mov);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_eq) {
@@ -1305,9 +1270,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
as with the ECMAScript '==' operator, and puts the result
as a boolean in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32())
callFrame->r(dst) = jsBoolean(src1.asInt32() == src2.asInt32());
else {
@@ -1316,7 +1281,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_eq);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_eq_null) {
@@ -1325,17 +1290,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
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->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
if (src.isUndefinedOrNull()) {
callFrame->r(dst) = jsBoolean(true);
- ++vPC;
+ vPC += OPCODE_LENGTH(op_eq_null);
NEXT_INSTRUCTION();
}
callFrame->r(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_eq_null);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_neq) {
@@ -1345,9 +1310,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
equal, as with the ECMAScript '!=' operator, and puts the
result as a boolean in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32())
callFrame->r(dst) = jsBoolean(src1.asInt32() != src2.asInt32());
else {
@@ -1356,7 +1321,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_neq);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_neq_null) {
@@ -1365,17 +1330,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
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->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
if (src.isUndefinedOrNull()) {
callFrame->r(dst) = jsBoolean(false);
- ++vPC;
+ vPC += OPCODE_LENGTH(op_neq_null);
NEXT_INSTRUCTION();
}
callFrame->r(dst) = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_neq_null);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_stricteq) {
@@ -1385,12 +1350,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
equal, as with the ECMAScript '===' operator, and puts the
result as a boolean in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- callFrame->r(dst) = jsBoolean(JSValue::strictEqual(src1, src2));
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
+ callFrame->r(dst) = jsBoolean(JSValue::strictEqual(callFrame, src1, src2));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_stricteq);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_nstricteq) {
@@ -1400,12 +1365,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
strictly equal, as with the ECMAScript '!==' operator, and
puts the result as a boolean in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- callFrame->r(dst) = jsBoolean(!JSValue::strictEqual(src1, src2));
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
+ callFrame->r(dst) = jsBoolean(!JSValue::strictEqual(callFrame, src1, src2));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_nstricteq);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_less) {
@@ -1415,14 +1380,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
with the ECMAScript '<' operator, and puts the result as
a boolean in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
JSValue result = jsBoolean(jsLess(callFrame, src1, src2));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
- ++vPC;
+ vPC += OPCODE_LENGTH(op_less);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_lesseq) {
@@ -1432,14 +1397,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
register src2, as with the ECMAScript '<=' operator, and
puts the result as a boolean in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
JSValue result = jsBoolean(jsLessEq(callFrame, src1, src2));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
- ++vPC;
+ vPC += OPCODE_LENGTH(op_lesseq);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_pre_inc) {
@@ -1448,7 +1413,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Converts register srcDst to number, adds one, and puts the result
back in register srcDst.
*/
- int srcDst = (++vPC)->u.operand;
+ int srcDst = vPC[1].u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
if (v.isInt32() && v.asInt32() < INT_MAX)
callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1);
@@ -1458,7 +1423,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(srcDst) = result;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_pre_inc);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_pre_dec) {
@@ -1467,7 +1432,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Converts register srcDst to number, subtracts one, and puts the result
back in register srcDst.
*/
- int srcDst = (++vPC)->u.operand;
+ int srcDst = vPC[1].u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
if (v.isInt32() && v.asInt32() > INT_MIN)
callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1);
@@ -1477,7 +1442,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(srcDst) = result;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_pre_dec);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_post_inc) {
@@ -1487,8 +1452,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
written to register dst, and the number plus one is written
back to register srcDst.
*/
- int dst = (++vPC)->u.operand;
- int srcDst = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int srcDst = vPC[2].u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
if (v.isInt32() && v.asInt32() < INT_MAX) {
callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1);
@@ -1500,7 +1465,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = number;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_post_inc);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_post_dec) {
@@ -1510,8 +1475,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
written to register dst, and the number minus one is written
back to register srcDst.
*/
- int dst = (++vPC)->u.operand;
- int srcDst = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int srcDst = vPC[2].u.operand;
JSValue v = callFrame->r(srcDst).jsValue();
if (v.isInt32() && v.asInt32() > INT_MIN) {
callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1);
@@ -1523,7 +1488,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = number;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_post_dec);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_to_jsnumber) {
@@ -1532,8 +1497,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Converts register src to number, and puts the result
in register dst.
*/
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
JSValue srcVal = callFrame->r(src).jsValue();
@@ -1545,7 +1510,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_to_jsnumber);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_negate) {
@@ -1554,8 +1519,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Converts register src to number, negates it, and puts the
result in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
if (src.isInt32() && src.asInt32())
callFrame->r(dst) = jsNumber(callFrame, -src.asInt32());
else {
@@ -1564,7 +1529,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_negate);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_add) {
@@ -1574,17 +1539,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
in register dst. (JS add may be string concatenation or
numeric add, depending on the types of the operands.)
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
+ if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow
callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() + src2.asInt32());
else {
JSValue result = jsAdd(callFrame, src1, src2);
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
- vPC += 2;
+ vPC += OPCODE_LENGTH(op_add);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_mul) {
@@ -1593,9 +1558,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Multiplies register src1 and register src2 (converted to
numbers), and puts the product in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow
callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() * src2.asInt32());
else {
@@ -1604,7 +1569,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- vPC += 2;
+ vPC += OPCODE_LENGTH(op_mul);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_div) {
@@ -1614,15 +1579,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
register divisor (converted to number), and puts the
quotient in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
JSValue result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
- vPC += 2;
+ vPC += OPCODE_LENGTH(op_div);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_mod) {
@@ -1632,15 +1597,15 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
register divisor (converted to number), and puts the
remainder in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue dividend = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue divisor = callFrame->r(vPC[3].u.operand).jsValue();
if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) {
JSValue result = jsNumber(callFrame, dividend.asInt32() % divisor.asInt32());
ASSERT(result);
callFrame->r(dst) = result;
- ++vPC;
+ vPC += OPCODE_LENGTH(op_mod);
NEXT_INSTRUCTION();
}
@@ -1651,7 +1616,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue result = jsNumber(callFrame, fmod(d1, d2));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
- ++vPC;
+ vPC += OPCODE_LENGTH(op_mod);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_sub) {
@@ -1661,17 +1626,17 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
src1 (converted to number), and puts the difference in
register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
+ if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | (src2.asInt32() & 0xc0000000))) // no overflow
callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() - src2.asInt32());
else {
JSValue result = jsNumber(callFrame, src1.toNumber(callFrame) - src2.toNumber(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
- vPC += 2;
+ vPC += OPCODE_LENGTH(op_sub);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_lshift) {
@@ -1681,9 +1646,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
register shift (converted to uint32), and puts the result
in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
if (val.isInt32() && shift.isInt32())
callFrame->r(dst) = jsNumber(callFrame, val.asInt32() << (shift.asInt32() & 0x1f));
@@ -1693,7 +1658,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_lshift);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_rshift) {
@@ -1703,9 +1668,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
to int32) by register shift (converted to
uint32), and puts the result in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
if (val.isInt32() && shift.isInt32())
callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f));
@@ -1715,7 +1680,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_rshift);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_urshift) {
@@ -1725,9 +1690,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
to uint32) by register shift (converted to
uint32), and puts the result in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue val = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue shift = callFrame->r(vPC[3].u.operand).jsValue();
if (val.isUInt32() && shift.isInt32())
callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f));
else {
@@ -1736,7 +1701,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_urshift);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_bitand) {
@@ -1746,9 +1711,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
and register src2 (converted to int32), and puts the result
in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32())
callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() & src2.asInt32());
else {
@@ -1757,7 +1722,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- vPC += 2;
+ vPC += OPCODE_LENGTH(op_bitand);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_bitxor) {
@@ -1767,9 +1732,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
and register src2 (converted to int32), and puts the result
in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32())
callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() ^ src2.asInt32());
else {
@@ -1778,7 +1743,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- vPC += 2;
+ vPC += OPCODE_LENGTH(op_bitxor);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_bitor) {
@@ -1788,9 +1753,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
and register src2 (converted to int32), and puts the
result in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
if (src1.isInt32() && src2.isInt32())
callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() | src2.asInt32());
else {
@@ -1799,7 +1764,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = result;
}
- vPC += 2;
+ vPC += OPCODE_LENGTH(op_bitor);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_bitnot) {
@@ -1808,8 +1773,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Computes bitwise NOT of register src1 (converted to int32),
and puts the result in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
+ int dst = vPC[1].u.operand;
+ JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
if (src.isInt32())
callFrame->r(dst) = jsNumber(callFrame, ~src.asInt32());
else {
@@ -1817,7 +1782,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_bitnot);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_not) {
@@ -1826,13 +1791,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Computes logical NOT of register src (converted to
boolean), and puts the result in register dst.
*/
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
- ++vPC;
+ vPC += OPCODE_LENGTH(op_not);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_instanceof) {
@@ -1862,7 +1827,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = jsBoolean(result);
- vPC += 5;
+ vPC += OPCODE_LENGTH(op_instanceof);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_typeof) {
@@ -1871,11 +1836,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Determines the type string for src according to ECMAScript
rules, and puts the result in register dst.
*/
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
callFrame->r(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue()));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_typeof);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_is_undefined) {
@@ -1885,12 +1850,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
the ECMAScript rules is "undefined", and puts the result
in register dst.
*/
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
JSValue v = callFrame->r(src).jsValue();
callFrame->r(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_is_undefined);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_is_boolean) {
@@ -1900,11 +1865,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
the ECMAScript rules is "boolean", and puts the result
in register dst.
*/
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_is_boolean);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_is_number) {
@@ -1914,11 +1879,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
the ECMAScript rules is "number", and puts the result
in register dst.
*/
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_is_number);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_is_string) {
@@ -1928,11 +1893,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
the ECMAScript rules is "string", and puts the result
in register dst.
*/
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isString());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_is_string);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_is_object) {
@@ -1942,11 +1907,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
the ECMAScript rules is "object", and puts the result
in register dst.
*/
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
callFrame->r(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue()));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_is_object);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_is_function) {
@@ -1956,11 +1921,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
the ECMAScript rules is "function", and puts the result
in register dst.
*/
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
callFrame->r(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue()));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_is_function);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_in) {
@@ -1972,9 +1937,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Raises an exception if register constructor is not an
object.
*/
- int dst = (++vPC)->u.operand;
- int property = (++vPC)->u.operand;
- int base = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int property = vPC[2].u.operand;
+ int base = vPC[3].u.operand;
JSValue baseVal = callFrame->r(base).jsValue();
if (isInvalidParamForIn(callFrame, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
@@ -1993,7 +1958,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = jsBoolean(baseObj->hasProperty(callFrame, property));
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_in);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_resolve) {
@@ -2006,7 +1971,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (UNLIKELY(!resolve(callFrame, vPC, exceptionValue)))
goto vm_throw;
- vPC += 3;
+ vPC += OPCODE_LENGTH(op_resolve);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_resolve_skip) {
@@ -2019,7 +1984,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (UNLIKELY(!resolveSkip(callFrame, vPC, exceptionValue)))
goto vm_throw;
- vPC += 4;
+ vPC += OPCODE_LENGTH(op_resolve_skip);
NEXT_INSTRUCTION();
}
@@ -2034,7 +1999,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue)))
goto vm_throw;
- vPC += 6;
+ vPC += OPCODE_LENGTH(op_resolve_global);
NEXT_INSTRUCTION();
}
@@ -2043,13 +2008,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Gets the global var at global slot index and places it in register dst.
*/
- int dst = (++vPC)->u.operand;
- JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell);
+ int dst = vPC[1].u.operand;
+ JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[2].u.jsCell);
ASSERT(scope->isGlobalObject());
- int index = (++vPC)->u.operand;
+ int index = vPC[3].u.operand;
callFrame->r(dst) = scope->registerAt(index);
- ++vPC;
+ vPC += OPCODE_LENGTH(op_get_global_var);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_put_global_var) {
@@ -2057,13 +2022,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Puts value into global slot index.
*/
- JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell);
+ JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[1].u.jsCell);
ASSERT(scope->isGlobalObject());
- int index = (++vPC)->u.operand;
- int value = (++vPC)->u.operand;
+ int index = vPC[2].u.operand;
+ int value = vPC[3].u.operand;
scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_put_global_var);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_get_scoped_var) {
@@ -2072,9 +2037,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Loads the contents of the index-th local from the scope skip nodes from
the top of the scope chain, and places it in register dst
*/
- int dst = (++vPC)->u.operand;
- int index = (++vPC)->u.operand;
- int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain();
+ int dst = vPC[1].u.operand;
+ int index = vPC[2].u.operand;
+ int skip = vPC[3].u.operand + callFrame->codeBlock()->needsFullScopeChain();
ScopeChainNode* scopeChain = callFrame->scopeChain();
ScopeChainIterator iter = scopeChain->begin();
@@ -2088,16 +2053,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT((*iter)->isVariableObject());
JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
callFrame->r(dst) = scope->registerAt(index);
- ++vPC;
+ vPC += OPCODE_LENGTH(op_get_scoped_var);
NEXT_INSTRUCTION();
}
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 value = (++vPC)->u.operand;
+ int index = vPC[1].u.operand;
+ int skip = vPC[2].u.operand + callFrame->codeBlock()->needsFullScopeChain();
+ int value = vPC[3].u.operand;
ScopeChainNode* scopeChain = callFrame->scopeChain();
ScopeChainIterator iter = scopeChain->begin();
@@ -2111,7 +2076,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT((*iter)->isVariableObject());
JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_put_scoped_var);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_resolve_base) {
@@ -2124,7 +2089,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
resolveBase(callFrame, vPC);
- vPC += 3;
+ vPC += OPCODE_LENGTH(op_resolve_base);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_resolve_with_base) {
@@ -2142,7 +2107,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (UNLIKELY(!resolveBaseAndProperty(callFrame, vPC, exceptionValue)))
goto vm_throw;
- vPC += 4;
+ vPC += OPCODE_LENGTH(op_resolve_with_base);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_get_by_id) {
@@ -2165,7 +2130,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot);
callFrame->r(dst) = result;
- vPC += 8;
+ vPC += OPCODE_LENGTH(op_get_by_id);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_get_by_id_self) {
@@ -2191,7 +2156,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset));
- vPC += 8;
+ vPC += OPCODE_LENGTH(op_get_by_id_self);
NEXT_INSTRUCTION();
}
}
@@ -2223,9 +2188,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int offset = vPC[6].u.operand;
ASSERT(protoObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
+ ASSERT(baseValue.get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
callFrame->r(dst) = JSValue(protoObject->getDirectOffset(offset));
- vPC += 8;
+ vPC += OPCODE_LENGTH(op_get_by_id_proto);
NEXT_INSTRUCTION();
}
}
@@ -2238,14 +2204,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
// 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;
+ vPC += OPCODE_LENGTH(op_get_by_id_self_list);
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;
+ vPC += OPCODE_LENGTH(op_get_by_id_proto_list);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_get_by_id_chain) {
@@ -2278,9 +2244,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int offset = vPC[7].u.operand;
ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
+ ASSERT(baseValue.get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset));
- vPC += 8;
+ vPC += OPCODE_LENGTH(op_get_by_id_chain);
NEXT_INSTRUCTION();
}
@@ -2310,7 +2277,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
- vPC += 8;
+ vPC += OPCODE_LENGTH(op_get_by_id_generic);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_get_array_length) {
@@ -2326,7 +2293,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (LIKELY(isJSArray(globalData, baseValue))) {
int dst = vPC[1].u.operand;
callFrame->r(dst) = jsNumber(callFrame, asArray(baseValue)->length());
- vPC += 8;
+ vPC += OPCODE_LENGTH(op_get_array_length);
NEXT_INSTRUCTION();
}
@@ -2345,8 +2312,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue baseValue = callFrame->r(base).jsValue();
if (LIKELY(isJSString(globalData, baseValue))) {
int dst = vPC[1].u.operand;
- callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->value().size());
- vPC += 8;
+ callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->length());
+ vPC += OPCODE_LENGTH(op_get_string_length);
NEXT_INSTRUCTION();
}
@@ -2376,7 +2343,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);
- vPC += 8;
+ vPC += OPCODE_LENGTH(op_put_by_id);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_put_by_id_transition) {
@@ -2421,7 +2388,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset);
baseObject->putDirectOffset(offset, callFrame->r(value).jsValue());
- vPC += 8;
+ vPC += OPCODE_LENGTH(op_put_by_id_transition);
NEXT_INSTRUCTION();
}
}
@@ -2456,7 +2423,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset);
baseObject->putDirectOffset(offset, callFrame->r(value).jsValue());
- vPC += 8;
+ vPC += OPCODE_LENGTH(op_put_by_id_replace);
NEXT_INSTRUCTION();
}
}
@@ -2483,7 +2450,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
CHECK_FOR_EXCEPTION();
- vPC += 8;
+ vPC += OPCODE_LENGTH(op_put_by_id_generic);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_del_by_id) {
@@ -2494,16 +2461,43 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
boolean indicating success (if true) or failure (if false)
to register dst.
*/
- int dst = (++vPC)->u.operand;
- int base = (++vPC)->u.operand;
- int property = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int base = vPC[2].u.operand;
+ int property = vPC[3].u.operand;
JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame);
Identifier& ident = callFrame->codeBlock()->identifier(property);
JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, ident));
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
- ++vPC;
+ vPC += OPCODE_LENGTH(op_del_by_id);
+ NEXT_INSTRUCTION();
+ }
+ DEFINE_OPCODE(op_get_by_pname) {
+ int dst = vPC[1].u.operand;
+ int base = vPC[2].u.operand;
+ int property = vPC[3].u.operand;
+ int expected = vPC[4].u.operand;
+ int iter = vPC[5].u.operand;
+ int i = vPC[6].u.operand;
+
+ JSValue baseValue = callFrame->r(base).jsValue();
+ JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator();
+ JSValue subscript = callFrame->r(property).jsValue();
+ JSValue expectedSubscript = callFrame->r(expected).jsValue();
+ int index = callFrame->r(i).i() - 1;
+ JSValue result;
+ int offset = 0;
+ if (subscript == expectedSubscript && baseValue.isCell() && (baseValue.asCell()->structure() == it->cachedStructure()) && it->getOffset(index, offset)) {
+ callFrame->r(dst) = asObject(baseValue)->getDirectOffset(offset);
+ vPC += OPCODE_LENGTH(op_get_by_pname);
+ NEXT_INSTRUCTION();
+ }
+ Identifier propertyName(callFrame, subscript.toString(callFrame));
+ result = baseValue.get(callFrame, propertyName);
+ CHECK_FOR_EXCEPTION();
+ callFrame->r(dst) = result;
+ vPC += OPCODE_LENGTH(op_get_by_pname);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_get_by_val) {
@@ -2514,9 +2508,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
in register dst. property is nominally converted to string
but numbers are treated more efficiently.
*/
- int dst = (++vPC)->u.operand;
- int base = (++vPC)->u.operand;
- int property = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int base = vPC[2].u.operand;
+ int property = vPC[3].u.operand;
JSValue baseValue = callFrame->r(base).jsValue();
JSValue subscript = callFrame->r(property).jsValue();
@@ -2532,7 +2526,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
else
result = jsArray->JSArray::get(callFrame, i);
} else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
- result = asString(baseValue)->getIndex(&callFrame->globalData(), i);
+ result = asString(baseValue)->getIndex(callFrame, i);
else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i))
result = asByteArray(baseValue)->getIndex(callFrame, i);
else
@@ -2544,7 +2538,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
- ++vPC;
+ vPC += OPCODE_LENGTH(op_get_by_val);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_put_by_val) {
@@ -2558,9 +2552,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Unlike many opcodes, this one does not write any output to
the register file.
*/
- int base = (++vPC)->u.operand;
- int property = (++vPC)->u.operand;
- int value = (++vPC)->u.operand;
+ int base = vPC[1].u.operand;
+ int property = vPC[2].u.operand;
+ int value = vPC[3].u.operand;
JSValue baseValue = callFrame->r(base).jsValue();
JSValue subscript = callFrame->r(property).jsValue();
@@ -2594,7 +2588,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
}
CHECK_FOR_EXCEPTION();
- ++vPC;
+ vPC += OPCODE_LENGTH(op_put_by_val);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_del_by_val) {
@@ -2605,9 +2599,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
boolean indicating success (if true) or failure (if false)
to register dst.
*/
- int dst = (++vPC)->u.operand;
- int base = (++vPC)->u.operand;
- int property = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int base = vPC[2].u.operand;
+ int property = vPC[3].u.operand;
JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw
@@ -2625,7 +2619,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
- ++vPC;
+ vPC += OPCODE_LENGTH(op_del_by_val);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_put_by_index) {
@@ -2640,13 +2634,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
This opcode is mainly used to initialize array literals.
*/
- int base = (++vPC)->u.operand;
- unsigned property = (++vPC)->u.operand;
- int value = (++vPC)->u.operand;
+ int base = vPC[1].u.operand;
+ unsigned property = vPC[2].u.operand;
+ int value = vPC[3].u.operand;
callFrame->r(base).jsValue().put(callFrame, property, callFrame->r(value).jsValue());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_put_by_index);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_loop) {
@@ -2661,7 +2655,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#if ENABLE(OPCODE_STATS)
OpcodeStats::resetLastInstruction();
#endif
- int target = (++vPC)->u.operand;
+ int target = vPC[1].u.operand;
CHECK_FOR_TIMEOUT();
vPC += target;
NEXT_INSTRUCTION();
@@ -2675,7 +2669,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#if ENABLE(OPCODE_STATS)
OpcodeStats::resetLastInstruction();
#endif
- int target = (++vPC)->u.operand;
+ int target = vPC[1].u.operand;
vPC += target;
NEXT_INSTRUCTION();
@@ -2689,15 +2683,35 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Additionally this loop instruction may terminate JS execution is
the JS timeout is reached.
*/
- int cond = (++vPC)->u.operand;
- int target = (++vPC)->u.operand;
+ int cond = vPC[1].u.operand;
+ int target = vPC[2].u.operand;
if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
vPC += target;
CHECK_FOR_TIMEOUT();
NEXT_INSTRUCTION();
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_loop_if_true);
+ NEXT_INSTRUCTION();
+ }
+ DEFINE_OPCODE(op_loop_if_false) {
+ /* loop_if_true cond(r) target(offset)
+
+ Jumps to offset target from the current instruction, if and
+ only if register cond converts to boolean as false.
+
+ Additionally this loop instruction may terminate JS execution is
+ the JS timeout is reached.
+ */
+ int cond = vPC[1].u.operand;
+ int target = vPC[2].u.operand;
+ if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
+ vPC += target;
+ CHECK_FOR_TIMEOUT();
+ NEXT_INSTRUCTION();
+ }
+
+ vPC += OPCODE_LENGTH(op_loop_if_true);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_jtrue) {
@@ -2706,14 +2720,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Jumps to offset target from the current instruction, if and
only if register cond converts to boolean as true.
*/
- int cond = (++vPC)->u.operand;
- int target = (++vPC)->u.operand;
+ int cond = vPC[1].u.operand;
+ int target = vPC[2].u.operand;
if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
vPC += target;
NEXT_INSTRUCTION();
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_jtrue);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_jfalse) {
@@ -2722,14 +2736,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Jumps to offset target from the current instruction, if and
only if register cond converts to boolean as false.
*/
- int cond = (++vPC)->u.operand;
- int target = (++vPC)->u.operand;
+ int cond = vPC[1].u.operand;
+ int target = vPC[2].u.operand;
if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
vPC += target;
NEXT_INSTRUCTION();
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_jfalse);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_jeq_null) {
@@ -2738,8 +2752,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Jumps to offset target from the current instruction, if and
only if register src is null.
*/
- int src = (++vPC)->u.operand;
- int target = (++vPC)->u.operand;
+ int src = vPC[1].u.operand;
+ int target = vPC[2].u.operand;
JSValue srcValue = callFrame->r(src).jsValue();
if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
@@ -2747,7 +2761,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
NEXT_INSTRUCTION();
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_jeq_null);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_jneq_null) {
@@ -2756,16 +2770,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Jumps to offset target from the current instruction, if and
only if register src is not null.
*/
- int src = (++vPC)->u.operand;
- int target = (++vPC)->u.operand;
+ int src = vPC[1].u.operand;
+ int target = vPC[2].u.operand;
JSValue srcValue = callFrame->r(src).jsValue();
- if (!srcValue.isUndefinedOrNull() || (srcValue.isCell() && !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
+ if (!srcValue.isUndefinedOrNull() && (!srcValue.isCell() || !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
vPC += target;
NEXT_INSTRUCTION();
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_jneq_null);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_jneq_ptr) {
@@ -2774,16 +2788,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Jumps to offset target from the current instruction, if the value r is equal
to ptr, using pointer equality.
*/
- int src = (++vPC)->u.operand;
- JSValue ptr = JSValue((++vPC)->u.jsCell);
- int target = (++vPC)->u.operand;
+ int src = vPC[1].u.operand;
+ JSValue ptr = JSValue(vPC[2].u.jsCell);
+ int target = vPC[3].u.operand;
JSValue srcValue = callFrame->r(src).jsValue();
if (srcValue != ptr) {
vPC += target;
NEXT_INSTRUCTION();
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_jneq_ptr);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_loop_if_less) {
@@ -2797,9 +2811,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Additionally this loop instruction may terminate JS execution is
the JS timeout is reached.
*/
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- int target = (++vPC)->u.operand;
+ JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
+ int target = vPC[3].u.operand;
bool result = jsLess(callFrame, src1, src2);
CHECK_FOR_EXCEPTION();
@@ -2810,7 +2824,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
NEXT_INSTRUCTION();
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_loop_if_less);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_loop_if_lesseq) {
@@ -2824,9 +2838,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Additionally this loop instruction may terminate JS execution is
the JS timeout is reached.
*/
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- int target = (++vPC)->u.operand;
+ JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
+ int target = vPC[3].u.operand;
bool result = jsLessEq(callFrame, src1, src2);
CHECK_FOR_EXCEPTION();
@@ -2837,7 +2851,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
NEXT_INSTRUCTION();
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_loop_if_lesseq);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_jnless) {
@@ -2848,9 +2862,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
target from the current instruction, if and only if the
result of the comparison is false.
*/
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- int target = (++vPC)->u.operand;
+ JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
+ int target = vPC[3].u.operand;
bool result = jsLess(callFrame, src1, src2);
CHECK_FOR_EXCEPTION();
@@ -2860,7 +2874,30 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
NEXT_INSTRUCTION();
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_jnless);
+ NEXT_INSTRUCTION();
+ }
+ DEFINE_OPCODE(op_jless) {
+ /* jless src1(r) src2(r) target(offset)
+
+ Checks whether register src1 is less than register src2, as
+ with the ECMAScript '<' operator, and then jumps to offset
+ target from the current instruction, if and only if the
+ result of the comparison is true.
+ */
+ JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
+ int target = vPC[3].u.operand;
+
+ bool result = jsLess(callFrame, src1, src2);
+ CHECK_FOR_EXCEPTION();
+
+ if (result) {
+ vPC += target;
+ NEXT_INSTRUCTION();
+ }
+
+ vPC += OPCODE_LENGTH(op_jless);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_jnlesseq) {
@@ -2871,9 +2908,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
and then jumps to offset target from the current instruction,
if and only if theresult of the comparison is false.
*/
- JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
- JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
- int target = (++vPC)->u.operand;
+ JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
+ JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
+ int target = vPC[3].u.operand;
bool result = jsLessEq(callFrame, src1, src2);
CHECK_FOR_EXCEPTION();
@@ -2883,7 +2920,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
NEXT_INSTRUCTION();
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_jnlesseq);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_switch_imm) {
@@ -2895,9 +2932,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
table, and the value at jumpTable[scrutinee value] is non-zero, then
that value is used as the jump offset, otherwise defaultOffset is used.
*/
- int tableIndex = (++vPC)->u.operand;
- int defaultOffset = (++vPC)->u.operand;
- JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue();
+ int tableIndex = vPC[1].u.operand;
+ int defaultOffset = vPC[2].u.operand;
+ JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
if (scrutinee.isInt32())
vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset);
else {
@@ -2919,13 +2956,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
table, and the value at jumpTable[scrutinee value] is non-zero, then
that value is used as the jump offset, otherwise defaultOffset is used.
*/
- int tableIndex = (++vPC)->u.operand;
- int defaultOffset = (++vPC)->u.operand;
- JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue();
+ int tableIndex = vPC[1].u.operand;
+ int defaultOffset = vPC[2].u.operand;
+ JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
if (!scrutinee.isString())
vPC += defaultOffset;
else {
- UString::Rep* value = asString(scrutinee)->value().rep();
+ UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
if (value->size() != 1)
vPC += defaultOffset;
else
@@ -2942,13 +2979,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
jump table, then the value associated with the string is used as the
jump offset, otherwise defaultOffset is used.
*/
- int tableIndex = (++vPC)->u.operand;
- int defaultOffset = (++vPC)->u.operand;
- JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue();
+ int tableIndex = vPC[1].u.operand;
+ int defaultOffset = vPC[2].u.operand;
+ JSValue scrutinee = callFrame->r(vPC[3].u.operand).jsValue();
if (!scrutinee.isString())
vPC += defaultOffset;
else
- vPC += callFrame->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value().rep(), defaultOffset);
+ vPC += callFrame->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value(callFrame).rep(), defaultOffset);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_new_func) {
@@ -2959,12 +2996,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
constructor, using the rules for function declarations, and
puts the result in register dst.
*/
- int dst = (++vPC)->u.operand;
- int func = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int func = vPC[2].u.operand;
callFrame->r(dst) = JSValue(callFrame->codeBlock()->functionDecl(func)->make(callFrame, callFrame->scopeChain()));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_new_func);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_new_func_exp) {
@@ -2975,8 +3012,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
constructor, using the rules for function expressions, and
puts the result in register dst.
*/
- int dst = (++vPC)->u.operand;
- int funcIndex = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int funcIndex = vPC[2].u.operand;
FunctionExecutable* function = callFrame->codeBlock()->functionExpr(funcIndex);
JSFunction* func = function->make(callFrame, callFrame->scopeChain());
@@ -2995,7 +3032,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(dst) = JSValue(func);
- ++vPC;
+ vPC += OPCODE_LENGTH(op_new_func_exp);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_call_eval) {
@@ -3020,7 +3057,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Register* newCallFrame = callFrame->registers() + registerOffset;
Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
JSValue thisValue = argv[0].jsValue();
- JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
+ JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject;
if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
JSValue result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
@@ -3028,7 +3065,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
goto vm_throw;
callFrame->r(dst) = result;
- vPC += 5;
+ vPC += OPCODE_LENGTH(op_call_eval);
NEXT_INSTRUCTION();
}
@@ -3088,7 +3125,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#else
newCallFrame->init(0, vPC + 5, scopeChain, callFrame, dst, argCount, asObject(v));
#endif
-
Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
ArgList args(thisRegister + 1, argCount - 1);
@@ -3099,14 +3135,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue returnValue;
{
- SamplingTool::HostCallRecord callRecord(m_sampler);
+ SamplingTool::HostCallRecord callRecord(m_sampler.get());
returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
}
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = returnValue;
- vPC += 5;
+ vPC += OPCODE_LENGTH(op_call);
NEXT_INSTRUCTION();
}
@@ -3116,8 +3152,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
goto vm_throw;
}
DEFINE_OPCODE(op_load_varargs) {
- int argCountDst = (++vPC)->u.operand;
- int argsOffset = (++vPC)->u.operand;
+ int argCountDst = vPC[1].u.operand;
+ int argsOffset = vPC[2].u.operand;
JSValue arguments = callFrame->r(argsOffset).jsValue();
int32_t argCount = 0;
@@ -3189,7 +3225,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
}
CHECK_FOR_EXCEPTION();
callFrame->r(argCountDst) = Register::withInt(argCount + 1);
- ++vPC;
+ vPC += OPCODE_LENGTH(op_load_varargs);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_call_varargs) {
@@ -3246,7 +3282,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#else
newCallFrame->init(0, vPC + 5, scopeChain, callFrame, dst, argCount, asObject(v));
#endif
-
+
Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
ArgList args(thisRegister + 1, argCount - 1);
@@ -3257,14 +3293,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue returnValue;
{
- SamplingTool::HostCallRecord callRecord(m_sampler);
+ SamplingTool::HostCallRecord callRecord(m_sampler.get());
returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
}
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = returnValue;
- vPC += 5;
+ vPC += OPCODE_LENGTH(op_call_varargs);
NEXT_INSTRUCTION();
}
@@ -3286,12 +3322,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
This opcode should only be used immediately before op_ret.
*/
- int src = (++vPC)->u.operand;
+ int src = vPC[1].u.operand;
ASSERT(callFrame->codeBlock()->needsFullScopeChain());
asActivation(callFrame->r(src).jsValue())->copyRegisters(callFrame->optionalCalleeArguments());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_tear_off_activation);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_tear_off_arguments) {
@@ -3312,7 +3348,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (callFrame->optionalCalleeArguments())
callFrame->optionalCalleeArguments()->copyRegisters();
- ++vPC;
+ vPC += OPCODE_LENGTH(op_tear_off_arguments);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_ret) {
@@ -3330,22 +3366,21 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
intptr_t sourceId = callFrame->codeBlock()->source()->asID();
#endif
- int result = (++vPC)->u.operand;
+ int result = vPC[1].u.operand;
if (callFrame->codeBlock()->needsFullScopeChain())
callFrame->scopeChain()->deref();
JSValue returnValue = callFrame->r(result).jsValue();
#ifdef QT_BUILD_SCRIPT_LIB
- if (debugger) {
+ if (debugger)
debugger->functionExit(returnValue, sourceId);
- }
#endif
vPC = callFrame->returnPC();
int dst = callFrame->returnValueRegister();
callFrame = callFrame->callerFrame();
-
+
if (callFrame->hasHostCallFrameFlag())
return returnValue;
@@ -3370,7 +3405,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
for (size_t count = codeBlock->m_numVars; i < count; ++i)
callFrame->r(i) = jsUndefined();
- ++vPC;
+ vPC += OPCODE_LENGTH(op_enter);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_enter_with_activation) {
@@ -3392,12 +3427,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
for (size_t count = codeBlock->m_numVars; i < count; ++i)
callFrame->r(i) = jsUndefined();
- int dst = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable()));
callFrame->r(dst) = JSValue(activation);
callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_enter_with_activation);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_convert_this) {
@@ -3412,12 +3447,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
block.
*/
- int thisRegister = (++vPC)->u.operand;
+ int thisRegister = vPC[1].u.operand;
JSValue thisVal = callFrame->r(thisRegister).jsValue();
if (thisVal.needsThisConversion())
callFrame->r(thisRegister) = JSValue(thisVal.toThisObject(callFrame));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_convert_this);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_init_arguments) {
@@ -3431,7 +3466,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
block.
*/
callFrame->r(RegisterFile::ArgumentsRegister) = JSValue();
- ++vPC;
+ vPC += OPCODE_LENGTH(op_init_arguments);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_create_arguments) {
@@ -3447,7 +3482,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->setCalleeArguments(arguments);
callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments);
}
- ++vPC;
+ vPC += OPCODE_LENGTH(op_create_arguments);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_construct) {
@@ -3486,11 +3521,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (prototype.isObject())
structure = asObject(prototype)->inheritorID();
else
- structure = callDataScopeChain->globalObject()->emptyObjectStructure();
+ structure = callDataScopeChain->globalObject->emptyObjectStructure();
#ifdef QT_BUILD_SCRIPT_LIB
// ### world-class hack
- QT_PREPEND_NAMESPACE(QScriptObject)* newObject
- = new (globalData) QT_PREPEND_NAMESPACE(QScriptObject)(structure);
+ QT_PREPEND_NAMESPACE(QScriptObject)* newObject = new (globalData) QT_PREPEND_NAMESPACE(QScriptObject)(structure);
#else
JSObject* newObject = new (globalData) JSObject(structure);
#endif
@@ -3519,7 +3553,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ArgList args(callFrame->registers() + thisRegister + 1, argCount - 1);
ScopeChainNode* scopeChain = callFrame->scopeChain();
-
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
#ifdef QT_BUILD_SCRIPT_LIB //we need the returnValue to be 0 as it is used as flags
newCallFrame->init(0, vPC + 7, scopeChain, callFrame, 0, argCount, asObject(v));
@@ -3529,13 +3562,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSValue returnValue;
{
- SamplingTool::HostCallRecord callRecord(m_sampler);
+ SamplingTool::HostCallRecord callRecord(m_sampler.get());
returnValue = constructData.native.function(newCallFrame, asObject(v), args);
}
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = JSValue(returnValue);
- vPC += 7;
+ vPC += OPCODE_LENGTH(op_construct);
NEXT_INSTRUCTION();
}
@@ -3553,32 +3586,33 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int dst = vPC[1].u.operand;
if (LIKELY(callFrame->r(dst).jsValue().isObject())) {
- vPC += 3;
+ vPC += OPCODE_LENGTH(op_construct_verify);
NEXT_INSTRUCTION();
}
int override = vPC[2].u.operand;
callFrame->r(dst) = callFrame->r(override);
- vPC += 3;
+ vPC += OPCODE_LENGTH(op_construct_verify);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_strcat) {
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
- int count = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
+ int count = vPC[3].u.operand;
- callFrame->r(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count);
- ++vPC;
+ callFrame->r(dst) = jsString(callFrame, &callFrame->registers()[src], count);
+ CHECK_FOR_EXCEPTION();
+ vPC += OPCODE_LENGTH(op_strcat);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_to_primitive) {
- int dst = (++vPC)->u.operand;
- int src = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int src = vPC[2].u.operand;
callFrame->r(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame);
- ++vPC;
+ vPC += OPCODE_LENGTH(op_to_primitive);
NEXT_INSTRUCTION();
}
@@ -3589,7 +3623,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
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;
+ int scope = vPC[1].u.operand;
JSValue v = callFrame->r(scope).jsValue();
JSObject* o = v.toObject(callFrame);
CHECK_FOR_EXCEPTION();
@@ -3597,7 +3631,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
callFrame->r(scope) = JSValue(o);
callFrame->setScopeChain(callFrame->scopeChain()->push(o));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_push_scope);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_pop_scope) {
@@ -3607,47 +3641,69 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
callFrame->setScopeChain(callFrame->scopeChain()->pop());
- ++vPC;
+ vPC += OPCODE_LENGTH(op_pop_scope);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_get_pnames) {
- /* get_pnames dst(r) base(r)
+ /* get_pnames dst(r) base(r) i(n) size(n) breakTarget(offset)
Creates a property name list for register base and puts it
- in register dst. This is not a true JavaScript value, just
- a synthetic value used to keep the iteration state in a
- register.
+ in register dst, initializing i and size for iteration. If
+ base is undefined or null, jumps to breakTarget.
*/
- int dst = (++vPC)->u.operand;
- int base = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int base = vPC[2].u.operand;
+ int i = vPC[3].u.operand;
+ int size = vPC[4].u.operand;
+ int breakTarget = vPC[5].u.operand;
+
+ JSValue v = callFrame->r(base).jsValue();
+ if (v.isUndefinedOrNull()) {
+ vPC += breakTarget;
+ NEXT_INSTRUCTION();
+ }
- callFrame->r(dst) = JSPropertyNameIterator::create(callFrame, callFrame->r(base).jsValue());
- ++vPC;
+ JSObject* o = v.toObject(callFrame);
+ Structure* structure = o->structure();
+ JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
+ if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame))
+ jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o);
+
+ callFrame->r(dst) = jsPropertyNameIterator;
+ callFrame->r(base) = JSValue(o);
+ callFrame->r(i) = Register::withInt(0);
+ callFrame->r(size) = Register::withInt(jsPropertyNameIterator->size());
+ vPC += OPCODE_LENGTH(op_get_pnames);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_next_pname) {
- /* next_pname dst(r) iter(r) target(offset)
+ /* next_pname dst(r) base(r) i(n) size(n) iter(r) target(offset)
- Tries to copies the next name from property name list in
- register iter. If there are names left, then copies one to
- register dst, and jumps to offset target. If there are none
- left, invalidates the iterator and continues to the next
+ Copies the next name from the property name list in
+ register iter to dst, then jumps to offset target. If there are no
+ names left, invalidates the iterator and continues to the next
instruction.
*/
- int dst = (++vPC)->u.operand;
- int iter = (++vPC)->u.operand;
- int target = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int base = vPC[2].u.operand;
+ int i = vPC[3].u.operand;
+ int size = vPC[4].u.operand;
+ int iter = vPC[5].u.operand;
+ int target = vPC[6].u.operand;
JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator();
- if (JSValue temp = it->next(callFrame)) {
- CHECK_FOR_TIMEOUT();
- callFrame->r(dst) = JSValue(temp);
- vPC += target;
- NEXT_INSTRUCTION();
+ while (callFrame->r(i).i() != callFrame->r(size).i()) {
+ JSValue key = it->get(callFrame, asObject(callFrame->r(base).jsValue()), callFrame->r(i).i());
+ callFrame->r(i) = Register::withInt(callFrame->r(i).i() + 1);
+ if (key) {
+ CHECK_FOR_TIMEOUT();
+ callFrame->r(dst) = key;
+ vPC += target;
+ NEXT_INSTRUCTION();
+ }
}
- it->invalidate();
- ++vPC;
+ vPC += OPCODE_LENGTH(op_next_pname);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_jmp_scopes) {
@@ -3657,8 +3713,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
specified by immediate number count, then jumps to offset
target.
*/
- int count = (++vPC)->u.operand;
- int target = (++vPC)->u.operand;
+ int count = vPC[1].u.operand;
+ int target = vPC[2].u.operand;
ScopeChainNode* tmp = callFrame->scopeChain();
while (count--)
@@ -3681,7 +3737,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
callFrame->setScopeChain(createExceptionScope(callFrame, vPC));
- vPC += 4;
+ vPC += OPCODE_LENGTH(op_push_new_scope);
NEXT_INSTRUCTION();
}
#if HAVE(COMPUTED_GOTO)
@@ -3706,11 +3762,11 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
}
#endif
- int ex = (++vPC)->u.operand;
+ int ex = vPC[1].u.operand;
callFrame->r(ex) = exceptionValue;
exceptionValue = JSValue();
- ++vPC;
+ vPC += OPCODE_LENGTH(op_catch);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_throw) {
@@ -3724,7 +3780,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
else the script returns control to the nearest native caller.
*/
- int ex = (++vPC)->u.operand;
+ int ex = vPC[1].u.operand;
exceptionValue = callFrame->r(ex).jsValue();
handler = throwException(callFrame, exceptionValue, vPC - callFrame->codeBlock()->instructions().begin(), true);
@@ -3744,14 +3800,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
constant message as the message string. The result is
written to register dst.
*/
- int dst = (++vPC)->u.operand;
- int type = (++vPC)->u.operand;
- int message = (++vPC)->u.operand;
+ int dst = vPC[1].u.operand;
+ int type = vPC[2].u.operand;
+ int message = vPC[3].u.operand;
CodeBlock* codeBlock = callFrame->codeBlock();
callFrame->r(dst) = JSValue(Error::create(callFrame, (ErrorType)type, callFrame->r(message).jsValue().toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_new_error);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_end) {
@@ -3766,7 +3822,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT(scopeChain->refCount > 1);
scopeChain->deref();
}
- int result = (++vPC)->u.operand;
+ int result = vPC[1].u.operand;
return callFrame->r(result).jsValue();
}
DEFINE_OPCODE(op_put_getter) {
@@ -3780,9 +3836,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Unlike many opcodes, this one does not write any output to
the register file.
*/
- int base = (++vPC)->u.operand;
- int property = (++vPC)->u.operand;
- int function = (++vPC)->u.operand;
+ int base = vPC[1].u.operand;
+ int property = vPC[2].u.operand;
+ int function = vPC[3].u.operand;
ASSERT(callFrame->r(base).jsValue().isObject());
JSObject* baseObj = asObject(callFrame->r(base).jsValue());
@@ -3790,7 +3846,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT(callFrame->r(function).jsValue().isObject());
baseObj->defineGetter(callFrame, ident, asObject(callFrame->r(function).jsValue()));
- ++vPC;
+ vPC += OPCODE_LENGTH(op_put_getter);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_put_setter) {
@@ -3804,9 +3860,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Unlike many opcodes, this one does not write any output to
the register file.
*/
- int base = (++vPC)->u.operand;
- int property = (++vPC)->u.operand;
- int function = (++vPC)->u.operand;
+ int base = vPC[1].u.operand;
+ int property = vPC[2].u.operand;
+ int function = vPC[3].u.operand;
ASSERT(callFrame->r(base).jsValue().isObject());
JSObject* baseObj = asObject(callFrame->r(base).jsValue());
@@ -3814,7 +3870,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT(callFrame->r(function).jsValue().isObject());
baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()), 0);
- ++vPC;
+ vPC += OPCODE_LENGTH(op_put_setter);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_method_check) {
@@ -3827,9 +3883,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
Places the address of the next instruction into the retAddrDst
register and jumps to offset target from the current instruction.
*/
- int retAddrDst = (++vPC)->u.operand;
- int target = (++vPC)->u.operand;
- callFrame->r(retAddrDst) = vPC + 1;
+ int retAddrDst = vPC[1].u.operand;
+ int target = vPC[2].u.operand;
+ callFrame->r(retAddrDst) = vPC + OPCODE_LENGTH(op_jsr);
vPC += target;
NEXT_INSTRUCTION();
@@ -3841,24 +3897,23 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
differs from op_jmp because the target address is stored in a
register, not as an immediate.
*/
- int retAddrSrc = (++vPC)->u.operand;
+ int retAddrSrc = vPC[1].u.operand;
vPC = callFrame->r(retAddrSrc).vPC();
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_debug) {
- /* debug debugHookID(n) firstLine(n) lastLine(n) columnNumber(n)
+ /* debug debugHookID(n) firstLine(n) lastLine(n)
Notifies the debugger of the current state of execution. This opcode
is only generated while the debugger is attached.
*/
- int debugHookID = (++vPC)->u.operand;
- int firstLine = (++vPC)->u.operand;
- int lastLine = (++vPC)->u.operand;
- int column = (++vPC)->u.operand;
+ int debugHookID = vPC[1].u.operand;
+ int firstLine = vPC[2].u.operand;
+ int lastLine = vPC[3].u.operand;
- debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
+ debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
- ++vPC;
+ vPC += OPCODE_LENGTH(op_debug);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_profile_will_call) {
@@ -3872,7 +3927,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (*enabledProfilerReference)
(*enabledProfilerReference)->willExecute(callFrame, callFrame->r(function).jsValue());
- vPC += 2;
+ vPC += OPCODE_LENGTH(op_profile_will_call);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_profile_did_call) {
@@ -3886,7 +3941,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (*enabledProfilerReference)
(*enabledProfilerReference)->didExecute(callFrame, callFrame->r(function).jsValue());
- vPC += 2;
+ vPC += OPCODE_LENGTH(op_profile_did_call);
NEXT_INSTRUCTION();
}
vm_throw: {
@@ -3992,4 +4047,40 @@ CallFrame* Interpreter::findFunctionCallFrame(CallFrame* callFrame, InternalFunc
return 0;
}
+void Interpreter::enableSampler()
+{
+#if ENABLE(OPCODE_SAMPLING)
+ if (!m_sampler) {
+ m_sampler.set(new SamplingTool(this));
+ m_sampler->setup();
+ }
+#endif
+}
+void Interpreter::dumpSampleData(ExecState* exec)
+{
+#if ENABLE(OPCODE_SAMPLING)
+ if (m_sampler)
+ m_sampler->dump(exec);
+#else
+ UNUSED_PARAM(exec);
+#endif
+}
+void Interpreter::startSampling()
+{
+#if ENABLE(SAMPLING_THREAD)
+ if (!m_sampleEntryDepth)
+ SamplingThread::start();
+
+ m_sampleEntryDepth++;
+#endif
+}
+void Interpreter::stopSampling()
+{
+#if ENABLE(SAMPLING_THREAD)
+ m_sampleEntryDepth--;
+ if (!m_sampleEntryDepth)
+ SamplingThread::stop();
+#endif
+}
+
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.h
index 157e0c7..e17b055 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Interpreter.h
@@ -105,13 +105,15 @@ namespace JSC {
void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
- void setSampler(SamplingTool* sampler) { m_sampler = sampler; }
- SamplingTool* sampler() { return m_sampler; }
+ SamplingTool* sampler() { return m_sampler.get(); }
NEVER_INLINE JSValue callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset, JSValue& exceptionValue);
NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset, bool);
- NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine, int column);
+ NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
+ void dumpSampleData(ExecState* exec);
+ void startSampling();
+ void stopSampling();
private:
enum ExecutionFlag { Normal, InitializeAndReturn };
@@ -127,7 +129,6 @@ namespace JSC {
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 bool resolveBaseAndFunc(CallFrame*, Instruction*, JSValue& exceptionValue);
NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const Identifier& propertyName, const PropertySlot&);
@@ -149,7 +150,9 @@ namespace JSC {
bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
- SamplingTool* m_sampler;
+ void enableSampler();
+ int m_sampleEntryDepth;
+ OwnPtr<SamplingTool> m_sampler;
int m_reentryDepth;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Register.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Register.h
index ea1f849..3486fa7 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Register.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/Register.h
@@ -50,17 +50,18 @@ namespace JSC {
class Register : public WTF::FastAllocBase {
public:
Register();
- Register(JSValue);
+ Register(const JSValue&);
+ Register& operator=(const JSValue&);
JSValue jsValue() const;
- Register(JSActivation*);
- Register(CallFrame*);
- Register(CodeBlock*);
- Register(JSObject*);
- Register(JSPropertyNameIterator*);
- Register(ScopeChainNode*);
- Register(Instruction*);
+ Register& operator=(JSActivation*);
+ Register& operator=(CallFrame*);
+ Register& operator=(CodeBlock*);
+ Register& operator=(JSObject*);
+ Register& operator=(JSPropertyNameIterator*);
+ Register& operator=(ScopeChainNode*);
+ Register& operator=(Instruction*);
int32_t i() const;
JSActivation* activation() const;
@@ -74,12 +75,12 @@ namespace JSC {
static Register withInt(int32_t i)
{
- return Register(i);
+ Register r;
+ r.u.i = i;
+ return r;
}
private:
- Register(int32_t);
-
union {
int32_t i;
EncodedJSValue value;
@@ -97,13 +98,25 @@ namespace JSC {
ALWAYS_INLINE Register::Register()
{
#ifndef NDEBUG
- u.value = JSValue::encode(JSValue());
+ *this = JSValue();
+#endif
+ }
+
+ ALWAYS_INLINE Register::Register(const JSValue& v)
+ {
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!v.isZombie());
#endif
+ u.value = JSValue::encode(v);
}
- ALWAYS_INLINE Register::Register(JSValue v)
+ ALWAYS_INLINE Register& Register::operator=(const JSValue& v)
{
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!v.isZombie());
+#endif
u.value = JSValue::encode(v);
+ return *this;
}
ALWAYS_INLINE JSValue Register::jsValue() const
@@ -113,44 +126,46 @@ namespace JSC {
// Interpreter functions
- ALWAYS_INLINE Register::Register(JSActivation* activation)
+ ALWAYS_INLINE Register& Register::operator=(JSActivation* activation)
{
u.activation = activation;
+ return *this;
}
- ALWAYS_INLINE Register::Register(CallFrame* callFrame)
+ ALWAYS_INLINE Register& Register::operator=(CallFrame* callFrame)
{
u.callFrame = callFrame;
+ return *this;
}
- ALWAYS_INLINE Register::Register(CodeBlock* codeBlock)
+ ALWAYS_INLINE Register& Register::operator=(CodeBlock* codeBlock)
{
u.codeBlock = codeBlock;
+ return *this;
}
- ALWAYS_INLINE Register::Register(JSObject* object)
+ ALWAYS_INLINE Register& Register::operator=(JSObject* object)
{
u.object = object;
+ return *this;
}
- ALWAYS_INLINE Register::Register(Instruction* vPC)
+ ALWAYS_INLINE Register& Register::operator=(Instruction* vPC)
{
u.vPC = vPC;
+ return *this;
}
- ALWAYS_INLINE Register::Register(ScopeChainNode* scopeChain)
+ ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
{
u.scopeChain = scopeChain;
+ return *this;
}
- ALWAYS_INLINE Register::Register(JSPropertyNameIterator* propertyNameIterator)
+ ALWAYS_INLINE Register& Register::operator=(JSPropertyNameIterator* propertyNameIterator)
{
u.propertyNameIterator = propertyNameIterator;
- }
-
- ALWAYS_INLINE Register::Register(int32_t i)
- {
- u.i = i;
+ return *this;
}
ALWAYS_INLINE int32_t Register::i() const
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.cpp
index de5175e..939573b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.cpp
@@ -36,7 +36,7 @@ RegisterFile::~RegisterFile()
#if HAVE(MMAP)
munmap(reinterpret_cast<char*>(m_buffer), ((m_max - m_start) + m_maxGlobals) * sizeof(Register));
#elif HAVE(VIRTUALALLOC)
-#if PLATFORM(WINCE)
+#if OS(WINCE)
VirtualFree(m_buffer, DWORD(m_commitEnd) - DWORD(m_buffer), MEM_DECOMMIT);
#endif
VirtualFree(m_buffer, 0, MEM_RELEASE);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h
index 0eeff0e..34e2504 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h
@@ -176,7 +176,7 @@ namespace JSC {
#if HAVE(MMAP)
m_buffer = reinterpret_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, VM_TAG_FOR_REGISTERFILE_MEMORY, 0));
if (m_buffer == MAP_FAILED) {
-#if PLATFORM(WINCE)
+#if OS(WINCE)
fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
#else
fprintf(stderr, "Could not allocate register file: %d\n", errno);
@@ -186,7 +186,7 @@ namespace JSC {
#elif HAVE(VIRTUALALLOC)
m_buffer = static_cast<Register*>(VirtualAlloc(0, roundUpAllocationSize(bufferLength, commitSize), MEM_RESERVE, PAGE_READWRITE));
if (!m_buffer) {
-#if PLATFORM(WINCE)
+#if OS(WINCE)
fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
#else
fprintf(stderr, "Could not allocate register file: %d\n", errno);
@@ -196,7 +196,7 @@ namespace JSC {
size_t committedSize = roundUpAllocationSize(maxGlobals * sizeof(Register), commitSize);
void* commitCheck = VirtualAlloc(m_buffer, committedSize, MEM_COMMIT, PAGE_READWRITE);
if (commitCheck != m_buffer) {
-#if PLATFORM(WINCE)
+#if OS(WINCE)
fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
#else
fprintf(stderr, "Could not allocate register file: %d\n", errno);
@@ -242,7 +242,7 @@ namespace JSC {
if (newEnd > m_commitEnd) {
size_t size = roundUpAllocationSize(reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_commitEnd), commitSize);
if (!VirtualAlloc(m_commitEnd, size, MEM_COMMIT, PAGE_READWRITE)) {
-#if PLATFORM(WINCE)
+#if OS(WINCE)
fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
#else
fprintf(stderr, "Could not allocate register file: %d\n", errno);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocator.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocator.h
index 3274fcc..1fb8ff7 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocator.h
@@ -26,6 +26,7 @@
#ifndef ExecutableAllocator_h
#define ExecutableAllocator_h
+#include <stddef.h> // for ptrdiff_t
#include <limits>
#include <wtf/Assertions.h>
#include <wtf/PassRefPtr.h>
@@ -33,15 +34,21 @@
#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
-#if PLATFORM(IPHONE)
+#if OS(IPHONE_OS)
#include <libkern/OSCacheControl.h>
#include <sys/mman.h>
#endif
-#if PLATFORM(SYMBIAN)
+#if OS(SYMBIAN)
#include <e32std.h>
#endif
+#if OS(WINCE)
+// From pkfuncs.h (private header file from the Platform Builder)
+#define CACHE_SYNC_ALL 0x07F
+extern "C" __declspec(dllimport) void CacheRangeFlush(LPVOID pAddr, DWORD dwLength, DWORD dwFlags);
+#endif
+
#define JIT_ALLOCATOR_PAGE_SIZE (ExecutableAllocator::pageSize)
#define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (ExecutableAllocator::pageSize * 4)
@@ -78,6 +85,9 @@ private:
struct Allocation {
char* pages;
size_t size;
+#if OS(SYMBIAN)
+ RChunk* chunk;
+#endif
};
typedef Vector<Allocation, 2> AllocationList;
@@ -176,22 +186,38 @@ public:
#endif
-#if PLATFORM(X86) || PLATFORM(X86_64)
+#if CPU(X86) || CPU(X86_64)
static void cacheFlush(void*, size_t)
{
}
-#elif PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE)
+#elif CPU(ARM_THUMB2) && OS(IPHONE_OS)
static void cacheFlush(void* code, size_t size)
{
sys_dcache_flush(code, size);
sys_icache_invalidate(code, size);
}
-#elif PLATFORM(SYMBIAN)
+#elif CPU(ARM_THUMB2) && OS(LINUX)
+ static void cacheFlush(void* code, size_t size)
+ {
+ asm volatile (
+ "push {r7}\n"
+ "mov r0, %0\n"
+ "mov r1, %1\n"
+ "movw r7, #0x2\n"
+ "movt r7, #0xf\n"
+ "movs r2, #0x0\n"
+ "svc 0x0\n"
+ "pop {r7}\n"
+ :
+ : "r" (code), "r" (reinterpret_cast<char*>(code) + size)
+ : "r0", "r1", "r2");
+ }
+#elif OS(SYMBIAN)
static void cacheFlush(void* code, size_t size)
{
User::IMB_Range(code, static_cast<char*>(code) + size);
}
-#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX)
+#elif CPU(ARM_TRADITIONAL) && OS(LINUX)
static void cacheFlush(void* code, size_t size)
{
asm volatile (
@@ -205,7 +231,12 @@ public:
"pop {r7}\n"
:
: "r" (code), "r" (reinterpret_cast<char*>(code) + size)
- : "r0", "r1");
+ : "r0", "r1", "r2");
+ }
+#elif OS(WINCE)
+ static void cacheFlush(void* code, size_t size)
+ {
+ CacheRangeFlush(code, size, CACHE_SYNC_ALL);
}
#else
#error "The cacheFlush support is missing on this platform."
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
index 7682b9c..dd1db4e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
@@ -29,7 +29,7 @@
#include <errno.h>
-#if ENABLE(ASSEMBLER) && PLATFORM(MAC) && PLATFORM(X86_64)
+#if ENABLE(ASSEMBLER) && OS(DARWIN) && CPU(X86_64)
#include "TCSpinLock.h"
#include <mach/mach_init.h>
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp
index 13a8626..2eb0c87 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp
@@ -27,7 +27,7 @@
#include "ExecutableAllocator.h"
-#if ENABLE(ASSEMBLER)
+#if ENABLE(ASSEMBLER) && OS(UNIX) && !OS(SYMBIAN)
#include <sys/mman.h>
#include <unistd.h>
@@ -35,7 +35,7 @@
namespace JSC {
-#if !(PLATFORM(MAC) && PLATFORM(X86_64))
+#if !(OS(DARWIN) && !PLATFORM(QT) && CPU(X86_64))
void ExecutableAllocator::intializePageSize()
{
@@ -57,7 +57,7 @@ void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc)
ASSERT_UNUSED(result, !result);
}
-#endif // !(PLATFORM(MAC) && PLATFORM(X86_64))
+#endif // !(OS(DARWIN) && !PLATFORM(QT) && CPU(X86_64))
#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
void ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSeting setting)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp
new file mode 100644
index 0000000..e82975c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+
+#include "ExecutableAllocator.h"
+
+#if ENABLE(ASSEMBLER) && OS(SYMBIAN)
+
+#include <e32hal.h>
+#include <e32std.h>
+
+// Set the page size to 256 Kb to compensate for moving memory model limitation
+const size_t MOVING_MEM_PAGE_SIZE = 256 * 1024;
+
+namespace JSC {
+
+void ExecutableAllocator::intializePageSize()
+{
+#if CPU(ARMV5_OR_LOWER)
+ // The moving memory model (as used in ARMv5 and earlier platforms)
+ // on Symbian OS limits the number of chunks for each process to 16.
+ // To mitigate this limitation increase the pagesize to
+ // allocate less of larger chunks.
+ ExecutableAllocator::pageSize = MOVING_MEM_PAGE_SIZE;
+#else
+ TInt page_size;
+ UserHal::PageSizeInBytes(page_size);
+ ExecutableAllocator::pageSize = page_size;
+#endif
+}
+
+ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n)
+{
+ RChunk* codeChunk = new RChunk();
+
+ TInt errorCode = codeChunk->CreateLocalCode(n, n);
+
+ char* allocation = reinterpret_cast<char*>(codeChunk->Base());
+ if (!allocation)
+ CRASH();
+ ExecutablePool::Allocation alloc = { allocation, n, codeChunk };
+ return alloc;
+}
+
+void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc)
+{
+ alloc.chunk->Close();
+ delete alloc.chunk;
+}
+
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+#error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform."
+#endif
+
+}
+
+#endif // HAVE(ASSEMBLER)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorWin.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorWin.cpp
index e6ac855..e38323c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorWin.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/ExecutableAllocatorWin.cpp
@@ -27,7 +27,7 @@
#include "ExecutableAllocator.h"
-#if ENABLE(ASSEMBLER)
+#if ENABLE(ASSEMBLER) && OS(WINDOWS)
#include "windows.h"
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp
index ea8434e..c0da66d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.cpp
@@ -27,7 +27,7 @@
#include "JIT.h"
// This probably does not belong here; adding here for now as a quick Windows build fix.
-#if ENABLE(ASSEMBLER) && PLATFORM(X86) && !PLATFORM(MAC)
+#if ENABLE(ASSEMBLER) && CPU(X86) && !OS(MAC_OS_X)
#include "MacroAssembler.h"
JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse2CheckState = NotCheckedSSE2;
#endif
@@ -37,7 +37,6 @@ JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse
#include "CodeBlock.h"
#include "Interpreter.h"
#include "JITInlineMethods.h"
-#include "JITStubs.h"
#include "JITStubCall.h"
#include "JSArray.h"
#include "JSFunction.h"
@@ -202,7 +201,6 @@ void JIT::privateCompileMainPass()
DEFINE_BINARY_OP(op_less)
DEFINE_BINARY_OP(op_lesseq)
DEFINE_BINARY_OP(op_urshift)
- DEFINE_UNARY_OP(op_get_pnames)
DEFINE_UNARY_OP(op_is_boolean)
DEFINE_UNARY_OP(op_is_function)
DEFINE_UNARY_OP(op_is_number)
@@ -240,7 +238,9 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_eq_null)
DEFINE_OP(op_get_by_id)
DEFINE_OP(op_get_by_val)
+ DEFINE_OP(op_get_by_pname)
DEFINE_OP(op_get_global_var)
+ DEFINE_OP(op_get_pnames)
DEFINE_OP(op_get_scoped_var)
DEFINE_OP(op_instanceof)
DEFINE_OP(op_jeq_null)
@@ -250,6 +250,7 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_jneq_null)
DEFINE_OP(op_jneq_ptr)
DEFINE_OP(op_jnless)
+ DEFINE_OP(op_jless)
DEFINE_OP(op_jnlesseq)
DEFINE_OP(op_jsr)
DEFINE_OP(op_jtrue)
@@ -258,6 +259,7 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_loop_if_less)
DEFINE_OP(op_loop_if_lesseq)
DEFINE_OP(op_loop_if_true)
+ DEFINE_OP(op_loop_if_false)
DEFINE_OP(op_lshift)
DEFINE_OP(op_method_check)
DEFINE_OP(op_mod)
@@ -385,14 +387,17 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_eq)
DEFINE_SLOWCASE_OP(op_get_by_id)
DEFINE_SLOWCASE_OP(op_get_by_val)
+ DEFINE_SLOWCASE_OP(op_get_by_pname)
DEFINE_SLOWCASE_OP(op_instanceof)
DEFINE_SLOWCASE_OP(op_jfalse)
DEFINE_SLOWCASE_OP(op_jnless)
+ DEFINE_SLOWCASE_OP(op_jless)
DEFINE_SLOWCASE_OP(op_jnlesseq)
DEFINE_SLOWCASE_OP(op_jtrue)
DEFINE_SLOWCASE_OP(op_loop_if_less)
DEFINE_SLOWCASE_OP(op_loop_if_lesseq)
DEFINE_SLOWCASE_OP(op_loop_if_true)
+ DEFINE_SLOWCASE_OP(op_loop_if_false)
DEFINE_SLOWCASE_OP(op_lshift)
DEFINE_SLOWCASE_OP(op_method_check)
DEFINE_SLOWCASE_OP(op_mod)
@@ -489,21 +494,21 @@ JITCode JIT::privateCompile()
ASSERT(record.type == SwitchRecord::Immediate || record.type == SwitchRecord::Character);
ASSERT(record.jumpTable.simpleJumpTable->branchOffsets.size() == record.jumpTable.simpleJumpTable->ctiOffsets.size());
- record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
+ record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 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.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.simpleJumpTable->ctiDefault;
+ record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + offset]) : record.jumpTable.simpleJumpTable->ctiDefault;
}
} else {
ASSERT(record.type == SwitchRecord::String);
- record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
+ record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 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.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.stringJumpTable->ctiDefault;
+ it->second.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + offset]) : record.jumpTable.stringJumpTable->ctiDefault;
}
}
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h
index fcbc45e..8e0c9ac 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JIT.h
@@ -38,6 +38,8 @@
#define JIT_CLASS_ALIGNMENT
#endif
+#define ASSERT_JIT_OFFSET(actual, expected) ASSERT_WITH_MESSAGE(actual == expected, "JIT Offset \"%s\" should be %d, not %d.\n", #expected, static_cast<int>(actual), static_cast<int>(expected));
+
#include "CodeBlock.h"
#include "Interpreter.h"
#include "JITCode.h"
@@ -190,7 +192,7 @@ namespace JSC {
// on x86/x86-64 it is ecx for performance reasons, since the
// MacroAssembler will need to plant register swaps if it is not -
// however the code will still function correctly.
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
static const RegisterID returnValueRegister = X86Registers::eax;
static const RegisterID cachedResultRegister = X86Registers::eax;
static const RegisterID firstArgumentRegister = X86Registers::edi;
@@ -208,7 +210,7 @@ namespace JSC {
static const FPRegisterID fpRegT0 = X86Registers::xmm0;
static const FPRegisterID fpRegT1 = X86Registers::xmm1;
static const FPRegisterID fpRegT2 = X86Registers::xmm2;
-#elif PLATFORM(X86)
+#elif CPU(X86)
static const RegisterID returnValueRegister = X86Registers::eax;
static const RegisterID cachedResultRegister = X86Registers::eax;
// On x86 we always use fastcall conventions = but on
@@ -226,7 +228,7 @@ namespace JSC {
static const FPRegisterID fpRegT0 = X86Registers::xmm0;
static const FPRegisterID fpRegT1 = X86Registers::xmm1;
static const FPRegisterID fpRegT2 = X86Registers::xmm2;
-#elif PLATFORM(ARM_THUMB2)
+#elif CPU(ARM_THUMB2)
static const RegisterID returnValueRegister = ARMRegisters::r0;
static const RegisterID cachedResultRegister = ARMRegisters::r0;
static const RegisterID firstArgumentRegister = ARMRegisters::r0;
@@ -242,14 +244,13 @@ namespace JSC {
static const FPRegisterID fpRegT0 = ARMRegisters::d0;
static const FPRegisterID fpRegT1 = ARMRegisters::d1;
static const FPRegisterID fpRegT2 = ARMRegisters::d2;
-#elif PLATFORM(ARM_TRADITIONAL)
+#elif CPU(ARM_TRADITIONAL)
static const RegisterID returnValueRegister = ARMRegisters::r0;
static const RegisterID cachedResultRegister = ARMRegisters::r0;
static const RegisterID firstArgumentRegister = ARMRegisters::r0;
static const RegisterID timeoutCheckRegister = ARMRegisters::r5;
static const RegisterID callFrameRegister = ARMRegisters::r4;
- static const RegisterID ctiReturnRegister = ARMRegisters::r6;
static const RegisterID regT0 = ARMRegisters::r0;
static const RegisterID regT1 = ARMRegisters::r1;
@@ -386,6 +387,8 @@ namespace JSC {
Address addressFor(unsigned index, RegisterID base = callFrameRegister);
+ void testPrototype(Structure*, JumpList& failureCases);
+
#if USE(JSVALUE32_64)
Address tagFor(unsigned index, RegisterID base = callFrameRegister);
Address payloadFor(unsigned index, RegisterID base = callFrameRegister);
@@ -425,6 +428,7 @@ namespace JSC {
#endif
void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset);
void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset);
+ void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset);
void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset);
// Arithmetic opcode helpers
@@ -432,7 +436,7 @@ namespace JSC {
void emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType);
void emitBinaryDoubleOp(OpcodeID, unsigned dst, unsigned op1, unsigned op2, OperandTypes, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters = true, bool op2IsInRegisters = true);
-#if PLATFORM(X86)
+#if CPU(X86)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 7;
static const int patchOffsetPutByIdExternalLoad = 13;
@@ -461,6 +465,47 @@ namespace JSC {
static const int patchOffsetMethodCheckProtoObj = 11;
static const int patchOffsetMethodCheckProtoStruct = 18;
static const int patchOffsetMethodCheckPutFunction = 29;
+#elif CPU(ARM_TRADITIONAL)
+ // These architecture specific value are used to enable patching - see comment on op_put_by_id.
+ static const int patchOffsetPutByIdStructure = 4;
+ static const int patchOffsetPutByIdExternalLoad = 16;
+ static const int patchLengthPutByIdExternalLoad = 4;
+ static const int patchOffsetPutByIdPropertyMapOffset1 = 20;
+ static const int patchOffsetPutByIdPropertyMapOffset2 = 28;
+ // These architecture specific value are used to enable patching - see comment on op_get_by_id.
+ static const int patchOffsetGetByIdStructure = 4;
+ static const int patchOffsetGetByIdBranchToSlowCase = 16;
+ static const int patchOffsetGetByIdExternalLoad = 16;
+ static const int patchLengthGetByIdExternalLoad = 4;
+ static const int patchOffsetGetByIdPropertyMapOffset1 = 20;
+ static const int patchOffsetGetByIdPropertyMapOffset2 = 28;
+ static const int patchOffsetGetByIdPutResult = 36;
+#if ENABLE(OPCODE_SAMPLING)
+ #error "OPCODE_SAMPLING is not yet supported"
+#else
+ static const int patchOffsetGetByIdSlowCaseCall = 32;
+#endif
+ static const int patchOffsetOpCallCompareToJump = 12;
+
+ static const int patchOffsetMethodCheckProtoObj = 12;
+ static const int patchOffsetMethodCheckProtoStruct = 20;
+ static const int patchOffsetMethodCheckPutFunction = 32;
+
+ // sequenceOpCall
+ static const int sequenceOpCallInstructionSpace = 12;
+ static const int sequenceOpCallConstantSpace = 2;
+ // sequenceMethodCheck
+ static const int sequenceMethodCheckInstructionSpace = 40;
+ static const int sequenceMethodCheckConstantSpace = 6;
+ // sequenceGetByIdHotPath
+ static const int sequenceGetByIdHotPathInstructionSpace = 36;
+ static const int sequenceGetByIdHotPathConstantSpace = 4;
+ // sequenceGetByIdSlowCase
+ static const int sequenceGetByIdSlowCaseInstructionSpace = 40;
+ static const int sequenceGetByIdSlowCaseConstantSpace = 2;
+ // sequencePutById
+ static const int sequencePutByIdInstructionSpace = 36;
+ static const int sequencePutByIdConstantSpace = 4;
#else
#error "JSVALUE32_64 not supported on this platform."
#endif
@@ -526,9 +571,10 @@ namespace JSC {
#endif
void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset);
void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset);
+ void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch);
void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 10;
static const int patchOffsetPutByIdExternalLoad = 20;
@@ -542,7 +588,7 @@ namespace JSC {
static const int patchOffsetGetByIdPropertyMapOffset = 31;
static const int patchOffsetGetByIdPutResult = 31;
#if ENABLE(OPCODE_SAMPLING)
- static const int patchOffsetGetByIdSlowCaseCall = 63;
+ static const int patchOffsetGetByIdSlowCaseCall = 64;
#else
static const int patchOffsetGetByIdSlowCaseCall = 41;
#endif
@@ -551,7 +597,7 @@ namespace JSC {
static const int patchOffsetMethodCheckProtoObj = 20;
static const int patchOffsetMethodCheckProtoStruct = 30;
static const int patchOffsetMethodCheckPutFunction = 50;
-#elif PLATFORM(X86)
+#elif CPU(X86)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 7;
static const int patchOffsetPutByIdExternalLoad = 13;
@@ -578,30 +624,30 @@ namespace JSC {
static const int patchOffsetMethodCheckProtoObj = 11;
static const int patchOffsetMethodCheckProtoStruct = 18;
static const int patchOffsetMethodCheckPutFunction = 29;
-#elif PLATFORM(ARM_THUMB2)
+#elif CPU(ARM_THUMB2)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 10;
- static const int patchOffsetPutByIdExternalLoad = 20;
+ static const int patchOffsetPutByIdExternalLoad = 26;
static const int patchLengthPutByIdExternalLoad = 12;
- static const int patchOffsetPutByIdPropertyMapOffset = 40;
+ static const int patchOffsetPutByIdPropertyMapOffset = 46;
// These architecture specific value are used to enable patching - see comment on op_get_by_id.
static const int patchOffsetGetByIdStructure = 10;
- static const int patchOffsetGetByIdBranchToSlowCase = 20;
- static const int patchOffsetGetByIdExternalLoad = 20;
+ static const int patchOffsetGetByIdBranchToSlowCase = 26;
+ static const int patchOffsetGetByIdExternalLoad = 26;
static const int patchLengthGetByIdExternalLoad = 12;
- static const int patchOffsetGetByIdPropertyMapOffset = 40;
- static const int patchOffsetGetByIdPutResult = 44;
+ static const int patchOffsetGetByIdPropertyMapOffset = 46;
+ static const int patchOffsetGetByIdPutResult = 50;
#if ENABLE(OPCODE_SAMPLING)
static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE
#else
static const int patchOffsetGetByIdSlowCaseCall = 28;
#endif
- static const int patchOffsetOpCallCompareToJump = 10;
+ static const int patchOffsetOpCallCompareToJump = 16;
- static const int patchOffsetMethodCheckProtoObj = 18;
- static const int patchOffsetMethodCheckProtoStruct = 28;
- static const int patchOffsetMethodCheckPutFunction = 46;
-#elif PLATFORM(ARM_TRADITIONAL)
+ static const int patchOffsetMethodCheckProtoObj = 24;
+ static const int patchOffsetMethodCheckProtoStruct = 34;
+ static const int patchOffsetMethodCheckPutFunction = 58;
+#elif CPU(ARM_TRADITIONAL)
// These architecture specific value are used to enable patching - see comment on op_put_by_id.
static const int patchOffsetPutByIdStructure = 4;
static const int patchOffsetPutByIdExternalLoad = 16;
@@ -617,17 +663,14 @@ namespace JSC {
#if ENABLE(OPCODE_SAMPLING)
#error "OPCODE_SAMPLING is not yet supported"
#else
- static const int patchOffsetGetByIdSlowCaseCall = 36;
+ static const int patchOffsetGetByIdSlowCaseCall = 28;
#endif
static const int patchOffsetOpCallCompareToJump = 12;
static const int patchOffsetMethodCheckProtoObj = 12;
static const int patchOffsetMethodCheckProtoStruct = 20;
static const int patchOffsetMethodCheckPutFunction = 32;
-#endif
-#endif // USE(JSVALUE32_64)
-#if PLATFORM(ARM_TRADITIONAL)
// sequenceOpCall
static const int sequenceOpCallInstructionSpace = 12;
static const int sequenceOpCallConstantSpace = 2;
@@ -638,12 +681,13 @@ namespace JSC {
static const int sequenceGetByIdHotPathInstructionSpace = 28;
static const int sequenceGetByIdHotPathConstantSpace = 3;
// sequenceGetByIdSlowCase
- static const int sequenceGetByIdSlowCaseInstructionSpace = 40;
+ static const int sequenceGetByIdSlowCaseInstructionSpace = 32;
static const int sequenceGetByIdSlowCaseConstantSpace = 2;
// sequencePutById
static const int sequencePutByIdInstructionSpace = 28;
static const int sequencePutByIdConstantSpace = 3;
#endif
+#endif // USE(JSVALUE32_64)
#if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL
#define BEGIN_UNINTERRUPTED_SEQUENCE(name) beginUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace)
@@ -680,6 +724,7 @@ namespace JSC {
void emit_op_eq_null(Instruction*);
void emit_op_get_by_id(Instruction*);
void emit_op_get_by_val(Instruction*);
+ void emit_op_get_by_pname(Instruction*);
void emit_op_get_global_var(Instruction*);
void emit_op_get_scoped_var(Instruction*);
void emit_op_init_arguments(Instruction*);
@@ -691,6 +736,7 @@ namespace JSC {
void emit_op_jneq_null(Instruction*);
void emit_op_jneq_ptr(Instruction*);
void emit_op_jnless(Instruction*);
+ void emit_op_jless(Instruction*);
void emit_op_jnlesseq(Instruction*);
void emit_op_jsr(Instruction*);
void emit_op_jtrue(Instruction*);
@@ -699,6 +745,7 @@ namespace JSC {
void emit_op_loop_if_less(Instruction*);
void emit_op_loop_if_lesseq(Instruction*);
void emit_op_loop_if_true(Instruction*);
+ void emit_op_loop_if_false(Instruction*);
void emit_op_lshift(Instruction*);
void emit_op_method_check(Instruction*);
void emit_op_mod(Instruction*);
@@ -713,6 +760,7 @@ namespace JSC {
void emit_op_new_func_exp(Instruction*);
void emit_op_new_object(Instruction*);
void emit_op_new_regexp(Instruction*);
+ void emit_op_get_pnames(Instruction*);
void emit_op_next_pname(Instruction*);
void emit_op_not(Instruction*);
void emit_op_nstricteq(Instruction*);
@@ -768,14 +816,17 @@ namespace JSC {
void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_get_by_pname(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_loop_if_lesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_loop_if_true(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_loop_if_false(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_lshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -903,6 +954,46 @@ namespace JSC {
#endif
#endif
} JIT_CLASS_ALIGNMENT;
+
+ inline void JIT::emit_op_loop(Instruction* currentInstruction)
+ {
+ emitTimeoutCheck();
+ emit_op_jmp(currentInstruction);
+ }
+
+ inline void JIT::emit_op_loop_if_true(Instruction* currentInstruction)
+ {
+ emitTimeoutCheck();
+ emit_op_jtrue(currentInstruction);
+ }
+
+ inline void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+ {
+ emitSlow_op_jtrue(currentInstruction, iter);
+ }
+
+ inline void JIT::emit_op_loop_if_false(Instruction* currentInstruction)
+ {
+ emitTimeoutCheck();
+ emit_op_jfalse(currentInstruction);
+ }
+
+ inline void JIT::emitSlow_op_loop_if_false(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+ {
+ emitSlow_op_jfalse(currentInstruction, iter);
+ }
+
+ inline void JIT::emit_op_loop_if_less(Instruction* currentInstruction)
+ {
+ emitTimeoutCheck();
+ emit_op_jless(currentInstruction);
+ }
+
+ inline void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+ {
+ emitSlow_op_jless(currentInstruction, iter);
+ }
+
} // namespace JSC
#endif // ENABLE(JIT)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp
index 7afc1f2..feee8d2 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITArithmetic.cpp
@@ -98,16 +98,16 @@ void JIT::emit_op_jnless(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1)) {
emitLoad(op2, regT3, regT2);
notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
- addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target + 3);
+ addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
} else if (isOperandConstantImmediateInt(op2)) {
emitLoad(op1, regT1, regT0);
notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3);
+ addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
} else {
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
- addJump(branch32(GreaterThanOrEqual, regT0, regT2), target + 3);
+ addJump(branch32(GreaterThanOrEqual, regT0, regT2), target);
}
if (!supportsFloatingPoint()) {
@@ -145,7 +145,70 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
stubCall.addArgument(op1);
stubCall.addArgument(op2);
stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target);
+}
+
+void JIT::emit_op_jless(Instruction* currentInstruction)
+{
+ unsigned op1 = currentInstruction[1].u.operand;
+ unsigned op2 = currentInstruction[2].u.operand;
+ unsigned target = currentInstruction[3].u.operand;
+
+ JumpList notInt32Op1;
+ JumpList notInt32Op2;
+
+ // Int32 less.
+ if (isOperandConstantImmediateInt(op1)) {
+ emitLoad(op2, regT3, regT2);
+ notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addJump(branch32(GreaterThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
+ } else if (isOperandConstantImmediateInt(op2)) {
+ emitLoad(op1, regT1, regT0);
+ notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
+ } else {
+ emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+ notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+ addJump(branch32(LessThan, regT0, regT2), target);
+ }
+
+ if (!supportsFloatingPoint()) {
+ addSlowCase(notInt32Op1);
+ addSlowCase(notInt32Op2);
+ return;
+ }
+ Jump end = jump();
+
+ // Double less.
+ emitBinaryDoubleOp(op_jless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));
+ end.link(this);
+}
+
+void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned op1 = currentInstruction[1].u.operand;
+ unsigned op2 = currentInstruction[2].u.operand;
+ unsigned target = currentInstruction[3].u.operand;
+
+ if (!supportsFloatingPoint()) {
+ if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
+ linkSlowCase(iter); // int32 check
+ linkSlowCase(iter); // int32 check
+ } else {
+ if (!isOperandConstantImmediateInt(op1)) {
+ linkSlowCase(iter); // double check
+ linkSlowCase(iter); // int32 check
+ }
+ if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2))
+ linkSlowCase(iter); // double check
+ }
+
+ JITStubCall stubCall(this, cti_op_jless);
+ stubCall.addArgument(op1);
+ stubCall.addArgument(op2);
+ stubCall.call();
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
}
void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
@@ -161,16 +224,16 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1)) {
emitLoad(op2, regT3, regT2);
notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
- addJump(branch32(LessThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target + 3);
+ addJump(branch32(LessThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
} else if (isOperandConstantImmediateInt(op2)) {
emitLoad(op1, regT1, regT0);
notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3);
+ addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
} else {
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
- addJump(branch32(GreaterThan, regT0, regT2), target + 3);
+ addJump(branch32(GreaterThan, regT0, regT2), target);
}
if (!supportsFloatingPoint()) {
@@ -208,7 +271,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
stubCall.addArgument(op1);
stubCall.addArgument(op2);
stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target);
}
// LeftShift (<<)
@@ -829,11 +892,15 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi
break;
case op_jnless:
emitLoadDouble(op1, fpRegT2);
- addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT2), dst + 3);
+ addJump(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT0, fpRegT2), dst);
+ break;
+ case op_jless:
+ emitLoadDouble(op1, fpRegT2);
+ addJump(branchDouble(DoubleLessThan, fpRegT2, fpRegT0), dst);
break;
case op_jnlesseq:
emitLoadDouble(op1, fpRegT2);
- addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT2), dst + 3);
+ addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT0, fpRegT2), dst);
break;
default:
ASSERT_NOT_REACHED();
@@ -882,11 +949,15 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsi
break;
case op_jnless:
emitLoadDouble(op2, fpRegT1);
- addJump(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), dst + 3);
+ addJump(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), dst);
+ break;
+ case op_jless:
+ emitLoadDouble(op2, fpRegT1);
+ addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), dst);
break;
case op_jnlesseq:
emitLoadDouble(op2, fpRegT1);
- addJump(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), dst + 3);
+ addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), dst);
break;
default:
ASSERT_NOT_REACHED();
@@ -1000,20 +1071,11 @@ void JIT::emit_op_div(Instruction* currentInstruction)
divDouble(fpRegT1, fpRegT0);
JumpList doubleResult;
- if (!isOperandConstantImmediateInt(op1) || getConstantOperand(op1).asInt32() > 1) {
- m_assembler.cvttsd2si_rr(fpRegT0, regT0);
- convertInt32ToDouble(regT0, fpRegT1);
- m_assembler.ucomisd_rr(fpRegT1, fpRegT0);
-
- doubleResult.append(m_assembler.jne());
- doubleResult.append(m_assembler.jp());
-
- doubleResult.append(branchTest32(Zero, regT0));
+ branchConvertDoubleToInt32(fpRegT0, regT0, doubleResult, fpRegT1);
- // Int32 result.
- emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
- end.append(jump());
- }
+ // Int32 result.
+ emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+ end.append(jump());
// Double result.
doubleResult.link(this);
@@ -1054,7 +1116,7 @@ void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry>
/* ------------------------------ BEGIN: OP_MOD ------------------------------ */
-#if PLATFORM(X86) || PLATFORM(X86_64)
+#if CPU(X86) || CPU(X86_64)
void JIT::emit_op_mod(Instruction* currentInstruction)
{
@@ -1116,7 +1178,7 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>
stubCall.call(dst);
}
-#else // PLATFORM(X86) || PLATFORM(X86_64)
+#else // CPU(X86) || CPU(X86_64)
void JIT::emit_op_mod(Instruction* currentInstruction)
{
@@ -1134,7 +1196,7 @@ void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&)
{
}
-#endif // PLATFORM(X86) || PLATFORM(X86_64)
+#endif // CPU(X86) || CPU(X86_64)
/* ------------------------------ END: OP_MOD ------------------------------ */
@@ -1152,13 +1214,8 @@ void JIT::emit_op_lshift(Instruction* currentInstruction)
emitJumpSlowCaseIfNotImmediateInteger(regT2);
emitFastArithImmToInt(regT0);
emitFastArithImmToInt(regT2);
-#if !PLATFORM(X86)
- // Mask with 0x1f as per ecma-262 11.7.2 step 7.
- // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
- and32(Imm32(0x1f), regT2);
-#endif
lshift32(regT2, regT0);
-#if !USE(JSVALUE64)
+#if USE(JSVALUE32)
addSlowCase(branchAdd32(Overflow, regT0, regT0));
signExtend32ToPtr(regT0, regT0);
#endif
@@ -1203,11 +1260,7 @@ void JIT::emit_op_rshift(Instruction* currentInstruction)
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
// Mask with 0x1f as per ecma-262 11.7.2 step 7.
-#if USE(JSVALUE64)
rshift32(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), regT0);
-#else
- rshiftPtr(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), regT0);
-#endif
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT2);
if (supportsFloatingPointTruncate()) {
@@ -1234,15 +1287,9 @@ void JIT::emit_op_rshift(Instruction* currentInstruction)
emitJumpSlowCaseIfNotImmediateInteger(regT2);
}
emitFastArithImmToInt(regT2);
-#if !PLATFORM(X86)
- // Mask with 0x1f as per ecma-262 11.7.2 step 7.
- // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
- and32(Imm32(0x1f), regT2);
-#endif
-#if USE(JSVALUE64)
rshift32(regT2, regT0);
-#else
- rshiftPtr(regT2, regT0);
+#if USE(JSVALUE32)
+ signExtend32ToPtr(regT0, regT0);
#endif
}
#if USE(JSVALUE64)
@@ -1313,7 +1360,7 @@ void JIT::emit_op_jnless(Instruction* currentInstruction)
#else
int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
#endif
- addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target + 3);
+ addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target);
} else if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
@@ -1322,13 +1369,13 @@ void JIT::emit_op_jnless(Instruction* currentInstruction)
#else
int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
#endif
- addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target + 3);
+ addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
- addJump(branch32(GreaterThanOrEqual, regT0, regT1), target + 3);
+ addJump(branch32(GreaterThanOrEqual, regT0, regT1), target);
}
}
@@ -1365,7 +1412,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
move(Imm32(op2imm), regT1);
convertInt32ToDouble(regT1, fpRegT1);
- emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3);
+ emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
@@ -1382,7 +1429,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
stubCall.addArgument(regT0);
stubCall.addArgument(op2, regT2);
stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target);
} else if (isOperandConstantImmediateInt(op1)) {
linkSlowCase(iter);
@@ -1406,7 +1453,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
move(Imm32(op1imm), regT0);
convertInt32ToDouble(regT0, fpRegT0);
- emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3);
+ emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
@@ -1423,7 +1470,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
stubCall.addArgument(op1, regT2);
stubCall.addArgument(regT1);
stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target);
} else {
linkSlowCase(iter);
@@ -1452,7 +1499,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
#endif
- emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3);
+ emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
@@ -1475,7 +1522,192 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
stubCall.addArgument(regT0);
stubCall.addArgument(regT1);
stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target);
+ }
+}
+
+void JIT::emit_op_jless(Instruction* currentInstruction)
+{
+ unsigned op1 = currentInstruction[1].u.operand;
+ unsigned op2 = currentInstruction[2].u.operand;
+ unsigned target = currentInstruction[3].u.operand;
+
+ // We generate inline code for the following cases in the fast path:
+ // - int immediate to constant int immediate
+ // - constant int immediate to int immediate
+ // - int immediate to int immediate
+
+ if (isOperandConstantImmediateInt(op2)) {
+ emitGetVirtualRegister(op1, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+ int32_t op2imm = getConstantOperandImmediateInt(op2);
+#else
+ int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
+#endif
+ addJump(branch32(LessThan, regT0, Imm32(op2imm)), target);
+ } else if (isOperandConstantImmediateInt(op1)) {
+ emitGetVirtualRegister(op2, regT1);
+ emitJumpSlowCaseIfNotImmediateInteger(regT1);
+#if USE(JSVALUE64)
+ int32_t op1imm = getConstantOperandImmediateInt(op1);
+#else
+ int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
+#endif
+ addJump(branch32(GreaterThan, regT1, Imm32(op1imm)), target);
+ } else {
+ emitGetVirtualRegisters(op1, regT0, op2, regT1);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT1);
+
+ addJump(branch32(LessThan, regT0, regT1), target);
+ }
+}
+
+void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned op1 = currentInstruction[1].u.operand;
+ unsigned op2 = currentInstruction[2].u.operand;
+ unsigned target = currentInstruction[3].u.operand;
+
+ // We generate inline code for the following cases in the slow path:
+ // - floating-point number to constant int immediate
+ // - constant int immediate to floating-point number
+ // - floating-point number to floating-point number.
+
+ if (isOperandConstantImmediateInt(op2)) {
+ linkSlowCase(iter);
+
+ if (supportsFloatingPoint()) {
+#if USE(JSVALUE64)
+ Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
+ addPtr(tagTypeNumberRegister, regT0);
+ movePtrToDouble(regT0, fpRegT0);
+#else
+ Jump fail1;
+ if (!m_codeBlock->isKnownNotImmediate(op1))
+ fail1 = emitJumpIfNotJSCell(regT0);
+
+ Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
+ loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
+#endif
+
+ int32_t op2imm = getConstantOperand(op2).asInt32();
+
+ move(Imm32(op2imm), regT1);
+ convertInt32ToDouble(regT1, fpRegT1);
+
+ emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
+
+ emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
+
+#if USE(JSVALUE64)
+ fail1.link(this);
+#else
+ if (!m_codeBlock->isKnownNotImmediate(op1))
+ fail1.link(this);
+ fail2.link(this);
+#endif
+ }
+
+ JITStubCall stubCall(this, cti_op_jless);
+ stubCall.addArgument(regT0);
+ stubCall.addArgument(op2, regT2);
+ stubCall.call();
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
+
+ } else if (isOperandConstantImmediateInt(op1)) {
+ linkSlowCase(iter);
+
+ if (supportsFloatingPoint()) {
+#if USE(JSVALUE64)
+ Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
+ addPtr(tagTypeNumberRegister, regT1);
+ movePtrToDouble(regT1, fpRegT1);
+#else
+ Jump fail1;
+ if (!m_codeBlock->isKnownNotImmediate(op2))
+ fail1 = emitJumpIfNotJSCell(regT1);
+
+ Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
+ loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
+#endif
+
+ int32_t op1imm = getConstantOperand(op1).asInt32();
+
+ move(Imm32(op1imm), regT0);
+ convertInt32ToDouble(regT0, fpRegT0);
+
+ emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
+
+ emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
+
+#if USE(JSVALUE64)
+ fail1.link(this);
+#else
+ if (!m_codeBlock->isKnownNotImmediate(op2))
+ fail1.link(this);
+ fail2.link(this);
+#endif
+ }
+
+ JITStubCall stubCall(this, cti_op_jless);
+ stubCall.addArgument(op1, regT2);
+ stubCall.addArgument(regT1);
+ stubCall.call();
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
+
+ } else {
+ linkSlowCase(iter);
+
+ if (supportsFloatingPoint()) {
+#if USE(JSVALUE64)
+ Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
+ Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
+ Jump fail3 = emitJumpIfImmediateInteger(regT1);
+ addPtr(tagTypeNumberRegister, regT0);
+ addPtr(tagTypeNumberRegister, regT1);
+ movePtrToDouble(regT0, fpRegT0);
+ movePtrToDouble(regT1, fpRegT1);
+#else
+ Jump fail1;
+ if (!m_codeBlock->isKnownNotImmediate(op1))
+ fail1 = emitJumpIfNotJSCell(regT0);
+
+ Jump fail2;
+ if (!m_codeBlock->isKnownNotImmediate(op2))
+ fail2 = emitJumpIfNotJSCell(regT1);
+
+ Jump fail3 = checkStructure(regT0, m_globalData->numberStructure.get());
+ Jump fail4 = checkStructure(regT1, m_globalData->numberStructure.get());
+ loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
+ loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
+#endif
+
+ emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
+
+ emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
+
+#if USE(JSVALUE64)
+ fail1.link(this);
+ fail2.link(this);
+ fail3.link(this);
+#else
+ if (!m_codeBlock->isKnownNotImmediate(op1))
+ fail1.link(this);
+ if (!m_codeBlock->isKnownNotImmediate(op2))
+ fail2.link(this);
+ fail3.link(this);
+ fail4.link(this);
+#endif
+ }
+
+ linkSlowCase(iter);
+ JITStubCall stubCall(this, cti_op_jless);
+ stubCall.addArgument(regT0);
+ stubCall.addArgument(regT1);
+ stubCall.call();
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
}
}
@@ -1498,7 +1730,7 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
#else
int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
#endif
- addJump(branch32(GreaterThan, regT0, Imm32(op2imm)), target + 3);
+ addJump(branch32(GreaterThan, regT0, Imm32(op2imm)), target);
} else if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
@@ -1507,13 +1739,13 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
#else
int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
#endif
- addJump(branch32(LessThan, regT1, Imm32(op1imm)), target + 3);
+ addJump(branch32(LessThan, regT1, Imm32(op1imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
- addJump(branch32(GreaterThan, regT0, regT1), target + 3);
+ addJump(branch32(GreaterThan, regT0, regT1), target);
}
}
@@ -1550,7 +1782,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
move(Imm32(op2imm), regT1);
convertInt32ToDouble(regT1, fpRegT1);
- emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3);
+ emitJumpSlowToHot(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
@@ -1567,7 +1799,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
stubCall.addArgument(regT0);
stubCall.addArgument(op2, regT2);
stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target);
} else if (isOperandConstantImmediateInt(op1)) {
linkSlowCase(iter);
@@ -1591,7 +1823,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
move(Imm32(op1imm), regT0);
convertInt32ToDouble(regT0, fpRegT0);
- emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3);
+ emitJumpSlowToHot(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
@@ -1608,7 +1840,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
stubCall.addArgument(op1, regT2);
stubCall.addArgument(regT1);
stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target);
} else {
linkSlowCase(iter);
@@ -1637,7 +1869,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
#endif
- emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3);
+ emitJumpSlowToHot(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
@@ -1660,7 +1892,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
stubCall.addArgument(regT0);
stubCall.addArgument(regT1);
stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target);
}
}
@@ -1849,7 +2081,7 @@ void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEn
/* ------------------------------ BEGIN: OP_MOD ------------------------------ */
-#if PLATFORM(X86) || PLATFORM(X86_64)
+#if CPU(X86) || CPU(X86_64)
void JIT::emit_op_mod(Instruction* currentInstruction)
{
@@ -1898,7 +2130,7 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>
stubCall.call(result);
}
-#else // PLATFORM(X86) || PLATFORM(X86_64)
+#else // CPU(X86) || CPU(X86_64)
void JIT::emit_op_mod(Instruction* currentInstruction)
{
@@ -1917,7 +2149,7 @@ void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&)
ASSERT_NOT_REACHED();
}
-#endif // PLATFORM(X86) || PLATFORM(X86_64)
+#endif // CPU(X86) || CPU(X86_64)
/* ------------------------------ END: OP_MOD ------------------------------ */
@@ -2160,27 +2392,10 @@ void JIT::emit_op_div(Instruction* currentInstruction)
}
divDouble(fpRegT1, fpRegT0);
- JumpList doubleResult;
- Jump end;
- bool attemptIntConversion = (!isOperandConstantImmediateInt(op1) || getConstantOperand(op1).asInt32() > 1) && isOperandConstantImmediateInt(op2);
- if (attemptIntConversion) {
- m_assembler.cvttsd2si_rr(fpRegT0, regT0);
- doubleResult.append(branchTest32(Zero, regT0));
- m_assembler.ucomisd_rr(fpRegT1, fpRegT0);
-
- doubleResult.append(m_assembler.jne());
- doubleResult.append(m_assembler.jp());
- emitFastArithIntToImmNoCheck(regT0, regT0);
- end = jump();
- }
-
// Double result.
- doubleResult.link(this);
moveDoubleToPtr(fpRegT0, regT0);
subPtr(tagTypeNumberRegister, regT0);
- if (attemptIntConversion)
- end.link(this);
emitPutVirtualRegister(dst, regT0);
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp
index f4f6e62..07253e1 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITCall.cpp
@@ -249,10 +249,10 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
stubCall.addArgument(JIT::Imm32(registerOffset));
stubCall.addArgument(JIT::Imm32(argCount));
stubCall.call();
- wasEval = branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag));
+ wasEval = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag));
}
- emitLoad(callee, regT1, regT2);
+ emitLoad(callee, regT1, regT0);
if (opcodeID == op_call)
compileOpCallSetupArgs(instruction);
@@ -260,12 +260,12 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
compileOpConstructSetupArgs(instruction);
emitJumpSlowCaseIfNotJSCell(callee, regT1);
- addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr)));
+ addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr)));
// First, in the case of a construct, allocate the new object.
if (opcodeID == op_construct) {
JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
- emitLoad(callee, regT1, regT2);
+ emitLoad(callee, regT1, regT0);
}
// Speculatively roll the callframe, assuming argCount will match the arity.
@@ -278,7 +278,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
if (opcodeID == op_call_eval)
wasEval.link(this);
- emitStore(dst, regT1, regT0);;
+ emitStore(dst, regT1, regT0);
sampleCodeBlock(m_codeBlock);
}
@@ -321,7 +321,13 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
emitLoad(callee, regT1, regT0);
DataLabelPtr addressOfLinkedFunctionCheck;
+
+ BEGIN_UNINTERRUPTED_SEQUENCE(sequenceOpCall);
+
Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, ImmPtr(0));
+
+ END_UNINTERRUPTED_SEQUENCE(sequenceOpCall);
+
addSlowCase(jumpToSlow);
ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump);
m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
@@ -620,7 +626,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
END_UNINTERRUPTED_SEQUENCE(sequenceOpCall);
addSlowCase(jumpToSlow);
- ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump);
+ ASSERT_JIT_OFFSET(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow), patchOffsetOpCallCompareToJump);
m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
// The following is the fast case, only used whan a callee can be linked.
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h
index f26457a..5af7565 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITInlineMethods.h
@@ -37,7 +37,7 @@ namespace JSC {
// puts an arg onto the stack, as an arg to a context threaded function.
ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID src, unsigned argumentNumber)
{
- unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1;
+ unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + JITSTACKFRAME_ARGS_INDEX;
poke(src, argumentStackOffset);
}
@@ -45,7 +45,7 @@ ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID src, unsigned argumentNumbe
ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(unsigned value, unsigned argumentNumber)
{
- unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1;
+ unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + JITSTACKFRAME_ARGS_INDEX;
poke(Imm32(value), argumentStackOffset);
}
@@ -53,7 +53,7 @@ ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(unsigned value, unsigned argum
ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(void* value, unsigned argumentNumber)
{
- unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1;
+ unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + JITSTACKFRAME_ARGS_INDEX;
poke(ImmPtr(value), argumentStackOffset);
}
@@ -61,7 +61,7 @@ ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(void* value, unsigned argument
ALWAYS_INLINE void JIT::emitGetJITStubArg(unsigned argumentNumber, RegisterID dst)
{
- unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1;
+ unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + JITSTACKFRAME_ARGS_INDEX;
peek(dst, argumentStackOffset);
}
@@ -115,7 +115,7 @@ ALWAYS_INLINE JIT::Call JIT::emitNakedCall(CodePtr function)
ALWAYS_INLINE void JIT::beginUninterruptedSequence(int insnSpace, int constSpace)
{
-#if PLATFORM(ARM_TRADITIONAL)
+#if CPU(ARM_TRADITIONAL)
#ifndef NDEBUG
// Ensure the label after the sequence can also fit
insnSpace += sizeof(ARMWord);
@@ -144,7 +144,7 @@ ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace)
#endif
-#if PLATFORM(ARM_THUMB2)
+#if CPU(ARM)
ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
{
@@ -161,7 +161,7 @@ ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
loadPtr(address, linkRegister);
}
-#else // PLATFORM(X86) || PLATFORM(X86_64) || PLATFORM(ARM_TRADITIONAL)
+#else // CPU(X86) || CPU(X86_64)
ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
{
@@ -191,16 +191,13 @@ ALWAYS_INLINE void JIT::restoreArgumentReference()
{
move(stackPointerRegister, firstArgumentRegister);
poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*));
-#if PLATFORM(ARM_TRADITIONAL)
- move(ctiReturnRegister, ARMRegisters::lr);
-#endif
}
ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
{
-#if PLATFORM(X86)
+#if CPU(X86)
// Within a trampoline the return address will be on the stack at this point.
addPtr(Imm32(sizeof(void*)), stackPointerRegister, firstArgumentRegister);
-#elif PLATFORM(ARM_THUMB2)
+#elif CPU(ARM)
move(stackPointerRegister, firstArgumentRegister);
#endif
// In the trampoline on x86-64, the first argument register is not overwritten.
@@ -268,9 +265,9 @@ ALWAYS_INLINE void JIT::clearSamplingFlag(int32_t flag)
#if ENABLE(SAMPLING_COUNTERS)
ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, uint32_t count)
{
-#if PLATFORM(X86_64) // Or any other 64-bit plattform.
+#if CPU(X86_64) // Or any other 64-bit plattform.
addPtr(Imm32(count), AbsoluteAddress(&counter.m_counter));
-#elif PLATFORM(X86) // Or any other little-endian 32-bit plattform.
+#elif CPU(X86) // Or any other little-endian 32-bit plattform.
intptr_t hiWord = reinterpret_cast<intptr_t>(&counter.m_counter) + sizeof(int32_t);
add32(Imm32(count), AbsoluteAddress(&counter.m_counter));
addWithCarry32(Imm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord)));
@@ -281,7 +278,7 @@ ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, uint32_t cou
#endif
#if ENABLE(OPCODE_SAMPLING)
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction)
{
move(ImmPtr(m_interpreter->sampler()->sampleSlot()), X86Registers::ecx);
@@ -296,7 +293,7 @@ ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostF
#endif
#if ENABLE(CODEBLOCK_SAMPLING)
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
{
move(ImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86Registers::ecx);
@@ -588,7 +585,7 @@ ALWAYS_INLINE bool JIT::getOperandConstantImmediateInt(unsigned op1, unsigned op
ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID tag, RegisterID payload, unsigned argumentNumber)
{
- unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1;
+ unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + JITSTACKFRAME_ARGS_INDEX;
poke(payload, argumentStackOffset);
poke(tag, argumentStackOffset + 1);
}
@@ -597,7 +594,7 @@ ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID tag, RegisterID payload, un
ALWAYS_INLINE void JIT::emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch1, RegisterID scratch2)
{
- unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1;
+ unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + JITSTACKFRAME_ARGS_INDEX;
if (m_codeBlock->isConstantRegisterIndex(src)) {
JSValue constant = m_codeBlock->getConstant(src);
poke(Imm32(constant.payload()), argumentStackOffset);
@@ -820,7 +817,7 @@ ALWAYS_INLINE void JIT::emitFastArithImmToInt(RegisterID reg)
#if USE(JSVALUE64)
UNUSED_PARAM(reg);
#else
- rshiftPtr(Imm32(JSImmediate::IntegerPayloadShift), reg);
+ rshift32(Imm32(JSImmediate::IntegerPayloadShift), reg);
#endif
}
@@ -849,7 +846,7 @@ ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg)
// 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)
{
- unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + 1;
+ unsigned argumentStackOffset = (argumentNumber * (sizeof(JSValue) / sizeof(void*))) + JITSTACKFRAME_ARGS_INDEX;
if (m_codeBlock->isConstantRegisterIndex(src)) {
JSValue value = m_codeBlock->getConstant(src);
poke(ImmPtr(JSValue::encode(value)), argumentStackOffset);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp
index b5f6597..601f2d6 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITOpcodes.cpp
@@ -33,6 +33,7 @@
#include "JSArray.h"
#include "JSCell.h"
#include "JSFunction.h"
+#include "JSPropertyNameIterator.h"
#include "LinkBuffer.h"
namespace JSC {
@@ -51,8 +52,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
// Checks out okay! - get the length from the Ustring.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSString, m_value) + OBJECT_OFFSETOF(UString, m_rep)), regT2);
- load32(Address(regT2, OBJECT_OFFSETOF(UString::Rep, len)), regT2);
+ load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_stringLength)), regT2);
Jump string_failureCases3 = branch32(Above, regT2, Imm32(INT_MAX));
move(regT2, regT0);
@@ -137,7 +137,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0);
jump(regT0);
-#if PLATFORM(X86)
+#if CPU(X86) || CPU(ARM_TRADITIONAL)
Label nativeCallThunk = align();
preserveReturnAddressAfterCall(regT0);
emitPutToCallFrameHeader(regT0, RegisterFile::ReturnPC); // Push return address
@@ -148,6 +148,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT1);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+#if CPU(X86)
emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
/* We have two structs that we use to describe the stackframe we set up for our
@@ -159,7 +160,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
* stack pointer by the right amount after the call.
*/
-#if COMPILER(MSVC) || PLATFORM(LINUX)
+#if COMPILER(MSVC) || OS(LINUX)
#if COMPILER(MSVC)
#pragma pack(push)
#pragma pack(4)
@@ -222,7 +223,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
storePtr(regT2, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
storePtr(regT3, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
-#if COMPILER(MSVC) || PLATFORM(LINUX)
+#if COMPILER(MSVC) || OS(LINUX)
// ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register)
addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86Registers::ecx);
@@ -247,6 +248,66 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
// so pull them off now
addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister);
+#elif CPU(ARM_TRADITIONAL)
+ emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+
+ // Allocate stack space for our arglist
+ COMPILE_ASSERT((sizeof(ArgList) & 0x7) == 0 && sizeof(JSValue) == 8 && sizeof(Register) == 8, ArgList_should_by_8byte_aligned);
+ subPtr(Imm32(sizeof(ArgList)), stackPointerRegister);
+
+ // Set up arguments
+ subPtr(Imm32(1), regT0); // Don't include 'this' in argcount
+
+ // Push argcount
+ storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_argCount)));
+
+ // Calculate the start of the callframe header, and store in regT1
+ move(callFrameRegister, regT1);
+ sub32(Imm32(RegisterFile::CallFrameHeaderSize * (int32_t)sizeof(Register)), regT1);
+
+ // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT1)
+ mul32(Imm32(sizeof(Register)), regT0, regT0);
+ subPtr(regT0, regT1);
+
+ // push pointer to arguments
+ storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_args)));
+
+ // Argument passing method:
+ // r0 - points to return value
+ // r1 - callFrame
+ // r2 - callee
+ // stack: this(JSValue) and a pointer to ArgList
+
+ move(stackPointerRegister, regT3);
+ subPtr(Imm32(8), stackPointerRegister);
+ move(stackPointerRegister, regT0);
+ subPtr(Imm32(8 + 4 + 4 /* padding */), stackPointerRegister);
+
+ // Setup arg4:
+ storePtr(regT3, Address(stackPointerRegister, 8));
+
+ // Setup arg3
+ // regT1 currently points to the first argument, regT1-sizeof(Register) points to 'this'
+ load32(Address(regT1, -(int32_t)sizeof(void*) * 2), regT3);
+ storePtr(regT3, Address(stackPointerRegister, 0));
+ load32(Address(regT1, -(int32_t)sizeof(void*)), regT3);
+ storePtr(regT3, Address(stackPointerRegister, 4));
+
+ // Setup arg2:
+ emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT2);
+
+ // Setup arg1:
+ move(callFrameRegister, regT1);
+
+ call(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data)));
+
+ // Load return value
+ load32(Address(stackPointerRegister, 16), regT0);
+ load32(Address(stackPointerRegister, 20), regT1);
+
+ addPtr(Imm32(sizeof(ArgList) + 16 + 8), stackPointerRegister);
+#endif
+
// Check for an exception
move(ImmPtr(&globalData->exception), regT2);
Jump sawException = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::EmptyValueTag));
@@ -267,7 +328,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
move(ImmPtr(&globalData->exceptionLocation), regT2);
storePtr(regT1, regT2);
- move(ImmPtr(reinterpret_cast<void*>(ctiVMThrowTrampoline)), regT2);
+ move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*));
restoreReturnAddressBeforeReturn(regT2);
@@ -345,59 +406,7 @@ void JIT::emit_op_end(Instruction* currentInstruction)
void JIT::emit_op_jmp(Instruction* currentInstruction)
{
unsigned target = currentInstruction[1].u.operand;
- addJump(jump(), target + 1);
-}
-
-void JIT::emit_op_loop(Instruction* currentInstruction)
-{
- unsigned target = currentInstruction[1].u.operand;
- emitTimeoutCheck();
- addJump(jump(), target + 1);
-}
-
-void JIT::emit_op_loop_if_less(Instruction* currentInstruction)
-{
- unsigned op1 = currentInstruction[1].u.operand;
- unsigned op2 = currentInstruction[2].u.operand;
- unsigned target = currentInstruction[3].u.operand;
-
- emitTimeoutCheck();
-
- if (isOperandConstantImmediateInt(op1)) {
- emitLoad(op2, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op1).asInt32())), target + 3);
- return;
- }
-
- if (isOperandConstantImmediateInt(op2)) {
- emitLoad(op1, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3);
- return;
- }
-
- emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
- addJump(branch32(LessThan, regT0, regT2), target + 3);
-}
-
-void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned op1 = currentInstruction[1].u.operand;
- unsigned op2 = currentInstruction[2].u.operand;
- unsigned target = currentInstruction[3].u.operand;
-
- if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
- linkSlowCase(iter); // int32 check
- linkSlowCase(iter); // int32 check
-
- JITStubCall stubCall(this, cti_op_loop_if_less);
- stubCall.addArgument(op1);
- stubCall.addArgument(op2);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+ addJump(jump(), target);
}
void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
@@ -411,21 +420,21 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1)) {
emitLoad(op2, regT1, regT0);
addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target + 3);
+ addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target);
return;
}
if (isOperandConstantImmediateInt(op2)) {
emitLoad(op1, regT1, regT0);
addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
- addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3);
+ addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
return;
}
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
- addJump(branch32(LessThanOrEqual, regT0, regT2), target + 3);
+ addJump(branch32(LessThanOrEqual, regT0, regT2), target);
}
void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -442,7 +451,7 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo
stubCall.addArgument(op1);
stubCall.addArgument(op2);
stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
}
void JIT::emit_op_new_object(Instruction* currentInstruction)
@@ -457,30 +466,20 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
unsigned baseVal = currentInstruction[3].u.operand;
unsigned proto = currentInstruction[4].u.operand;
- // Load the operands (baseVal, proto, and value respectively) into registers.
+ // Load the operands into registers.
// We use regT0 for baseVal since we will be done with this first, and we can then use it for the result.
- emitLoadPayload(proto, regT1);
- emitLoadPayload(baseVal, regT0);
emitLoadPayload(value, regT2);
+ emitLoadPayload(baseVal, regT0);
+ emitLoadPayload(proto, regT1);
- // Check that baseVal & proto are cells.
- emitJumpSlowCaseIfNotJSCell(proto);
+ // Check that value, baseVal, and proto are cells.
+ emitJumpSlowCaseIfNotJSCell(value);
emitJumpSlowCaseIfNotJSCell(baseVal);
+ emitJumpSlowCaseIfNotJSCell(proto);
- // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'.
+ // Check that baseVal 'ImplementsDefaultHasInstance'.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); // FIXME: Maybe remove this test.
- addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsHasInstance))); // FIXME: TOT checks ImplementsDefaultHasInstance.
-
- // If value is not an Object, return false.
- emitLoadTag(value, regT0);
- Jump valueIsImmediate = branch32(NotEqual, regT0, Imm32(JSValue::CellTag));
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); // FIXME: Maybe remove this test.
-
- // Check proto is object.
- loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+ addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
// Optimistically load the result true, and start looping.
// Initially, regT1 still contains proto and regT2 still contains value.
@@ -488,16 +487,14 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
move(Imm32(JSValue::TrueTag), regT0);
Label loop(this);
- // Load the prototype of the object in regT2. If this is equal to regT1 - WIN!
+ // Load the prototype of the cell in regT2. If this is equal to regT1 - WIN!
// Otherwise, check if we've hit null - if we have then drop out of the loop, if not go again.
loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
load32(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
Jump isInstance = branchPtr(Equal, regT2, regT1);
- branch32(NotEqual, regT2, Imm32(0), loop);
+ branchTest32(NonZero, regT2).linkTo(loop, this);
// We get here either by dropping out of the loop, or if value was not an Object. Result is false.
- valueIsImmediate.link(this);
- valueIsNotObject.link(this);
move(Imm32(JSValue::FalseTag), regT0);
// isInstance jumps right down to here, to skip setting the result to false (it has already set true).
@@ -512,11 +509,10 @@ void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCas
unsigned baseVal = currentInstruction[3].u.operand;
unsigned proto = currentInstruction[4].u.operand;
+ linkSlowCaseIfNotJSCell(iter, value);
linkSlowCaseIfNotJSCell(iter, baseVal);
linkSlowCaseIfNotJSCell(iter, proto);
linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_instanceof);
stubCall.addArgument(value);
@@ -661,40 +657,6 @@ void JIT::emit_op_strcat(Instruction* currentInstruction)
stubCall.call(currentInstruction[1].u.operand);
}
-void JIT::emit_op_loop_if_true(Instruction* currentInstruction)
-{
- unsigned cond = currentInstruction[1].u.operand;
- unsigned target = currentInstruction[2].u.operand;
-
- emitTimeoutCheck();
-
- emitLoad(cond, regT1, regT0);
-
- Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
- addJump(branch32(NotEqual, regT0, Imm32(0)), target + 2);
- Jump isNotZero = jump();
-
- isNotInteger.link(this);
-
- addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target + 2);
- addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::FalseTag)));
-
- isNotZero.link(this);
-}
-
-void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned cond = currentInstruction[1].u.operand;
- unsigned target = currentInstruction[2].u.operand;
-
- linkSlowCase(iter);
-
- JITStubCall stubCall(this, cti_op_jtrue);
- stubCall.addArgument(cond);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2);
-}
-
void JIT::emit_op_resolve_base(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_base);
@@ -785,11 +747,11 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction)
emitLoad(cond, regT1, regT0);
Jump isTrue = branch32(Equal, regT1, Imm32(JSValue::TrueTag));
- addJump(branch32(Equal, regT1, Imm32(JSValue::FalseTag)), target + 2);
+ addJump(branch32(Equal, regT1, Imm32(JSValue::FalseTag)), target);
Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
Jump isTrue2 = branch32(NotEqual, regT0, Imm32(0));
- addJump(jump(), target + 2);
+ addJump(jump(), target);
if (supportsFloatingPoint()) {
isNotInteger.link(this);
@@ -798,7 +760,7 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction)
zeroDouble(fpRegT0);
emitLoadDouble(cond, fpRegT1);
- addJump(branchDouble(DoubleEqual, fpRegT0, fpRegT1), target + 2);
+ addJump(branchDouble(DoubleEqualOrUnordered, fpRegT0, fpRegT1), target);
} else
addSlowCase(isNotInteger);
@@ -815,7 +777,7 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt
JITStubCall stubCall(this, cti_op_jtrue);
stubCall.addArgument(cond);
stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), target + 2); // Inverted.
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target); // Inverted.
}
void JIT::emit_op_jtrue(Instruction* currentInstruction)
@@ -826,11 +788,11 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction)
emitLoad(cond, regT1, regT0);
Jump isFalse = branch32(Equal, regT1, Imm32(JSValue::FalseTag));
- addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target + 2);
+ addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target);
Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
Jump isFalse2 = branch32(Equal, regT0, Imm32(0));
- addJump(jump(), target + 2);
+ addJump(jump(), target);
if (supportsFloatingPoint()) {
isNotInteger.link(this);
@@ -839,7 +801,7 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction)
zeroDouble(fpRegT0);
emitLoadDouble(cond, fpRegT1);
- addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target + 2);
+ addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target);
} else
addSlowCase(isNotInteger);
@@ -856,7 +818,7 @@ void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntr
JITStubCall stubCall(this, cti_op_jtrue);
stubCall.addArgument(cond);
stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
}
void JIT::emit_op_jeq_null(Instruction* currentInstruction)
@@ -870,7 +832,7 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+ addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
Jump wasNotImmediate = jump();
@@ -881,7 +843,7 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1);
or32(regT2, regT1);
- addJump(branchTest32(NonZero, regT1), target + 2);
+ addJump(branchTest32(NonZero, regT1), target);
wasNotImmediate.link(this);
}
@@ -897,7 +859,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+ addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
Jump wasNotImmediate = jump();
@@ -908,7 +870,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1);
or32(regT2, regT1);
- addJump(branchTest32(Zero, regT1), target + 2);
+ addJump(branchTest32(Zero, regT1), target);
wasNotImmediate.link(this);
}
@@ -920,8 +882,8 @@ void JIT::emit_op_jneq_ptr(Instruction* currentInstruction)
unsigned target = currentInstruction[3].u.operand;
emitLoad(src, regT1, regT0);
- addJump(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)), target + 3);
- addJump(branchPtr(NotEqual, regT0, ImmPtr(ptr)), target + 3);
+ addJump(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)), target);
+ addJump(branchPtr(NotEqual, regT0, ImmPtr(ptr)), target);
}
void JIT::emit_op_jsr(Instruction* currentInstruction)
@@ -929,7 +891,7 @@ void JIT::emit_op_jsr(Instruction* currentInstruction)
int retAddrDst = currentInstruction[1].u.operand;
int target = currentInstruction[2].u.operand;
DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst));
- addJump(jump(), target + 2);
+ addJump(jump(), target);
m_jsrSites.append(JSRInfo(storeLocation, label()));
}
@@ -1195,23 +1157,109 @@ void JIT::emit_op_throw(Instruction* currentInstruction)
#endif
}
+void JIT::emit_op_get_pnames(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int base = currentInstruction[2].u.operand;
+ int i = currentInstruction[3].u.operand;
+ int size = currentInstruction[4].u.operand;
+ int breakTarget = currentInstruction[5].u.operand;
+
+ JumpList isNotObject;
+
+ emitLoad(base, regT1, regT0);
+ if (!m_codeBlock->isKnownNotImmediate(base))
+ isNotObject.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+ if (base != m_codeBlock->thisRegister()) {
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ isNotObject.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+ }
+
+ // We could inline the case where you have a valid cache, but
+ // this call doesn't seem to be hot.
+ Label isObject(this);
+ JITStubCall getPnamesStubCall(this, cti_op_get_pnames);
+ getPnamesStubCall.addArgument(regT0);
+ getPnamesStubCall.call(dst);
+ load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3);
+ store32(Imm32(0), addressFor(i));
+ store32(regT3, addressFor(size));
+ Jump end = jump();
+
+ isNotObject.link(this);
+ addJump(branch32(Equal, regT1, Imm32(JSValue::NullTag)), breakTarget);
+ addJump(branch32(Equal, regT1, Imm32(JSValue::UndefinedTag)), breakTarget);
+ JITStubCall toObjectStubCall(this, cti_to_object);
+ toObjectStubCall.addArgument(regT1, regT0);
+ toObjectStubCall.call(base);
+ jump().linkTo(isObject, this);
+
+ end.link(this);
+}
+
void JIT::emit_op_next_pname(Instruction* currentInstruction)
{
int dst = currentInstruction[1].u.operand;
- int iter = currentInstruction[2].u.operand;
- int target = currentInstruction[3].u.operand;
+ int base = currentInstruction[2].u.operand;
+ int i = currentInstruction[3].u.operand;
+ int size = currentInstruction[4].u.operand;
+ int it = currentInstruction[5].u.operand;
+ int target = currentInstruction[6].u.operand;
+
+ JumpList callHasProperty;
+
+ Label begin(this);
+ load32(addressFor(i), regT0);
+ Jump end = branch32(Equal, regT0, addressFor(size));
+
+ // Grab key @ i
+ loadPtr(addressFor(it), regT1);
+ loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2);
+ load32(BaseIndex(regT2, regT0, TimesEight), regT2);
+ store32(Imm32(JSValue::CellTag), tagFor(dst));
+ store32(regT2, payloadFor(dst));
+
+ // Increment i
+ add32(Imm32(1), regT0);
+ store32(regT0, addressFor(i));
+
+ // Verify that i is valid:
+ loadPtr(addressFor(base), regT0);
+
+ // Test base's structure
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))));
+
+ // Test base's prototype chain
+ loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3);
+ loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3);
+ addJump(branchTestPtr(Zero, Address(regT3)), target);
+
+ Label checkPrototype(this);
+ callHasProperty.append(branch32(Equal, Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::NullTag)));
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3)));
+ addPtr(Imm32(sizeof(Structure*)), regT3);
+ branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this);
- load32(Address(callFrameRegister, (iter * sizeof(Register))), regT0);
+ // Continue loop.
+ addJump(jump(), target);
- JITStubCall stubCall(this, cti_op_next_pname);
+ // Slow case: Ask the object if i is valid.
+ callHasProperty.link(this);
+ loadPtr(addressFor(dst), regT1);
+ JITStubCall stubCall(this, cti_has_property);
stubCall.addArgument(regT0);
+ stubCall.addArgument(regT1);
stubCall.call();
- Jump endOfIter = branchTestPtr(Zero, regT0);
- emitStore(dst, regT1, regT0);
- map(m_bytecodeIndex + OPCODE_LENGTH(op_next_pname), dst, regT1, regT0);
- addJump(jump(), target + 3);
- endOfIter.link(this);
+ // Test for valid key.
+ addJump(branchTest32(NonZero, regT0), target);
+ jump().linkTo(begin, this);
+
+ // End of loop.
+ end.link(this);
}
void JIT::emit_op_push_scope(Instruction* currentInstruction)
@@ -1286,7 +1334,7 @@ void JIT::emit_op_jmp_scopes(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_jmp_scopes);
stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.call();
- addJump(jump(), currentInstruction[2].u.operand + 2);
+ addJump(jump(), currentInstruction[2].u.operand);
}
void JIT::emit_op_switch_imm(Instruction* currentInstruction)
@@ -1361,7 +1409,6 @@ void JIT::emit_op_debug(Instruction* currentInstruction)
stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
- stubCall.addArgument(Imm32(currentInstruction[4].u.operand));
stubCall.call();
}
@@ -1464,8 +1511,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
// Checks out okay! - get the length from the Ustring.
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSString, m_value) + OBJECT_OFFSETOF(UString, m_rep)), regT0);
- load32(Address(regT0, OBJECT_OFFSETOF(UString::Rep, len)), regT0);
+ load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_stringLength)), regT0);
Jump string_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt));
@@ -1560,7 +1606,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, X86Registers::ecx);
// Allocate stack space for our arglist
@@ -1596,7 +1642,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
call(Address(X86Registers::esi, OBJECT_OFFSETOF(JSFunction, m_data)));
addPtr(Imm32(sizeof(ArgList)), stackPointerRegister);
-#elif PLATFORM(X86)
+#elif CPU(X86)
emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
/* We have two structs that we use to describe the stackframe we set up for our
@@ -1607,7 +1653,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
* not the rest of the callframe so we need a nice way to ensure we increment the
* stack pointer by the right amount after the call.
*/
-#if COMPILER(MSVC) || PLATFORM(LINUX)
+#if COMPILER(MSVC) || OS(LINUX)
struct NativeCallFrameStructure {
// CallFrame* callFrame; // passed in EDX
JSObject* callee;
@@ -1660,7 +1706,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
loadPtr(Address(regT1, -(int)sizeof(Register)), regT1);
storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue)));
-#if COMPILER(MSVC) || PLATFORM(LINUX)
+#if COMPILER(MSVC) || OS(LINUX)
// ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register)
addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86Registers::ecx);
@@ -1688,7 +1734,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
// so pull them off now
addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister);
-#elif PLATFORM(ARM_TRADITIONAL)
+#elif CPU(ARM)
emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
// Allocate stack space for our arglist
@@ -1722,9 +1768,8 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
move(callFrameRegister, regT0);
// Setup arg4: This is a plain hack
- move(stackPointerRegister, ARMRegisters::S0);
+ move(stackPointerRegister, ARMRegisters::r3);
- move(ctiReturnRegister, ARMRegisters::lr);
call(Address(regT1, OBJECT_OFFSETOF(JSFunction, m_data)));
addPtr(Imm32(sizeof(ArgList)), stackPointerRegister);
@@ -1755,7 +1800,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
move(ImmPtr(&globalData->exceptionLocation), regT2);
storePtr(regT1, regT2);
- move(ImmPtr(reinterpret_cast<void*>(ctiVMThrowTrampoline)), regT2);
+ move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*));
restoreReturnAddressBeforeReturn(regT2);
@@ -1831,49 +1876,8 @@ void JIT::emit_op_end(Instruction* currentInstruction)
void JIT::emit_op_jmp(Instruction* currentInstruction)
{
unsigned target = currentInstruction[1].u.operand;
- addJump(jump(), target + 1);
- RECORD_JUMP_TARGET(target + 1);
-}
-
-void JIT::emit_op_loop(Instruction* currentInstruction)
-{
- emitTimeoutCheck();
-
- unsigned target = currentInstruction[1].u.operand;
- addJump(jump(), target + 1);
-}
-
-void JIT::emit_op_loop_if_less(Instruction* currentInstruction)
-{
- emitTimeoutCheck();
-
- unsigned op1 = currentInstruction[1].u.operand;
- unsigned op2 = currentInstruction[2].u.operand;
- unsigned target = currentInstruction[3].u.operand;
- if (isOperandConstantImmediateInt(op2)) {
- emitGetVirtualRegister(op1, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
- int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
- int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
-#endif
- addJump(branch32(LessThan, regT0, Imm32(op2imm)), target + 3);
- } else if (isOperandConstantImmediateInt(op1)) {
- emitGetVirtualRegister(op2, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
- int32_t op1imm = getConstantOperandImmediateInt(op1);
-#else
- int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
-#endif
- addJump(branch32(GreaterThan, regT0, Imm32(op1imm)), target + 3);
- } else {
- emitGetVirtualRegisters(op1, regT0, op2, regT1);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT1);
- addJump(branch32(LessThan, regT0, regT1), target + 3);
- }
+ addJump(jump(), target);
+ RECORD_JUMP_TARGET(target);
}
void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
@@ -1891,12 +1895,12 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
#else
int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
#endif
- addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target + 3);
+ addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
- addJump(branch32(LessThanOrEqual, regT0, regT1), target + 3);
+ addJump(branch32(LessThanOrEqual, regT0, regT1), target);
}
}
@@ -1907,30 +1911,26 @@ void JIT::emit_op_new_object(Instruction* currentInstruction)
void JIT::emit_op_instanceof(Instruction* currentInstruction)
{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned value = currentInstruction[2].u.operand;
+ unsigned baseVal = currentInstruction[3].u.operand;
+ unsigned proto = currentInstruction[4].u.operand;
+
// Load the operands (baseVal, proto, and value respectively) into registers.
// We use regT0 for baseVal since we will be done with this first, and we can then use it for the result.
- emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
- emitGetVirtualRegister(currentInstruction[4].u.operand, regT1);
- emitGetVirtualRegister(currentInstruction[2].u.operand, regT2);
+ emitGetVirtualRegister(value, regT2);
+ emitGetVirtualRegister(baseVal, regT0);
+ emitGetVirtualRegister(proto, regT1);
// Check that baseVal & proto are cells.
- emitJumpSlowCaseIfNotJSCell(regT0);
- emitJumpSlowCaseIfNotJSCell(regT1);
+ emitJumpSlowCaseIfNotJSCell(regT2, value);
+ emitJumpSlowCaseIfNotJSCell(regT0, baseVal);
+ emitJumpSlowCaseIfNotJSCell(regT1, proto);
- // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'.
+ // Check that baseVal 'ImplementsDefaultHasInstance'.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
- // If value is not an Object, return false.
- Jump valueIsImmediate = emitJumpIfNotJSCell(regT2);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType));
-
- // Check proto is object.
- loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
- addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
-
// Optimistically load the result true, and start looping.
// Initially, regT1 still contains proto and regT2 still contains value.
// As we loop regT2 will be updated with its prototype, recursively walking the prototype chain.
@@ -1942,16 +1942,14 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
Jump isInstance = branchPtr(Equal, regT2, regT1);
- branchPtr(NotEqual, regT2, ImmPtr(JSValue::encode(jsNull())), loop);
+ emitJumpIfJSCell(regT2).linkTo(loop, this);
// We get here either by dropping out of the loop, or if value was not an Object. Result is false.
- valueIsImmediate.link(this);
- valueIsNotObject.link(this);
move(ImmPtr(JSValue::encode(jsBoolean(false))), regT0);
// isInstance jumps right down to here, to skip setting the result to false (it has already set true).
isInstance.link(this);
- emitPutVirtualRegister(currentInstruction[1].u.operand);
+ emitPutVirtualRegister(dst);
}
void JIT::emit_op_new_func(Instruction* currentInstruction)
@@ -2125,21 +2123,6 @@ void JIT::emit_op_strcat(Instruction* currentInstruction)
stubCall.call(currentInstruction[1].u.operand);
}
-void JIT::emit_op_loop_if_true(Instruction* currentInstruction)
-{
- emitTimeoutCheck();
-
- unsigned target = currentInstruction[2].u.operand;
- emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
-
- Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0))));
- addJump(emitJumpIfImmediateInteger(regT0), target + 2);
-
- addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target + 2);
- addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))));
-
- isZero.link(this);
-};
void JIT::emit_op_resolve_base(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve_base);
@@ -2202,14 +2185,14 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction)
unsigned target = currentInstruction[2].u.operand;
emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
- addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target + 2);
+ addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target);
Jump isNonZero = emitJumpIfImmediateInteger(regT0);
- addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target + 2);
+ addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target);
addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))));
isNonZero.link(this);
- RECORD_JUMP_TARGET(target + 2);
+ RECORD_JUMP_TARGET(target);
};
void JIT::emit_op_jeq_null(Instruction* currentInstruction)
{
@@ -2221,16 +2204,16 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+ addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
Jump wasNotImmediate = jump();
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
- addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNull()))), target + 2);
+ addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNull()))), target);
wasNotImmediate.link(this);
- RECORD_JUMP_TARGET(target + 2);
+ RECORD_JUMP_TARGET(target);
};
void JIT::emit_op_jneq_null(Instruction* currentInstruction)
{
@@ -2242,16 +2225,16 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+ addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
Jump wasNotImmediate = jump();
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
- addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsNull()))), target + 2);
+ addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsNull()))), target);
wasNotImmediate.link(this);
- RECORD_JUMP_TARGET(target + 2);
+ RECORD_JUMP_TARGET(target);
}
void JIT::emit_op_jneq_ptr(Instruction* currentInstruction)
@@ -2261,9 +2244,9 @@ void JIT::emit_op_jneq_ptr(Instruction* currentInstruction)
unsigned target = currentInstruction[3].u.operand;
emitGetVirtualRegister(src, regT0);
- addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue(ptr)))), target + 3);
+ addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue(ptr)))), target);
- RECORD_JUMP_TARGET(target + 3);
+ RECORD_JUMP_TARGET(target);
}
void JIT::emit_op_jsr(Instruction* currentInstruction)
@@ -2271,10 +2254,10 @@ void JIT::emit_op_jsr(Instruction* currentInstruction)
int retAddrDst = currentInstruction[1].u.operand;
int target = currentInstruction[2].u.operand;
DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst));
- addJump(jump(), target + 2);
+ addJump(jump(), target);
m_jsrSites.append(JSRInfo(storeLocation, label()));
killLastResultRegister();
- RECORD_JUMP_TARGET(target + 2);
+ RECORD_JUMP_TARGET(target);
}
void JIT::emit_op_sret(Instruction* currentInstruction)
@@ -2326,13 +2309,13 @@ void JIT::emit_op_jtrue(Instruction* currentInstruction)
emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0))));
- addJump(emitJumpIfImmediateInteger(regT0), target + 2);
+ addJump(emitJumpIfImmediateInteger(regT0), target);
- addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target + 2);
+ addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target);
addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))));
isZero.link(this);
- RECORD_JUMP_TARGET(target + 2);
+ RECORD_JUMP_TARGET(target);
}
void JIT::emit_op_neq(Instruction* currentInstruction)
@@ -2383,15 +2366,116 @@ void JIT::emit_op_throw(Instruction* currentInstruction)
#endif
}
+void JIT::emit_op_get_pnames(Instruction* currentInstruction)
+{
+ int dst = currentInstruction[1].u.operand;
+ int base = currentInstruction[2].u.operand;
+ int i = currentInstruction[3].u.operand;
+ int size = currentInstruction[4].u.operand;
+ int breakTarget = currentInstruction[5].u.operand;
+
+ JumpList isNotObject;
+
+ emitGetVirtualRegister(base, regT0);
+ if (!m_codeBlock->isKnownNotImmediate(base))
+ isNotObject.append(emitJumpIfNotJSCell(regT0));
+ if (base != m_codeBlock->thisRegister()) {
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ isNotObject.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+ }
+
+ // We could inline the case where you have a valid cache, but
+ // this call doesn't seem to be hot.
+ Label isObject(this);
+ JITStubCall getPnamesStubCall(this, cti_op_get_pnames);
+ getPnamesStubCall.addArgument(regT0);
+ getPnamesStubCall.call(dst);
+ load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3);
+ store32(Imm32(0), addressFor(i));
+ store32(regT3, addressFor(size));
+ Jump end = jump();
+
+ isNotObject.link(this);
+ move(regT0, regT1);
+ and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT1);
+ addJump(branch32(Equal, regT1, Imm32(JSImmediate::FullTagTypeNull)), breakTarget);
+
+ JITStubCall toObjectStubCall(this, cti_to_object);
+ toObjectStubCall.addArgument(regT0);
+ toObjectStubCall.call(base);
+ jump().linkTo(isObject, this);
+
+ end.link(this);
+}
+
void JIT::emit_op_next_pname(Instruction* currentInstruction)
{
- JITStubCall stubCall(this, cti_op_next_pname);
- stubCall.addArgument(currentInstruction[2].u.operand, regT2);
+ int dst = currentInstruction[1].u.operand;
+ int base = currentInstruction[2].u.operand;
+ int i = currentInstruction[3].u.operand;
+ int size = currentInstruction[4].u.operand;
+ int it = currentInstruction[5].u.operand;
+ int target = currentInstruction[6].u.operand;
+
+ JumpList callHasProperty;
+
+ Label begin(this);
+ load32(addressFor(i), regT0);
+ Jump end = branch32(Equal, regT0, addressFor(size));
+
+ // Grab key @ i
+ loadPtr(addressFor(it), regT1);
+ loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2);
+
+#if USE(JSVALUE64)
+ loadPtr(BaseIndex(regT2, regT0, TimesEight), regT2);
+#else
+ loadPtr(BaseIndex(regT2, regT0, TimesFour), regT2);
+#endif
+
+ emitPutVirtualRegister(dst, regT2);
+
+ // Increment i
+ add32(Imm32(1), regT0);
+ store32(regT0, addressFor(i));
+
+ // Verify that i is valid:
+ emitGetVirtualRegister(base, regT0);
+
+ // Test base's structure
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))));
+
+ // Test base's prototype chain
+ loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3);
+ loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3);
+ addJump(branchTestPtr(Zero, Address(regT3)), target);
+
+ Label checkPrototype(this);
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
+ callHasProperty.append(emitJumpIfNotJSCell(regT2));
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3)));
+ addPtr(Imm32(sizeof(Structure*)), regT3);
+ branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this);
+
+ // Continue loop.
+ addJump(jump(), target);
+
+ // Slow case: Ask the object if i is valid.
+ callHasProperty.link(this);
+ emitGetVirtualRegister(dst, regT1);
+ JITStubCall stubCall(this, cti_has_property);
+ stubCall.addArgument(regT0);
+ stubCall.addArgument(regT1);
stubCall.call();
- Jump endOfIter = branchTestPtr(Zero, regT0);
- emitPutVirtualRegister(currentInstruction[1].u.operand);
- addJump(jump(), currentInstruction[3].u.operand + 3);
- endOfIter.link(this);
+
+ // Test for valid key.
+ addJump(branchTest32(NonZero, regT0), target);
+ jump().linkTo(begin, this);
+
+ // End of loop.
+ end.link(this);
}
void JIT::emit_op_push_scope(Instruction* currentInstruction)
@@ -2480,8 +2564,8 @@ void JIT::emit_op_jmp_scopes(Instruction* currentInstruction)
JITStubCall stubCall(this, cti_op_jmp_scopes);
stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.call();
- addJump(jump(), currentInstruction[2].u.operand + 2);
- RECORD_JUMP_TARGET(currentInstruction[2].u.operand + 2);
+ addJump(jump(), currentInstruction[2].u.operand);
+ RECORD_JUMP_TARGET(currentInstruction[2].u.operand);
}
void JIT::emit_op_switch_imm(Instruction* currentInstruction)
@@ -2552,7 +2636,6 @@ void JIT::emit_op_debug(Instruction* currentInstruction)
stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
- stubCall.addArgument(Imm32(currentInstruction[4].u.operand));
stubCall.call();
}
@@ -2724,36 +2807,6 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
stubCall.call(dst);
}
-void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned op1 = currentInstruction[1].u.operand;
- unsigned op2 = currentInstruction[2].u.operand;
- unsigned target = currentInstruction[3].u.operand;
- if (isOperandConstantImmediateInt(op2)) {
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_loop_if_less);
- stubCall.addArgument(regT0);
- stubCall.addArgument(op2, regT2);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
- } else if (isOperandConstantImmediateInt(op1)) {
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_loop_if_less);
- stubCall.addArgument(op1, regT2);
- stubCall.addArgument(regT0);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
- } else {
- linkSlowCase(iter);
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_loop_if_less);
- stubCall.addArgument(regT0);
- stubCall.addArgument(regT1);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
- }
-}
-
void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned op2 = currentInstruction[2].u.operand;
@@ -2764,7 +2817,7 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo
stubCall.addArgument(regT0);
stubCall.addArgument(currentInstruction[2].u.operand, regT2);
stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
} else {
linkSlowCase(iter);
linkSlowCase(iter);
@@ -2772,7 +2825,7 @@ void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<Slo
stubCall.addArgument(regT0);
stubCall.addArgument(regT1);
stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
}
}
@@ -2794,15 +2847,6 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas
stubPutByValCall.call();
}
-void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- linkSlowCase(iter);
- JITStubCall stubCall(this, cti_op_jtrue);
- stubCall.addArgument(regT0);
- stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2);
-}
-
void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
linkSlowCase(iter);
@@ -2818,7 +2862,7 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt
JITStubCall stubCall(this, cti_op_jtrue);
stubCall.addArgument(regT0);
stubCall.call();
- emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand + 2); // inverted!
+ emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand); // inverted!
}
void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -2835,7 +2879,7 @@ void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntr
JITStubCall stubCall(this, cti_op_jtrue);
stubCall.addArgument(regT0);
stubCall.call();
- emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand);
}
void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -2901,16 +2945,20 @@ void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCase
void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned value = currentInstruction[2].u.operand;
+ unsigned baseVal = currentInstruction[3].u.operand;
+ unsigned proto = currentInstruction[4].u.operand;
+
+ linkSlowCaseIfNotJSCell(iter, value);
+ linkSlowCaseIfNotJSCell(iter, baseVal);
+ linkSlowCaseIfNotJSCell(iter, proto);
linkSlowCase(iter);
JITStubCall stubCall(this, cti_op_instanceof);
- stubCall.addArgument(currentInstruction[2].u.operand, regT2);
- stubCall.addArgument(currentInstruction[3].u.operand, regT2);
- stubCall.addArgument(currentInstruction[4].u.operand, regT2);
- stubCall.call(currentInstruction[1].u.operand);
+ stubCall.addArgument(value, regT2);
+ stubCall.addArgument(baseVal, regT2);
+ stubCall.addArgument(proto, regT2);
+ stubCall.call(dst);
}
void JIT::emitSlow_op_call(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp
index 9edfd01..ef95f99 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -33,6 +33,7 @@
#include "JITStubCall.h"
#include "JSArray.h"
#include "JSFunction.h"
+#include "JSPropertyNameIterator.h"
#include "Interpreter.h"
#include "LinkBuffer.h"
#include "RepatchBuffer.h"
@@ -211,12 +212,17 @@ void JIT::emit_op_method_check(Instruction* currentInstruction)
emitLoad(base, regT1, regT0);
emitJumpSlowCaseIfNotJSCell(base, regT1);
+ BEGIN_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck);
+
Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), info.structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
DataLabelPtr protoStructureToCompare, protoObj = moveWithPatch(ImmPtr(0), regT2);
Jump protoStructureCheck = branchPtrWithPatch(NotEqual, Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), protoStructureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
// This will be relinked to load the function without doing a load.
DataLabelPtr putFunction = moveWithPatch(ImmPtr(0), regT0);
+
+ END_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck);
+
move(Imm32(JSValue::CellTag), regT1);
Jump match = jump();
@@ -373,6 +379,9 @@ void JIT::compileGetByIdHotPath()
// Additionally, for get_by_id we need patch the offset of the branch to the slow case (we patch this to jump
// to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
// to jump back to if one of these trampolies finds a match.
+
+ BEGIN_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath);
+
Label hotPathBegin(this);
m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
m_propertyAccessInstructionIndex++;
@@ -395,6 +404,8 @@ void JIT::compileGetByIdHotPath()
Label putResult(this);
ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult);
+
+ END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath);
}
void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -416,13 +427,18 @@ void JIT::compileGetByIdSlowCase(int dst, int base, Identifier* ident, Vector<Sl
linkSlowCaseIfNotJSCell(iter, base);
linkSlowCase(iter);
- Label coldPathBegin(this);
+ BEGIN_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase);
+#ifndef NDEBUG
+ Label coldPathBegin(this);
+#endif
JITStubCall stubCall(this, isMethodCheck ? cti_op_get_by_id_method_check : cti_op_get_by_id);
stubCall.addArgument(regT1, regT0);
stubCall.addArgument(ImmPtr(ident));
Call call = stubCall.call(dst);
+ END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase);
+
ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall);
// Track the location of the call; this will be used to recover patch information.
@@ -443,6 +459,8 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(base, regT1);
+ BEGIN_UNINTERRUPTED_SEQUENCE(sequencePutById);
+
Label hotPathBegin(this);
m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
m_propertyAccessInstructionIndex++;
@@ -460,6 +478,9 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
DataLabel32 displacementLabel1 = storePtrWithAddressOffsetPatch(regT2, Address(regT0, patchGetByIdDefaultOffset)); // payload
DataLabel32 displacementLabel2 = storePtrWithAddressOffsetPatch(regT3, Address(regT0, patchGetByIdDefaultOffset)); // tag
+
+ END_UNINTERRUPTED_SEQUENCE(sequencePutById);
+
ASSERT(differenceBetween(hotPathBegin, displacementLabel1) == patchOffsetPutByIdPropertyMapOffset1);
ASSERT(differenceBetween(hotPathBegin, displacementLabel2) == patchOffsetPutByIdPropertyMapOffset2);
}
@@ -521,22 +542,26 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID res
load32(Address(temp, offset + 4), resultTag);
}
+void JIT::testPrototype(Structure* structure, JumpList& failureCases)
+{
+ if (structure->m_prototype.isNull())
+ return;
+
+ failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(structure->m_prototype)->m_structure), ImmPtr(asCell(structure->m_prototype)->m_structure)));
+}
+
void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress)
{
// It is assumed that regT0 contains the basePayload and regT1 contains the baseTag. The value can be found on the stack.
JumpList failureCases;
failureCases.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
-
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- failureCases.append(branchPtr(NotEqual, regT2, ImmPtr(oldStructure)));
+ failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure)));
+ testPrototype(oldStructure, failureCases);
// Verify that nothing in the prototype chain has a setter for this property.
- for (RefPtr<Structure>* it = chain->head(); *it; ++it) {
- loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- failureCases.append(branchPtr(NotEqual, regT2, ImmPtr(it->get())));
- }
+ for (RefPtr<Structure>* it = chain->head(); *it; ++it)
+ testPrototype(it->get(), failureCases);
// Reallocate property storage if needed.
Call callTarget;
@@ -705,7 +730,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
move(ImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
#else
@@ -785,7 +810,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
move(ImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
#else
@@ -838,7 +863,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
move(ImmPtr(currStructure), regT3);
bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
#else
@@ -893,7 +918,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
move(ImmPtr(currStructure), regT3);
bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
#else
@@ -930,6 +955,69 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
#endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset)
+{
+ ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t));
+ ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t));
+ ASSERT(sizeof(JSValue) == 8);
+
+ Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity));
+ loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
+ loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
+ Jump finishedLoad = jump();
+ notUsingInlineStorage.link(this);
+ loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
+ loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
+ loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
+ finishedLoad.link(this);
+}
+
+void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned base = currentInstruction[2].u.operand;
+ unsigned property = currentInstruction[3].u.operand;
+ unsigned expected = currentInstruction[4].u.operand;
+ unsigned iter = currentInstruction[5].u.operand;
+ unsigned i = currentInstruction[6].u.operand;
+
+ emitLoad2(property, regT1, regT0, base, regT3, regT2);
+ emitJumpSlowCaseIfNotJSCell(property, regT1);
+ addSlowCase(branchPtr(NotEqual, regT0, payloadFor(expected)));
+ // Property registers are now available as the property is known
+ emitJumpSlowCaseIfNotJSCell(base, regT3);
+ emitLoadPayload(iter, regT1);
+
+ // Test base's structure
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
+ addSlowCase(branchPtr(NotEqual, regT0, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))));
+ load32(addressFor(i), regT3);
+ sub32(Imm32(1), regT3);
+ addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
+ compileGetDirectOffset(regT2, regT1, regT0, regT0, regT3);
+
+ emitStore(dst, regT1, regT0);
+ map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_pname), dst, regT1, regT0);
+}
+
+void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned base = currentInstruction[2].u.operand;
+ unsigned property = currentInstruction[3].u.operand;
+
+ linkSlowCaseIfNotJSCell(iter, property);
+ linkSlowCase(iter);
+ linkSlowCaseIfNotJSCell(iter, base);
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+
+ JITStubCall stubCall(this, cti_op_get_by_val);
+ stubCall.addArgument(base);
+ stubCall.addArgument(property);
+ stubCall.call(dst);
+}
+
#else // USE(JSVALUE32_64)
void JIT::emit_op_get_by_val(Instruction* currentInstruction)
@@ -963,6 +1051,62 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
emitPutVirtualRegister(dst);
}
+void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch)
+{
+ ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t));
+ ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t));
+
+ Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity));
+ loadPtr(BaseIndex(base, offset, ScalePtr, OBJECT_OFFSETOF(JSObject, m_inlineStorage)), result);
+ Jump finishedLoad = jump();
+ notUsingInlineStorage.link(this);
+ loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), scratch);
+ loadPtr(BaseIndex(scratch, offset, ScalePtr, 0), result);
+ finishedLoad.link(this);
+}
+
+void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned base = currentInstruction[2].u.operand;
+ unsigned property = currentInstruction[3].u.operand;
+ unsigned expected = currentInstruction[4].u.operand;
+ unsigned iter = currentInstruction[5].u.operand;
+ unsigned i = currentInstruction[6].u.operand;
+
+ emitGetVirtualRegister(property, regT0);
+ addSlowCase(branchPtr(NotEqual, regT0, addressFor(expected)));
+ emitGetVirtualRegisters(base, regT0, iter, regT1);
+ emitJumpSlowCaseIfNotJSCell(regT0, base);
+
+ // Test base's structure
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ addSlowCase(branchPtr(NotEqual, regT2, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))));
+ load32(addressFor(i), regT3);
+ sub32(Imm32(1), regT3);
+ addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
+ compileGetDirectOffset(regT0, regT0, regT2, regT3, regT1);
+
+ emitPutVirtualRegister(dst, regT0);
+}
+
+void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned dst = currentInstruction[1].u.operand;
+ unsigned base = currentInstruction[2].u.operand;
+ unsigned property = currentInstruction[3].u.operand;
+
+ linkSlowCase(iter);
+ linkSlowCaseIfNotJSCell(iter, base);
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+
+ JITStubCall stubCall(this, cti_op_get_by_val);
+ stubCall.addArgument(base, regT2);
+ stubCall.addArgument(property, regT2);
+ stubCall.call(dst);
+}
+
void JIT::emit_op_put_by_val(Instruction* currentInstruction)
{
unsigned base = currentInstruction[1].u.operand;
@@ -1128,9 +1272,9 @@ void JIT::emit_op_method_check(Instruction* currentInstruction)
Jump match = jump();
- ASSERT(differenceBetween(info.structureToCompare, protoObj) == patchOffsetMethodCheckProtoObj);
- ASSERT(differenceBetween(info.structureToCompare, protoStructureToCompare) == patchOffsetMethodCheckProtoStruct);
- ASSERT(differenceBetween(info.structureToCompare, putFunction) == patchOffsetMethodCheckPutFunction);
+ ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoObj), patchOffsetMethodCheckProtoObj);
+ ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoStructureToCompare), patchOffsetMethodCheckProtoStruct);
+ ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, putFunction), patchOffsetMethodCheckPutFunction);
// Link the failure cases here.
notCell.link(this);
@@ -1197,22 +1341,22 @@ void JIT::compileGetByIdHotPath(int, int baseVReg, Identifier*, unsigned propert
DataLabelPtr structureToCompare;
Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
addSlowCase(structureCheck);
- ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetGetByIdStructure);
- ASSERT(differenceBetween(hotPathBegin, structureCheck) == patchOffsetGetByIdBranchToSlowCase);
+ ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetGetByIdStructure);
+ ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureCheck), patchOffsetGetByIdBranchToSlowCase)
Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0);
Label externalLoadComplete(this);
- ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetGetByIdExternalLoad);
- ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthGetByIdExternalLoad);
+ ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetGetByIdExternalLoad);
+ ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthGetByIdExternalLoad);
DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(regT0, patchGetByIdDefaultOffset), regT0);
- ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetGetByIdPropertyMapOffset);
+ ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel), patchOffsetGetByIdPropertyMapOffset);
Label putResult(this);
END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath);
- ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult);
+ ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, putResult), patchOffsetGetByIdPutResult);
}
void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -1247,7 +1391,7 @@ void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident
END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase);
- ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall);
+ ASSERT_JIT_OFFSET(differenceBetween(coldPathBegin, call), patchOffsetGetByIdSlowCaseCall);
// Track the location of the call; this will be used to recover patch information.
m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call;
@@ -1278,19 +1422,19 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
// It is important that the following instruction plants a 32bit immediate, in order that it can be patched over.
DataLabelPtr structureToCompare;
addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
- ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetPutByIdStructure);
+ ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetPutByIdStructure);
// Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used.
Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0);
Label externalLoadComplete(this);
- ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetPutByIdExternalLoad);
- ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthPutByIdExternalLoad);
+ ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetPutByIdExternalLoad);
+ ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthPutByIdExternalLoad);
DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT0, patchGetByIdDefaultOffset));
END_UNINTERRUPTED_SEQUENCE(sequencePutById);
- ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetPutByIdPropertyMapOffset);
+ ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel), patchOffsetPutByIdPropertyMapOffset);
}
void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -1347,35 +1491,27 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID res
}
}
+void JIT::testPrototype(Structure* structure, JumpList& failureCases)
+{
+ if (structure->m_prototype.isNull())
+ return;
+
+ move(ImmPtr(&asCell(structure->m_prototype)->m_structure), regT2);
+ move(ImmPtr(asCell(structure->m_prototype)->m_structure), regT3);
+ failureCases.append(branchPtr(NotEqual, Address(regT2), regT3));
+}
+
void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress)
{
JumpList failureCases;
// Check eax is an object of the right Structure.
failureCases.append(emitJumpIfNotJSCell(regT0));
failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure)));
- JumpList successCases;
-
- // ecx = baseObject
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- // proto(ecx) = baseObject->structure()->prototype()
- failureCases.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType)));
+ testPrototype(oldStructure, failureCases);
- loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
-
// ecx = baseObject->m_structure
- for (RefPtr<Structure>* it = chain->head(); *it; ++it) {
- // null check the prototype
- successCases.append(branchPtr(Equal, regT2, ImmPtr(JSValue::encode(jsNull()))));
-
- // Check the structure id
- failureCases.append(branchPtr(NotEqual, Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(it->get())));
-
- loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
- failureCases.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType)));
- loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
- }
-
- successCases.link(this);
+ for (RefPtr<Structure>* it = chain->head(); *it; ++it)
+ testPrototype(it->get(), failureCases);
Call callTarget;
@@ -1540,7 +1676,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
move(ImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
#else
@@ -1615,7 +1751,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
move(ImmPtr(prototypeStructure), regT3);
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
#else
@@ -1668,7 +1804,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
move(ImmPtr(currStructure), regT3);
bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
#else
@@ -1721,7 +1857,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
move(ImmPtr(currStructure), regT3);
bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
#else
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubCall.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubCall.h
index cb5354b..cfbd7dc 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubCall.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubCall.h
@@ -26,7 +26,7 @@
#ifndef JITStubCall_h
#define JITStubCall_h
-#include <wtf/Platform.h>
+#include "MacroAssemblerCodeRef.h"
#if ENABLE(JIT)
@@ -36,58 +36,58 @@ namespace JSC {
public:
JITStubCall(JIT* jit, JSObject* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
- , m_stub(reinterpret_cast<void*>(stub))
+ , m_stub(stub)
, m_returnType(Cell)
- , m_stackIndex(stackIndexStart)
+ , m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
JITStubCall(JIT* jit, JSPropertyNameIterator* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
- , m_stub(reinterpret_cast<void*>(stub))
+ , m_stub(stub)
, m_returnType(Cell)
- , m_stackIndex(stackIndexStart)
+ , m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
JITStubCall(JIT* jit, void* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
- , m_stub(reinterpret_cast<void*>(stub))
+ , m_stub(stub)
, m_returnType(VoidPtr)
- , m_stackIndex(stackIndexStart)
+ , m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
JITStubCall(JIT* jit, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
- , m_stub(reinterpret_cast<void*>(stub))
+ , m_stub(stub)
, m_returnType(Int)
- , m_stackIndex(stackIndexStart)
+ , m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
JITStubCall(JIT* jit, bool (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
- , m_stub(reinterpret_cast<void*>(stub))
+ , m_stub(stub)
, m_returnType(Int)
- , m_stackIndex(stackIndexStart)
+ , m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
JITStubCall(JIT* jit, void (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
- , m_stub(reinterpret_cast<void*>(stub))
+ , m_stub(stub)
, m_returnType(Void)
- , m_stackIndex(stackIndexStart)
+ , m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
#if USE(JSVALUE32_64)
JITStubCall(JIT* jit, EncodedJSValue (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
: m_jit(jit)
- , m_stub(reinterpret_cast<void*>(stub))
+ , m_stub(stub)
, m_returnType(Value)
- , m_stackIndex(stackIndexStart)
+ , m_stackIndex(JITSTACKFRAME_ARGS_INDEX)
{
}
#endif
@@ -145,7 +145,7 @@ namespace JSC {
void getArgument(size_t argumentNumber, JIT::RegisterID tag, JIT::RegisterID payload)
{
- size_t stackIndex = stackIndexStart + (argumentNumber * stackIndexStep);
+ size_t stackIndex = JITSTACKFRAME_ARGS_INDEX + (argumentNumber * stackIndexStep);
m_jit->peek(payload, stackIndex);
m_jit->peek(tag, stackIndex + 1);
}
@@ -171,7 +171,7 @@ namespace JSC {
m_jit->restoreArgumentReference();
JIT::Call call = m_jit->call();
- m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeIndex, m_stub));
+ m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeIndex, m_stub.value()));
#if ENABLE(OPCODE_SAMPLING)
if (m_jit->m_bytecodeIndex != (unsigned)-1)
@@ -222,10 +222,9 @@ namespace JSC {
private:
static const size_t stackIndexStep = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 2 : 1;
- static const size_t stackIndexStart = 1; // Index 0 is reserved for restoreArgumentReference().
JIT* m_jit;
- void* m_stub;
+ FunctionPtr m_stub;
enum { Void, VoidPtr, Int, Value, Cell } m_returnType;
size_t m_stackIndex;
};
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp
index b098728..91b9401 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp
@@ -56,6 +56,7 @@
#include "RegExpPrototype.h"
#include "Register.h"
#include "SamplingTool.h"
+#include <wtf/StdLibExtras.h>
#include <stdarg.h>
#include <stdio.h>
@@ -67,25 +68,37 @@ using namespace std;
namespace JSC {
-#if PLATFORM(DARWIN) || PLATFORM(WIN_OS)
+#if OS(DARWIN) || OS(WINDOWS)
#define SYMBOL_STRING(name) "_" #name
#else
#define SYMBOL_STRING(name) #name
#endif
-#if PLATFORM(IPHONE)
+#if OS(IPHONE_OS)
#define THUMB_FUNC_PARAM(name) SYMBOL_STRING(name)
#else
#define THUMB_FUNC_PARAM(name)
#endif
-#if PLATFORM(DARWIN)
+#if OS(LINUX) && CPU(X86_64)
+#define SYMBOL_STRING_RELOCATION(name) #name "@plt"
+#else
+#define SYMBOL_STRING_RELOCATION(name) SYMBOL_STRING(name)
+#endif
+
+#if OS(DARWIN)
// Mach-O platform
#define HIDE_SYMBOL(name) ".private_extern _" #name
-#elif PLATFORM(AIX)
+#elif OS(AIX)
// IBM's own file format
#define HIDE_SYMBOL(name) ".lglobl " #name
-#elif PLATFORM(LINUX) || PLATFORM(FREEBSD) || PLATFORM(OPENBSD) || PLATFORM(SOLARIS) || (PLATFORM(HPUX) && PLATFORM(IA64)) || PLATFORM(SYMBIAN) || PLATFORM(NETBSD)
+#elif OS(LINUX) \
+ || OS(FREEBSD) \
+ || OS(OPENBSD) \
+ || OS(SOLARIS) \
+ || (OS(HPUX) && CPU(IA64)) \
+ || OS(SYMBIAN) \
+ || OS(NETBSD)
// ELF platform
#define HIDE_SYMBOL(name) ".hidden " #name
#else
@@ -94,7 +107,7 @@ namespace JSC {
#if USE(JSVALUE32_64)
-#if COMPILER(GCC) && PLATFORM(X86)
+#if COMPILER(GCC) && CPU(X86)
// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
// need to change the assembly trampolines below to match.
@@ -104,6 +117,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x58, JITStackFrame_
COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_offset_matches_ctiTrampoline);
asm volatile (
+".text\n"
".globl " SYMBOL_STRING(ctiTrampoline) "\n"
HIDE_SYMBOL(ctiTrampoline) "\n"
SYMBOL_STRING(ctiTrampoline) ":" "\n"
@@ -131,7 +145,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
#if !USE(JIT_STUB_ARGUMENT_VA_LIST)
"movl %esp, %ecx" "\n"
#endif
- "call " SYMBOL_STRING(cti_vm_throw) "\n"
+ "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n"
"addl $0x3c, %esp" "\n"
"popl %ebx" "\n"
"popl %edi" "\n"
@@ -152,7 +166,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"ret" "\n"
);
-#elif COMPILER(GCC) && PLATFORM(X86_64)
+#elif COMPILER(GCC) && CPU(X86_64)
#if USE(JIT_STUB_ARGUMENT_VA_LIST)
#error "JIT_STUB_ARGUMENT_VA_LIST not supported on x86-64."
@@ -197,7 +211,7 @@ asm volatile (
HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
"movq %rsp, %rdi" "\n"
- "call " SYMBOL_STRING(cti_vm_throw) "\n"
+ "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n"
"addq $0x48, %rsp" "\n"
"popq %rbx" "\n"
"popq %r15" "\n"
@@ -222,7 +236,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"ret" "\n"
);
-#elif COMPILER(GCC) && PLATFORM(ARM_THUMB2)
+#elif COMPILER(GCC) && CPU(ARM_THUMB2)
#if USE(JIT_STUB_ARGUMENT_VA_LIST)
#error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7."
@@ -232,9 +246,9 @@ asm volatile (
".text" "\n"
".align 2" "\n"
".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+HIDE_SYMBOL(ctiTrampoline) "\n"
".thumb" "\n"
".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n"
-HIDE_SYMBOL(ctiTrampoline) "\n"
SYMBOL_STRING(ctiTrampoline) ":" "\n"
"sub sp, sp, #0x3c" "\n"
"str lr, [sp, #0x20]" "\n"
@@ -259,12 +273,12 @@ asm volatile (
".text" "\n"
".align 2" "\n"
".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
".thumb" "\n"
".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n"
-HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
"cpy r0, sp" "\n"
- "bl " SYMBOL_STRING(cti_vm_throw) "\n"
+ "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n"
"ldr r6, [sp, #0x2c]" "\n"
"ldr r5, [sp, #0x28]" "\n"
"ldr r4, [sp, #0x24]" "\n"
@@ -277,9 +291,9 @@ asm volatile (
".text" "\n"
".align 2" "\n"
".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
".thumb" "\n"
".thumb_func " THUMB_FUNC_PARAM(ctiOpThrowNotCaught) "\n"
-HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"ldr r6, [sp, #0x2c]" "\n"
"ldr r5, [sp, #0x28]" "\n"
@@ -289,7 +303,44 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"bx lr" "\n"
);
-#elif COMPILER(MSVC)
+#elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+HIDE_SYMBOL(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+ "stmdb sp!, {r1-r3}" "\n"
+ "stmdb sp!, {r4-r8, lr}" "\n"
+ "sub sp, sp, #68" "\n"
+ "mov r4, r2" "\n"
+ "mov r5, #512" "\n"
+ // r0 contains the code
+ "mov lr, pc" "\n"
+ "mov pc, r0" "\n"
+ "add sp, sp, #68" "\n"
+ "ldmia sp!, {r4-r8, lr}" "\n"
+ "add sp, sp, #12" "\n"
+ "mov pc, lr" "\n"
+);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+ "mov r0, sp" "\n"
+ "bl " SYMBOL_STRING(cti_vm_throw) "\n"
+
+// Both has the same return sequence
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+ "add sp, sp, #68" "\n"
+ "ldmia sp!, {r4-r8, lr}" "\n"
+ "add sp, sp, #12" "\n"
+ "mov pc, lr" "\n"
+);
+
+#elif COMPILER(MSVC) && CPU(X86)
#if USE(JIT_STUB_ARGUMENT_VA_LIST)
#error "JIT_STUB_ARGUMENT_VA_LIST configuration not supported on MSVC."
@@ -353,11 +404,13 @@ extern "C" {
}
}
-#endif // COMPILER(GCC) && PLATFORM(X86)
+#else
+ #error "JIT not supported on this platform."
+#endif
#else // USE(JSVALUE32_64)
-#if COMPILER(GCC) && PLATFORM(X86)
+#if COMPILER(GCC) && CPU(X86)
// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
// need to change the assembly trampolines below to match.
@@ -366,6 +419,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x30, JITStackFrame_code_
COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x1c, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
asm volatile (
+".text\n"
".globl " SYMBOL_STRING(ctiTrampoline) "\n"
HIDE_SYMBOL(ctiTrampoline) "\n"
SYMBOL_STRING(ctiTrampoline) ":" "\n"
@@ -393,7 +447,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
#if !USE(JIT_STUB_ARGUMENT_VA_LIST)
"movl %esp, %ecx" "\n"
#endif
- "call " SYMBOL_STRING(cti_vm_throw) "\n"
+ "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n"
"addl $0x1c, %esp" "\n"
"popl %ebx" "\n"
"popl %edi" "\n"
@@ -414,7 +468,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"ret" "\n"
);
-#elif COMPILER(GCC) && PLATFORM(X86_64)
+#elif COMPILER(GCC) && CPU(X86_64)
#if USE(JIT_STUB_ARGUMENT_VA_LIST)
#error "JIT_STUB_ARGUMENT_VA_LIST not supported on x86-64."
@@ -427,6 +481,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x48, JITStackFrame_code_
COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x78, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
asm volatile (
+".text\n"
".globl " SYMBOL_STRING(ctiTrampoline) "\n"
HIDE_SYMBOL(ctiTrampoline) "\n"
SYMBOL_STRING(ctiTrampoline) ":" "\n"
@@ -465,7 +520,7 @@ asm volatile (
HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
"movq %rsp, %rdi" "\n"
- "call " SYMBOL_STRING(cti_vm_throw) "\n"
+ "call " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n"
"addq $0x78, %rsp" "\n"
"popq %rbx" "\n"
"popq %r15" "\n"
@@ -490,7 +545,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"ret" "\n"
);
-#elif COMPILER(GCC) && PLATFORM(ARM_THUMB2)
+#elif COMPILER(GCC) && CPU(ARM_THUMB2)
#if USE(JIT_STUB_ARGUMENT_VA_LIST)
#error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7."
@@ -532,7 +587,7 @@ HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
"cpy r0, sp" "\n"
- "bl " SYMBOL_STRING(cti_vm_throw) "\n"
+ "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n"
"ldr r6, [sp, #0x2c]" "\n"
"ldr r5, [sp, #0x28]" "\n"
"ldr r4, [sp, #0x24]" "\n"
@@ -557,30 +612,24 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"bx lr" "\n"
);
-#elif COMPILER(GCC) && PLATFORM(ARM_TRADITIONAL)
+#elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
asm volatile (
+".text\n"
".globl " SYMBOL_STRING(ctiTrampoline) "\n"
HIDE_SYMBOL(ctiTrampoline) "\n"
SYMBOL_STRING(ctiTrampoline) ":" "\n"
"stmdb sp!, {r1-r3}" "\n"
"stmdb sp!, {r4-r8, lr}" "\n"
- "mov r6, pc" "\n"
- "add r6, r6, #40" "\n"
- "sub sp, sp, #32" "\n"
- "ldr r4, [sp, #60]" "\n"
+ "sub sp, sp, #36" "\n"
+ "mov r4, r2" "\n"
"mov r5, #512" "\n"
- // r0 contains the code
- "add r8, pc, #4" "\n"
- "str r8, [sp, #-4]!" "\n"
+ "mov lr, pc" "\n"
"mov pc, r0" "\n"
- "add sp, sp, #32" "\n"
+ "add sp, sp, #36" "\n"
"ldmia sp!, {r4-r8, lr}" "\n"
"add sp, sp, #12" "\n"
"mov pc, lr" "\n"
-
- // the return instruction
- "ldr pc, [sp], #4" "\n"
);
asm volatile (
@@ -588,22 +637,58 @@ asm volatile (
HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
"mov r0, sp" "\n"
- "mov lr, r6" "\n"
- "add r8, pc, #4" "\n"
- "str r8, [sp, #-4]!" "\n"
- "b " SYMBOL_STRING(cti_vm_throw) "\n"
+ "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n"
// Both has the same return sequence
".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
- "add sp, sp, #32" "\n"
+ "add sp, sp, #36" "\n"
"ldmia sp!, {r4-r8, lr}" "\n"
"add sp, sp, #12" "\n"
"mov pc, lr" "\n"
);
-#elif COMPILER(MSVC)
+#elif COMPILER(RVCT) && CPU(ARM_TRADITIONAL)
+
+__asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, JSValue*, Profiler**, JSGlobalData*)
+{
+ ARM
+ stmdb sp!, {r1-r3}
+ stmdb sp!, {r4-r8, lr}
+ sub sp, sp, #36
+ mov r4, r2
+ mov r5, #512
+ mov lr, pc
+ bx r0
+ add sp, sp, #36
+ ldmia sp!, {r4-r8, lr}
+ add sp, sp, #12
+ bx lr
+}
+
+__asm void ctiVMThrowTrampoline()
+{
+ ARM
+ PRESERVE8
+ mov r0, sp
+ bl cti_vm_throw
+ add sp, sp, #36
+ ldmia sp!, {r4-r8, lr}
+ add sp, sp, #12
+ bx lr
+}
+
+__asm void ctiOpThrowNotCaught()
+{
+ ARM
+ add sp, sp, #36
+ ldmia sp!, {r4-r8, lr}
+ add sp, sp, #12
+ bx lr
+}
+
+#elif COMPILER(MSVC) && CPU(X86)
#if USE(JIT_STUB_ARGUMENT_VA_LIST)
#error "JIT_STUB_ARGUMENT_VA_LIST configuration not supported on MSVC."
@@ -666,7 +751,9 @@ extern "C" {
}
}
-#endif // COMPILER(GCC) && PLATFORM(X86)
+#else
+ #error "JIT not supported on this platform."
+#endif
#endif // USE(JSVALUE32_64)
@@ -680,7 +767,7 @@ JITThunks::JITThunks(JSGlobalData* globalData)
{
JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk);
-#if PLATFORM(ARM_THUMB2)
+#if CPU(ARM_THUMB2)
// Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types),
// and the OBJECT_OFFSETOF macro does not appear constantish enough for it to be happy with its use in COMPILE_ASSERT
// macros.
@@ -732,11 +819,15 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co
// Structure transition, cache transition info
if (slot.type() == PutPropertySlot::NewProperty) {
- StructureChain* prototypeChain = structure->prototypeChain(callFrame);
- if (!prototypeChain->isCacheable() || structure->isDictionary()) {
+ if (structure->isDictionary()) {
ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic));
return;
}
+
+ // put_by_id_transition checks the prototype chain for setters.
+ normalizePrototypeChain(callFrame, baseCell);
+
+ StructureChain* prototypeChain = structure->prototypeChain(callFrame);
stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain);
JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress);
return;
@@ -796,35 +887,42 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
return;
}
+ if (structure->isDictionary()) {
+ ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
+ return;
+ }
+
if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
ASSERT(slot.slotBase().isObject());
JSObject* slotBaseObject = asObject(slot.slotBase());
-
+ size_t offset = slot.cachedOffset();
+
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
- if (slotBaseObject->structure()->isDictionary())
- slotBaseObject->setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure()));
+ if (slotBaseObject->structure()->isDictionary()) {
+ slotBaseObject->flattenDictionaryObject();
+ offset = slotBaseObject->structure()->get(propertyName);
+ }
stubInfo->initGetByIdProto(structure, slotBaseObject->structure());
- JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), slot.cachedOffset(), returnAddress);
+ ASSERT(!structure->isDictionary());
+ ASSERT(!slotBaseObject->structure()->isDictionary());
+ JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), offset, returnAddress);
return;
}
- size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot);
+ size_t offset = slot.cachedOffset();
+ size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
if (!count) {
stubInfo->accessType = access_get_by_id_generic;
return;
}
StructureChain* prototypeChain = structure->prototypeChain(callFrame);
- if (!prototypeChain->isCacheable()) {
- ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
- return;
- }
stubInfo->initGetByIdChain(structure, prototypeChain);
- JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, slot.cachedOffset(), returnAddress);
+ JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, offset, returnAddress);
}
#endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
@@ -920,7 +1018,7 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
} \
} while (0)
-#if PLATFORM(ARM_THUMB2)
+#if CPU(ARM_THUMB2)
#define DEFINE_STUB_FUNCTION(rtype, op) \
extern "C" { \
@@ -941,6 +1039,57 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
); \
rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) \
+#elif CPU(ARM_TRADITIONAL) && COMPILER(GCC)
+
+#if USE(JSVALUE32_64)
+#define THUNK_RETURN_ADDRESS_OFFSET 64
+#else
+#define THUNK_RETURN_ADDRESS_OFFSET 32
+#endif
+
+COMPILE_ASSERT(offsetof(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET, JITStackFrame_thunkReturnAddress_offset_mismatch);
+
+#define DEFINE_STUB_FUNCTION(rtype, op) \
+ extern "C" { \
+ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
+ }; \
+ asm volatile ( \
+ ".globl " SYMBOL_STRING(cti_##op) "\n" \
+ HIDE_SYMBOL(cti_##op) "\n" \
+ SYMBOL_STRING(cti_##op) ":" "\n" \
+ "str lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
+ "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \
+ "ldr lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
+ "mov pc, lr" "\n" \
+ ); \
+ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
+
+#elif CPU(ARM_TRADITIONAL) && COMPILER(RVCT)
+
+#define DEFINE_STUB_FUNCTION(rtype, op) rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
+
+/* The following is a workaround for RVCT toolchain; precompiler macros are not expanded before the code is passed to the assembler */
+
+/* The following section is a template to generate code for GeneratedJITStubs_RVCT.h */
+/* The pattern "#xxx#" will be replaced with "xxx" */
+
+/*
+RVCT(extern "C" #rtype# JITStubThunked_#op#(STUB_ARGS_DECLARATION);)
+RVCT(__asm #rtype# cti_#op#(STUB_ARGS_DECLARATION))
+RVCT({)
+RVCT( ARM)
+RVCT( IMPORT JITStubThunked_#op#)
+RVCT( str lr, [sp, #32])
+RVCT( bl JITStubThunked_#op#)
+RVCT( ldr lr, [sp, #32])
+RVCT( bx lr)
+RVCT(})
+RVCT()
+*/
+
+/* Include the generated file */
+#include "GeneratedJITStubs_RVCT.h"
+
#else
#define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION)
#endif
@@ -972,38 +1121,19 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_add)
JSValue v1 = stackFrame.args[0].jsValue();
JSValue v2 = stackFrame.args[1].jsValue();
-
- double left;
- double right = 0.0;
-
- bool rightIsNumber = v2.getNumber(right);
- if (rightIsNumber && v1.getNumber(left))
- return JSValue::encode(jsNumber(stackFrame.globalData, left + right));
-
CallFrame* callFrame = stackFrame.callFrame;
- bool leftIsString = v1.isString();
- if (leftIsString && v2.isString()) {
- RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
- if (UNLIKELY(!value)) {
- throwOutOfMemoryError(callFrame);
- VM_THROW_EXCEPTION();
- }
-
- return JSValue::encode(jsString(stackFrame.globalData, value.release()));
+ if (v1.isString()) {
+ JSValue result = v2.isString()
+ ? jsString(callFrame, asString(v1), asString(v2))
+ : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValue::encode(result);
}
- if (rightIsNumber & leftIsString) {
- RefPtr<UString::Rep> value = v2.isInt32() ?
- concatenate(asString(v1)->value().rep(), v2.asInt32()) :
- concatenate(asString(v1)->value().rep(), right);
-
- if (UNLIKELY(!value)) {
- throwOutOfMemoryError(callFrame);
- VM_THROW_EXCEPTION();
- }
- return JSValue::encode(jsString(stackFrame.globalData, value.release()));
- }
+ double left = 0.0, right;
+ if (v1.getNumber(left) && v2.getNumber(right))
+ return JSValue::encode(jsNumber(stackFrame.globalData, left + right));
// All other cases are pretty uncommon
JSValue result = jsAddSlowCase(callFrame, v1, v2);
@@ -1053,19 +1183,6 @@ DEFINE_STUB_FUNCTION(void, register_file_check)
throwStackOverflowError(oldCallFrame, stackFrame.globalData, ReturnAddressPtr(oldCallFrame->returnPC()), STUB_RETURN_ADDRESS);
}
-DEFINE_STUB_FUNCTION(int, op_loop_if_less)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
- CallFrame* callFrame = stackFrame.callFrame;
-
- bool result = jsLess(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-}
-
DEFINE_STUB_FUNCTION(int, op_loop_if_lesseq)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -1204,7 +1321,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
if (slotBaseObject->structure()->isDictionary())
- slotBaseObject->setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure()));
+ slotBaseObject->flattenDictionaryObject();
// The result fetched should always be the callee!
ASSERT(result == JSValue(callee));
@@ -1222,7 +1339,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
// for now. For now it performs a check on a special object on the global object only used for this
// purpose. The object is in no way exposed, and as such the check will always pass.
if (slot.slotBase() == baseValue) {
- JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject()->methodCallDummy(), STUB_RETURN_ADDRESS);
+ JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
return JSValue::encode(result);
}
}
@@ -1332,14 +1449,15 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
STUB_INIT_STACK_FRAME(stackFrame);
CallFrame* callFrame = stackFrame.callFrame;
+ const Identifier& propertyName = stackFrame.args[1].identifier();
JSValue baseValue = stackFrame.args[0].jsValue();
PropertySlot slot(baseValue);
- JSValue result = baseValue.get(callFrame, stackFrame.args[1].identifier(), slot);
+ JSValue result = baseValue.get(callFrame, propertyName, slot);
CHECK_FOR_EXCEPTION();
- if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isUncacheableDictionary()) {
+ if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) {
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
return JSValue::encode(result);
}
@@ -1350,32 +1468,34 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
ASSERT(slot.slotBase().isObject());
JSObject* slotBaseObject = asObject(slot.slotBase());
+
+ size_t offset = slot.cachedOffset();
if (slot.slotBase() == baseValue)
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
else if (slot.slotBase() == asCell(baseValue)->structure()->prototypeForLookup(callFrame)) {
+ ASSERT(!asCell(baseValue)->structure()->isDictionary());
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
- if (slotBaseObject->structure()->isDictionary())
- slotBaseObject->setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure()));
+ if (slotBaseObject->structure()->isDictionary()) {
+ slotBaseObject->flattenDictionaryObject();
+ offset = slotBaseObject->structure()->get(propertyName);
+ }
int listIndex;
PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
- JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), slot.cachedOffset());
+ JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), offset);
if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
- } else if (size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot)) {
- StructureChain* protoChain = structure->prototypeChain(callFrame);
- if (!protoChain->isCacheable()) {
- ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
- return JSValue::encode(result);
- }
-
+ } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) {
+ ASSERT(!asCell(baseValue)->structure()->isDictionary());
int listIndex;
PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
- JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, slot.cachedOffset());
+
+ StructureChain* protoChain = structure->prototypeChain(callFrame);
+ JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, offset);
if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
@@ -1452,7 +1572,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof)
// ECMA-262 15.3.5.3:
// Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function).
- TypeInfo typeInfo(UnspecifiedType, 0);
+ TypeInfo typeInfo(UnspecifiedType);
if (!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance()) {
CallFrame* callFrame = stackFrame.callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
@@ -1520,7 +1640,7 @@ DEFINE_STUB_FUNCTION(void*, op_call_JSFunction)
{
STUB_INIT_STACK_FRAME(stackFrame);
-#ifndef NDEBUG
+#if !ASSERT_DISABLED
CallData callData;
ASSERT(stackFrame.args[0].jsValue().getCallData(callData) == CallTypeJS);
#endif
@@ -1769,7 +1889,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_construct_JSConstruct)
VM_THROW_EXCEPTION();
}
-#ifndef NDEBUG
+#if !ASSERT_DISABLED
ConstructData constructData;
ASSERT(constructor->getConstructData(constructData) == ConstructTypeJS);
#endif
@@ -1778,7 +1898,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_construct_JSConstruct)
if (stackFrame.args[3].jsValue().isObject())
structure = asObject(stackFrame.args[3].jsValue())->inheritorID();
else
- structure = constructor->scope().node()->globalObject()->emptyObjectStructure();
+ structure = constructor->scope().node()->globalObject->emptyObjectStructure();
#ifdef QT_BUILD_SCRIPT_LIB
return new (stackFrame.globalData) QT_PREPEND_NAMESPACE(QScriptObject)(structure);
#else
@@ -1843,7 +1963,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
} else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) {
// All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string));
- result = asString(baseValue)->getIndex(stackFrame.globalData, i);
+ result = asString(baseValue)->getIndex(callFrame, i);
} else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
// All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_byte_array));
@@ -1874,7 +1994,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
if (LIKELY(subscript.isUInt32())) {
uint32_t i = subscript.asUInt32();
if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
- result = asString(baseValue)->getIndex(stackFrame.globalData, i);
+ result = asString(baseValue)->getIndex(callFrame, i);
else {
result = baseValue.get(callFrame, i);
if (!isJSString(globalData, baseValue))
@@ -2039,19 +2159,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_lesseq)
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(int, op_loop_if_true)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- bool result = src1.toBoolean(callFrame);
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-}
-
DEFINE_STUB_FUNCTION(int, op_load_varargs)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2326,8 +2433,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_inc)
return JSValue::encode(number);
}
-#if USE(JSVALUE32_64)
-
DEFINE_STUB_FUNCTION(int, op_eq)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2335,6 +2440,7 @@ DEFINE_STUB_FUNCTION(int, op_eq)
JSValue src1 = stackFrame.args[0].jsValue();
JSValue src2 = stackFrame.args[1].jsValue();
+#if USE(JSVALUE32_64)
start:
if (src2.isUndefined()) {
return src1.isNull() ||
@@ -2390,20 +2496,20 @@ DEFINE_STUB_FUNCTION(int, op_eq)
if (cell1->isString()) {
if (src2.isInt32())
- return static_cast<JSString*>(cell1)->value().toDouble() == src2.asInt32();
+ return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == src2.asInt32();
if (src2.isDouble())
- return static_cast<JSString*>(cell1)->value().toDouble() == src2.asDouble();
+ return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == src2.asDouble();
if (src2.isTrue())
- return static_cast<JSString*>(cell1)->value().toDouble() == 1.0;
+ return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == 1.0;
if (src2.isFalse())
- return static_cast<JSString*>(cell1)->value().toDouble() == 0.0;
+ return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == 0.0;
JSCell* cell2 = asCell(src2);
if (cell2->isString())
- return static_cast<JSString*>(cell1)->value() == static_cast<JSString*>(cell2)->value();
+ return static_cast<JSString*>(cell1)->value(stackFrame.callFrame) == static_cast<JSString*>(cell2)->value(stackFrame.callFrame);
src2 = asObject(cell2)->toPrimitive(stackFrame.callFrame);
CHECK_FOR_EXCEPTION();
@@ -2420,8 +2526,18 @@ DEFINE_STUB_FUNCTION(int, op_eq)
src1 = asObject(cell1)->toPrimitive(stackFrame.callFrame);
CHECK_FOR_EXCEPTION();
goto start;
+
+#else // USE(JSVALUE32_64)
+ CallFrame* callFrame = stackFrame.callFrame;
+
+ bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return result;
+#endif // USE(JSVALUE32_64)
}
+#if USE(JSVALUE32_64)
+
DEFINE_STUB_FUNCTION(int, op_eq_strings)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2431,26 +2547,10 @@ DEFINE_STUB_FUNCTION(int, op_eq_strings)
ASSERT(string1->isString());
ASSERT(string2->isString());
- return string1->value() == string2->value();
-}
-
-#else // USE(JSVALUE32_64)
-
-DEFINE_STUB_FUNCTION(int, op_eq)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
+ return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame);
}
-#endif // USE(JSVALUE32_64)
+#endif
DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift)
{
@@ -2668,7 +2768,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
Register* newCallFrame = callFrame->registers() + registerOffset;
Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
JSValue thisValue = argv[0].jsValue();
- JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
+ JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject;
if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
JSValue exceptionValue;
@@ -2699,7 +2799,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_throw)
if (!handler) {
*stackFrame.exception = exceptionValue;
- STUB_SET_RETURN_ADDRESS(reinterpret_cast<void*>(ctiOpThrowNotCaught));
+ STUB_SET_RETURN_ADDRESS(FunctionPtr(ctiOpThrowNotCaught).value());
return JSValue::encode(jsNull());
}
@@ -2714,18 +2814,22 @@ DEFINE_STUB_FUNCTION(JSPropertyNameIterator*, op_get_pnames)
{
STUB_INIT_STACK_FRAME(stackFrame);
- return JSPropertyNameIterator::create(stackFrame.callFrame, stackFrame.args[0].jsValue());
+ CallFrame* callFrame = stackFrame.callFrame;
+ JSObject* o = stackFrame.args[0].jsObject();
+ Structure* structure = o->structure();
+ JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
+ if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame))
+ jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o);
+ return jsPropertyNameIterator;
}
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_next_pname)
+DEFINE_STUB_FUNCTION(int, has_property)
{
STUB_INIT_STACK_FRAME(stackFrame);
- JSPropertyNameIterator* it = stackFrame.args[0].propertyNameIterator();
- JSValue temp = it->next(stackFrame.callFrame);
- if (!temp)
- it->invalidate();
- return JSValue::encode(temp);
+ JSObject* base = stackFrame.args[0].jsObject();
+ JSString* property = stackFrame.args[1].jsString();
+ return base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value(stackFrame.callFrame)));
}
DEFINE_STUB_FUNCTION(JSObject*, op_push_scope)
@@ -2802,7 +2906,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_stricteq)
JSValue src1 = stackFrame.args[0].jsValue();
JSValue src2 = stackFrame.args[1].jsValue();
- return JSValue::encode(jsBoolean(JSValue::strictEqual(src1, src2)));
+ return JSValue::encode(jsBoolean(JSValue::strictEqual(stackFrame.callFrame, src1, src2)));
}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_primitive)
@@ -2816,7 +2920,9 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_strcat)
{
STUB_INIT_STACK_FRAME(stackFrame);
- return JSValue::encode(concatenateStrings(stackFrame.callFrame, &stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32()));
+ JSValue result = jsString(stackFrame.callFrame, &stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32());
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValue::encode(result);
}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_nstricteq)
@@ -2826,7 +2932,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_nstricteq)
JSValue src1 = stackFrame.args[0].jsValue();
JSValue src2 = stackFrame.args[1].jsValue();
- return JSValue::encode(jsBoolean(!JSValue::strictEqual(src1, src2)));
+ return JSValue::encode(jsBoolean(!JSValue::strictEqual(stackFrame.callFrame, src1, src2)));
}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_jsnumber)
@@ -2935,7 +3041,7 @@ DEFINE_STUB_FUNCTION(void*, op_switch_char)
void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
if (scrutinee.isString()) {
- UString::Rep* value = asString(scrutinee)->value().rep();
+ UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
if (value->size() == 1)
result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->data()[0]).executableAddress();
}
@@ -2955,7 +3061,7 @@ DEFINE_STUB_FUNCTION(void*, op_switch_string)
void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
if (scrutinee.isString()) {
- UString::Rep* value = asString(scrutinee)->value().rep();
+ UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress();
}
@@ -3034,9 +3140,8 @@ DEFINE_STUB_FUNCTION(void, op_debug)
int debugHookID = stackFrame.args[0].int32();
int firstLine = stackFrame.args[1].int32();
int lastLine = stackFrame.args[2].int32();
- int column = stackFrame.args[3].int32();
- stackFrame.globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
+ stackFrame.globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
}
#ifdef QT_BUILD_SCRIPT_LIB
@@ -3092,6 +3197,14 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, vm_throw)
return JSValue::encode(exceptionValue);
}
+DEFINE_STUB_FUNCTION(EncodedJSValue, to_object)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+
+ CallFrame* callFrame = stackFrame.callFrame;
+ return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame));
+}
+
} // namespace JSC
- #endif // ENABLE(JIT)
+#endif // ENABLE(JIT)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h
index c2b8c02..da80133 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h
@@ -63,6 +63,7 @@ namespace JSC {
int32_t asInt32;
JSValue jsValue() { return JSValue::decode(asEncodedJSValue); }
+ JSObject* jsObject() { return static_cast<JSObject*>(asPointer); }
Identifier& identifier() { return *static_cast<Identifier*>(asPointer); }
int32_t int32() { return asInt32; }
CodeBlock* codeBlock() { return static_cast<CodeBlock*>(asPointer); }
@@ -74,7 +75,7 @@ namespace JSC {
ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); }
};
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
struct JITStackFrame {
void* reserved; // Unused
JITStubArg args[6];
@@ -98,7 +99,7 @@ namespace JSC {
// When JIT code makes a call, it pushes its return address just below the rest of the stack.
ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
};
-#elif PLATFORM(X86)
+#elif CPU(X86)
#if COMPILER(MSVC)
#pragma pack(push)
#pragma pack(4)
@@ -129,7 +130,7 @@ namespace JSC {
#if COMPILER(MSVC)
#pragma pack(pop)
#endif // COMPILER(MSVC)
-#elif PLATFORM(ARM_THUMB2)
+#elif CPU(ARM_THUMB2)
struct JITStackFrame {
void* reserved; // Unused
JITStubArg args[6];
@@ -157,11 +158,13 @@ namespace JSC {
ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
};
-#elif PLATFORM(ARM_TRADITIONAL)
+#elif CPU(ARM_TRADITIONAL)
struct JITStackFrame {
JITStubArg padding; // Unused
JITStubArg args[7];
+ ReturnAddressPtr thunkReturnAddress;
+
void* preservedR4;
void* preservedR5;
void* preservedR6;
@@ -172,16 +175,20 @@ namespace JSC {
RegisterFile* registerFile;
CallFrame* callFrame;
JSValue* exception;
+
+ // These arguments passed on the stack.
Profiler** enabledProfilerReference;
JSGlobalData* globalData;
// When JIT code makes a call, it pushes its return address just below the rest of the stack.
- ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
+ ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
};
#else
#error "JITStackFrame not defined for this platform."
#endif
+#define JITSTACKFRAME_ARGS_INDEX (OBJECT_OFFSETOF(JITStackFrame, args) / sizeof(void*))
+
#if USE(JIT_STUB_ARGUMENT_VA_LIST)
#define STUB_ARGS_DECLARATION void* args, ...
#define STUB_ARGS (reinterpret_cast<void**>(vl_args) - 1)
@@ -195,16 +202,16 @@ namespace JSC {
#define STUB_ARGS_DECLARATION void** args
#define STUB_ARGS (args)
- #if PLATFORM(X86) && COMPILER(MSVC)
+ #if CPU(X86) && COMPILER(MSVC)
#define JIT_STUB __fastcall
- #elif PLATFORM(X86) && COMPILER(GCC)
+ #elif CPU(X86) && COMPILER(GCC)
#define JIT_STUB __attribute__ ((fastcall))
#else
#define JIT_STUB
#endif
#endif
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
struct VoidPtrPair {
void* first;
void* second;
@@ -289,7 +296,6 @@ extern "C" {
EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_mul(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION);
- EncodedJSValue JIT_STUB cti_op_next_pname(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_post_dec(STUB_ARGS_DECLARATION);
@@ -311,6 +317,7 @@ extern "C" {
EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION);
+ EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_new_error(STUB_ARGS_DECLARATION);
@@ -332,10 +339,9 @@ extern "C" {
int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION);
int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION);
int JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION);
- int JIT_STUB cti_op_loop_if_less(STUB_ARGS_DECLARATION);
int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS_DECLARATION);
- int JIT_STUB cti_op_loop_if_true(STUB_ARGS_DECLARATION);
int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION);
+ int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION);
void JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION);
void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS_DECLARATION);
void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp
index ee4e393..252fb96 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/jsc.cpp
@@ -29,6 +29,7 @@
#include "JSArray.h"
#include "JSFunction.h"
#include "JSLock.h"
+#include "JSString.h"
#include "PrototypeFunction.h"
#include "SamplingTool.h"
#include <math.h>
@@ -36,7 +37,7 @@
#include <stdlib.h>
#include <string.h>
-#if !PLATFORM(WIN_OS)
+#if !OS(WINDOWS)
#include <unistd.h>
#endif
@@ -53,10 +54,10 @@
#include <signal.h>
#endif
-#if COMPILER(MSVC) && !PLATFORM(WINCE)
+#if COMPILER(MSVC) && !OS(WINCE)
#include <crtdbg.h>
-#include <windows.h>
#include <mmsystem.h>
+#include <windows.h>
#endif
#if PLATFORM(QT)
@@ -87,8 +88,8 @@ static JSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState*, JSObject*, J
struct Script {
bool isFile;
- char *argument;
-
+ char* argument;
+
Script(bool isFile, char *argument)
: isFile(isFile)
, argument(argument)
@@ -173,12 +174,12 @@ GlobalObject::GlobalObject(const Vector<UString>& arguments)
JSValue JSC_HOST_CALL functionPrint(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
for (unsigned i = 0; i < args.size(); ++i) {
- if (i != 0)
+ if (i)
putchar(' ');
-
+
printf("%s", args.at(i).toString(exec).UTF8String().c_str());
}
-
+
putchar('\n');
fflush(stdout);
return jsUndefined();
@@ -193,7 +194,7 @@ JSValue JSC_HOST_CALL functionDebug(ExecState* exec, JSObject*, JSValue, const A
JSValue JSC_HOST_CALL functionGC(ExecState* exec, JSObject*, JSValue, const ArgList&)
{
JSLock lock(SilenceAssertionsOnly);
- exec->heap()->collect();
+ exec->heap()->collectAllGarbage();
return jsUndefined();
}
@@ -291,8 +292,18 @@ JSValue JSC_HOST_CALL functionReadline(ExecState* exec, JSObject*, JSValue, cons
JSValue JSC_HOST_CALL functionQuit(ExecState* exec, JSObject*, JSValue, const ArgList&)
{
+ // Technically, destroying the heap in the middle of JS execution is a no-no,
+ // but we want to maintain compatibility with the Mozilla test suite, so
+ // we pretend that execution has terminated to avoid ASSERTs, then tear down the heap.
+ exec->globalData().dynamicGlobalObject = 0;
+
cleanupGlobalData(&exec->globalData());
exit(EXIT_SUCCESS);
+
+#if COMPILER(MSVC) && OS(WINCE)
+ // Without this, Visual Studio will complain that this method does not return a value.
+ return jsUndefined();
+#endif
}
// Use SEH for Release builds only to get rid of the crash report dialog
@@ -312,7 +323,7 @@ int jscmain(int argc, char** argv, JSGlobalData*);
int main(int argc, char** argv)
{
-#if defined(_DEBUG) && PLATFORM(WIN_OS)
+#if defined(_DEBUG) && OS(WINDOWS)
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
@@ -321,7 +332,7 @@ int main(int argc, char** argv)
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
#endif
-#if COMPILER(MSVC) && !PLATFORM(WINCE)
+#if COMPILER(MSVC) && !OS(WINCE)
timeBeginPeriod(1);
#endif
@@ -360,11 +371,8 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
if (dump)
BytecodeGenerator::setDumpsGeneratedCode(true);
-#if ENABLE(OPCODE_SAMPLING)
- Interpreter* interpreter = globalObject->globalData()->interpreter;
- interpreter->setSampler(new SamplingTool(interpreter));
- interpreter->sampler()->setup();
-#endif
+ JSGlobalData* globalData = globalObject->globalData();
+
#if ENABLE(SAMPLING_FLAGS)
SamplingFlags::start();
#endif
@@ -381,9 +389,7 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
fileName = "[Command Line]";
}
-#if ENABLE(SAMPLING_THREAD)
- SamplingThread::start();
-#endif
+ globalData->startSampling();
Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script, fileName));
success = success && completion.complType() != Throw;
@@ -394,20 +400,14 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr
printf("End: %s\n", completion.value().toString(globalObject->globalExec()).ascii());
}
-#if ENABLE(SAMPLING_THREAD)
- SamplingThread::stop();
-#endif
-
+ globalData->stopSampling();
globalObject->globalExec()->clearException();
}
#if ENABLE(SAMPLING_FLAGS)
SamplingFlags::stop();
#endif
-#if ENABLE(OPCODE_SAMPLING)
- interpreter->sampler()->dump(globalObject->globalExec());
- delete interpreter->sampler();
-#endif
+ globalData->dumpSampleData(globalObject->globalExec());
#if ENABLE(SAMPLING_COUNTERS)
AbstractSamplingCounter::dump();
#endif
@@ -473,30 +473,27 @@ static void parseArguments(int argc, char** argv, Options& options, JSGlobalData
int i = 1;
for (; i < argc; ++i) {
const char* arg = argv[i];
- if (strcmp(arg, "-f") == 0) {
+ if (!strcmp(arg, "-f")) {
if (++i == argc)
printUsageStatement(globalData);
options.scripts.append(Script(true, argv[i]));
continue;
}
- if (strcmp(arg, "-e") == 0) {
+ if (!strcmp(arg, "-e")) {
if (++i == argc)
printUsageStatement(globalData);
options.scripts.append(Script(false, argv[i]));
continue;
}
- if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
- printUsageStatement(globalData, true);
- }
- if (strcmp(arg, "-i") == 0) {
+ if (!strcmp(arg, "-i")) {
options.interactive = true;
continue;
}
- if (strcmp(arg, "-d") == 0) {
+ if (!strcmp(arg, "-d")) {
options.dump = true;
continue;
}
- if (strcmp(arg, "-s") == 0) {
+ if (!strcmp(arg, "-s")) {
#if HAVE(SIGNAL_H)
signal(SIGILL, _exit);
signal(SIGFPE, _exit);
@@ -505,16 +502,18 @@ static void parseArguments(int argc, char** argv, Options& options, JSGlobalData
#endif
continue;
}
- if (strcmp(arg, "--") == 0) {
+ if (!strcmp(arg, "--")) {
++i;
break;
}
+ if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
+ printUsageStatement(globalData, true);
options.scripts.append(Script(true, argv[i]));
}
-
+
if (options.scripts.isEmpty())
options.interactive = true;
-
+
for (; i < argc; ++i)
options.arguments.append(argv[i]);
}
@@ -542,20 +541,20 @@ static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>&
return false;
}
- size_t buffer_size = 0;
- size_t buffer_capacity = 1024;
+ size_t bufferSize = 0;
+ size_t bufferCapacity = 1024;
- buffer.resize(buffer_capacity);
+ buffer.resize(bufferCapacity);
while (!feof(f) && !ferror(f)) {
- buffer_size += fread(buffer.data() + buffer_size, 1, buffer_capacity - buffer_size, f);
- if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
- buffer_capacity *= 2;
- buffer.resize(buffer_capacity);
+ bufferSize += fread(buffer.data() + bufferSize, 1, bufferCapacity - bufferSize, f);
+ if (bufferSize == bufferCapacity) { // guarantees space for trailing '\0'
+ bufferCapacity *= 2;
+ buffer.resize(bufferCapacity);
}
}
fclose(f);
- buffer[buffer_size] = '\0';
+ buffer[bufferSize] = '\0';
return true;
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/WinMain.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/WinMain.cpp
new file mode 100644
index 0000000..17800d0
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/os-win32/WinMain.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009 Patrick Gansterer (paroga@paroga.com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "Vector.h"
+#include <winbase.h>
+#include <winnls.h>
+#include <wtf/UnusedParam.h>
+
+int main(int argc, char** argv);
+
+static inline char* convertToUtf8(LPCWSTR widecharString, int length)
+{
+ int requiredSize = WideCharToMultiByte(CP_UTF8, 0, widecharString, length, 0, 0, 0, 0);
+ char* multibyteString = new char[requiredSize + 1];
+
+ WideCharToMultiByte(CP_UTF8, 0, widecharString, length, multibyteString, requiredSize, 0, 0);
+ multibyteString[requiredSize] = '\0';
+
+ return multibyteString;
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
+{
+ UNUSED_PARAM(hInstance);
+ UNUSED_PARAM(hPrevInstance);
+ UNUSED_PARAM(nCmdShow);
+
+ Vector<char*> arguments;
+ TCHAR buffer[MAX_PATH];
+
+ int length = GetModuleFileNameW(0, buffer, MAX_PATH);
+ arguments.append(convertToUtf8(buffer, length));
+
+ WCHAR* commandLine = lpCmdLine;
+ while (commandLine[0] != '\0') {
+ int commandLineLength = 1;
+ WCHAR endChar = ' ';
+
+ while (commandLine[0] == ' ')
+ ++commandLine;
+
+ if (commandLine[0] == '\"') {
+ ++commandLine;
+ endChar = '\"';
+ }
+
+ while (commandLine[commandLineLength] != endChar && commandLine[commandLineLength] != '\0')
+ ++commandLineLength;
+
+ arguments.append(convertToUtf8(commandLine, commandLineLength));
+
+ commandLine += commandLineLength;
+ if (endChar != ' ' && commandLine[0] != '\0')
+ ++commandLine;
+ }
+
+ int res = main(arguments.size(), arguments.data());
+
+ for (size_t i = 0; i < arguments.size(); i++)
+ delete arguments[i];
+
+ return res;
+}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Grammar.y b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Grammar.y
index fa4ffd0..717a266 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Grammar.y
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Grammar.y
@@ -27,6 +27,7 @@
#include "JSObject.h"
#include "JSString.h"
+#include "Lexer.h"
#include "NodeConstructors.h"
#include "NodeInfo.h"
#include <stdlib.h>
@@ -42,13 +43,12 @@
// Default values for bison.
#define YYDEBUG 0 // Set to 1 to debug a parse error.
#define jscyydebug 0 // Set to 1 to debug a parse error.
-#if !PLATFORM(DARWIN)
+#if !OS(DARWIN)
// Avoid triggering warnings in older bison by not setting this on the Darwin platform.
// FIXME: Is this still needed?
#define YYERROR_VERBOSE
#endif
-int jscyylex(void* lvalp, void* llocp, void* globalPtr);
int jscyyerror(const char*);
static inline bool allowAutomaticSemicolon(JSC::Lexer&, int);
@@ -179,7 +179,7 @@ static inline void appendToVarDeclarationList(JSGlobalData* globalData, ParserAr
template <typename T> inline void setStatementLocation(StatementNode* statement, const T& start, const T& end)
{
- statement->setLoc(start.first_line, end.last_line, start.first_column);
+ statement->setLoc(start.first_line, end.last_line);
}
static inline void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.cpp
index a85ed3d..e616c7a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.cpp
@@ -39,19 +39,10 @@ using namespace Unicode;
// We can't specify the namespace in yacc's C output, so do it here instead.
using namespace JSC;
-#ifndef KDE_USE_FINAL
#include "Grammar.h"
-#endif
-
#include "Lookup.h"
#include "Lexer.lut.h"
-// A bridge for yacc from the C world to the C++ world.
-int jscyylex(void* lvalp, void* llocp, void* globalData)
-{
- return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp);
-}
-
namespace JSC {
static const UChar byteOrderMark = 0xFEFF;
@@ -652,6 +643,8 @@ inStringEscapeSequence:
shiftLineTerminator();
goto inString;
}
+ if (m_current == -1)
+ goto returnError;
record16(singleEscape(m_current));
shift1();
goto inString;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.h
index 174e05a..c76696c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Lexer.h
@@ -136,6 +136,12 @@ namespace JSC {
return (convertHex(c1, c2) << 8) | convertHex(c3, c4);
}
+ // A bridge for yacc from the C world to the C++ world.
+ inline int jscyylex(void* lvalp, void* llocp, void* globalData)
+ {
+ return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp);
+ }
+
} // namespace JSC
#endif // Lexer_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/NodeConstructors.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/NodeConstructors.h
index 5431e18..8c9135f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/NodeConstructors.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/NodeConstructors.h
@@ -46,7 +46,6 @@ namespace JSC {
inline StatementNode::StatementNode(JSGlobalData* globalData)
: Node(globalData)
, m_lastLine(-1)
- , m_column(-1)
{
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp
index 89bbc11..4b97e9a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.cpp
@@ -49,71 +49,13 @@ using namespace WTF;
namespace JSC {
-/*
- Details of the emitBytecode function.
-
- Return value: The register holding the production's value.
- dst: An optional parameter specifying the most efficient destination at
- which to store the production's value. The callee must honor dst.
-
- The dst argument provides for a crude form of copy propagation. For example,
-
- x = 1
-
- becomes
-
- load r[x], 1
-
- instead of
-
- load r0, 1
- mov r[x], r0
-
- because the assignment node, "x =", passes r[x] as dst to the number node, "1".
-*/
-
-// ------------------------------ ThrowableExpressionData --------------------------------
-
-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;
-}
-
-RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message)
-{
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message));
- generator.emitThrow(exception);
- return exception;
-}
-
-RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const UString& label)
-{
- UString message = messageTemplate;
- substitute(message, label);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message));
- generator.emitThrow(exception);
- return exception;
-}
-
-inline RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const Identifier& label)
-{
- return emitThrowError(generator, type, messageTemplate, label.ustring());
-}
// ------------------------------ StatementNode --------------------------------
-void StatementNode::setLoc(int firstLine, int lastLine, int column)
+void StatementNode::setLoc(int firstLine, int lastLine)
{
m_line = firstLine;
m_lastLine = lastLine;
- m_column = column;
}
// ------------------------------ SourceElements --------------------------------
@@ -131,1754 +73,6 @@ inline StatementNode* SourceElements::singleStatement() const
return size == 1 ? m_statements[0] : 0;
}
-inline StatementNode* SourceElements::lastStatement() const
-{
- size_t size = m_statements.size();
- return size ? m_statements[size - 1] : 0;
-}
-
-// ------------------------------ NullNode -------------------------------------
-
-RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (dst == generator.ignoredResult())
- return 0;
- return generator.emitLoad(dst, jsNull());
-}
-
-// ------------------------------ BooleanNode ----------------------------------
-
-RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (dst == generator.ignoredResult())
- return 0;
- return generator.emitLoad(dst, m_value);
-}
-
-// ------------------------------ NumberNode -----------------------------------
-
-RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (dst == generator.ignoredResult())
- return 0;
- return generator.emitLoad(dst, m_value);
-}
-
-// ------------------------------ StringNode -----------------------------------
-
-RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (dst == generator.ignoredResult())
- return 0;
- return generator.emitLoad(dst, m_value);
-}
-
-// ------------------------------ RegExpNode -----------------------------------
-
-RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern.ustring(), m_flags.ustring());
- if (!regExp->isValid())
- return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage());
- if (dst == generator.ignoredResult())
- return 0;
- return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
-}
-
-// ------------------------------ ThisNode -------------------------------------
-
-RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (dst == generator.ignoredResult())
- return 0;
- return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
-}
-
-// ------------------------------ ResolveNode ----------------------------------
-
-bool ResolveNode::isPure(BytecodeGenerator& generator) const
-{
- return generator.isLocal(m_ident);
-}
-
-RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (RegisterID* local = generator.registerFor(m_ident)) {
- if (dst == generator.ignoredResult())
- return 0;
- return generator.moveToDestinationIfNeeded(dst, local);
- }
-
- generator.emitExpressionInfo(m_startOffset + m_ident.size(), m_ident.size(), 0);
- return generator.emitResolve(generator.finalDestination(dst), m_ident);
-}
-
-// ------------------------------ ArrayNode ------------------------------------
-
-RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- // FIXME: Should we put all of this code into emitNewArray?
-
- unsigned length = 0;
- ElementNode* firstPutElement;
- for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
- if (firstPutElement->elision())
- break;
- ++length;
- }
-
- if (!firstPutElement && !m_elision)
- return generator.emitNewArray(generator.finalDestination(dst), m_element);
-
- RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element);
-
- for (ElementNode* n = firstPutElement; n; n = n->next()) {
- RegisterID* value = generator.emitNode(n->value());
- length += n->elision();
- generator.emitPutByIndex(array.get(), length++, value);
- }
-
- if (m_elision) {
- RegisterID* value = generator.emitLoad(0, jsNumber(generator.globalData(), m_elision + length));
- generator.emitPutById(array.get(), generator.propertyNames().length, value);
- }
-
- return generator.moveToDestinationIfNeeded(dst, array.get());
-}
-
-bool ArrayNode::isSimpleArray() const
-{
- if (m_elision || m_optional)
- return false;
- for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
- if (ptr->elision())
- return false;
- }
- return true;
-}
-
-ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData) const
-{
- ASSERT(!m_elision && !m_optional);
- ElementNode* ptr = m_element;
- if (!ptr)
- return 0;
- ArgumentListNode* head = new (globalData) ArgumentListNode(globalData, ptr->value());
- ArgumentListNode* tail = head;
- ptr = ptr->next();
- for (; ptr; ptr = ptr->next()) {
- ASSERT(!ptr->elision());
- tail = new (globalData) ArgumentListNode(globalData, tail, ptr->value());
- }
- return head;
-}
-
-// ------------------------------ ObjectLiteralNode ----------------------------
-
-RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (!m_list) {
- if (dst == generator.ignoredResult())
- return 0;
- return generator.emitNewObject(generator.finalDestination(dst));
- }
- return generator.emitNode(dst, m_list);
-}
-
-// ------------------------------ PropertyListNode -----------------------------
-
-RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> newObj = generator.tempDestination(dst);
-
- generator.emitNewObject(newObj.get());
-
- for (PropertyListNode* p = this; p; p = p->m_next) {
- RegisterID* value = generator.emitNode(p->m_node->m_assign);
-
- switch (p->m_node->m_type) {
- case PropertyNode::Constant: {
- generator.emitPutById(newObj.get(), p->m_node->name(), value);
- break;
- }
- case PropertyNode::Getter: {
- generator.emitPutGetter(newObj.get(), p->m_node->name(), value);
- break;
- }
- case PropertyNode::Setter: {
- generator.emitPutSetter(newObj.get(), p->m_node->name(), value);
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
- return generator.moveToDestinationIfNeeded(dst, newObj.get());
-}
-
-// ------------------------------ BracketAccessorNode --------------------------------
-
-RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
- RegisterID* property = generator.emitNode(m_subscript);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
-}
-
-// ------------------------------ DotAccessorNode --------------------------------
-
-RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RegisterID* base = generator.emitNode(m_base);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
-}
-
-// ------------------------------ ArgumentListNode -----------------------------
-
-RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- ASSERT(m_expr);
- return generator.emitNode(dst, m_expr);
-}
-
-// ------------------------------ NewExprNode ----------------------------------
-
-RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> func = generator.emitNode(m_expr);
- return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args, divot(), startOffset(), endOffset());
-}
-
-// ------------------------------ EvalFunctionCallNode ----------------------------------
-
-RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> func = generator.tempDestination(dst);
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
- generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
- generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
- return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
-}
-
-// ------------------------------ FunctionCallValueNode ----------------------------------
-
-RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> func = generator.emitNode(m_expr);
- RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
- return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
-}
-
-// ------------------------------ FunctionCallResolveNode ----------------------------------
-
-RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
- RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
- return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args, 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);
- RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
- return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
- }
-
- RefPtr<RegisterID> func = generator.newTemporary();
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
- int identifierStart = divot() - startOffset();
- generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
- generator.emitResolveWithBase(thisRegister.get(), func.get(), m_ident);
- return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
-}
-
-// ------------------------------ FunctionCallBracketNode ----------------------------------
-
-RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> base = generator.emitNode(m_base);
- RegisterID* property = generator.emitNode(m_subscript);
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
- RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
- RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
- return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
-}
-
-// ------------------------------ FunctionCallDotNode ----------------------------------
-
-RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> function = generator.tempDestination(dst);
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
- generator.emitNode(thisRegister.get(), m_base);
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
- generator.emitMethodCheck();
- generator.emitGetById(function.get(), thisRegister.get(), m_ident);
- return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
-}
-
-RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<Label> realCall = generator.newLabel();
- RefPtr<Label> end = generator.newLabel();
- RefPtr<RegisterID> base = generator.emitNode(m_base);
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
- RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
- RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
- generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
- {
- RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
- ArgumentListNode* oldList = m_args->m_listNode;
- if (m_args->m_listNode && m_args->m_listNode->m_expr) {
- generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
- m_args->m_listNode = m_args->m_listNode->m_next;
- } else
- generator.emitLoad(thisRegister.get(), jsNull());
-
- generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
- generator.emitJump(end.get());
- m_args->m_listNode = oldList;
- }
- generator.emitLabel(realCall.get());
- {
- RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
- generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
- }
- generator.emitLabel(end.get());
- return finalDestination.get();
-}
-
-static bool areTrivialApplyArguments(ArgumentsNode* args)
-{
- return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
- || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
-}
-
-RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- // A few simple cases can be trivially handled as ordinary function calls.
- // function.apply(), function.apply(arg) -> identical to function.call
- // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
- bool mayBeCall = areTrivialApplyArguments(m_args);
-
- RefPtr<Label> realCall = generator.newLabel();
- RefPtr<Label> end = generator.newLabel();
- RefPtr<RegisterID> base = generator.emitNode(m_base);
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
- RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
- RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
- generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
- {
- if (mayBeCall) {
- RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
- ArgumentListNode* oldList = m_args->m_listNode;
- if (m_args->m_listNode && m_args->m_listNode->m_expr) {
- generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
- m_args->m_listNode = m_args->m_listNode->m_next;
- if (m_args->m_listNode) {
- ASSERT(m_args->m_listNode->m_expr->isSimpleArray());
- ASSERT(!m_args->m_listNode->m_next);
- m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_expr)->toArgumentList(generator.globalData());
- }
- } else
- generator.emitLoad(thisRegister.get(), jsNull());
- generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
- m_args->m_listNode = oldList;
- } else {
- ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
- RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
- RefPtr<RegisterID> argsCountRegister = generator.newTemporary();
- RefPtr<RegisterID> thisRegister = generator.newTemporary();
- RefPtr<RegisterID> argsRegister = generator.newTemporary();
- generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
- ArgumentListNode* args = m_args->m_listNode->m_next;
- bool isArgumentsApply = false;
- if (args->m_expr->isResolveNode()) {
- ResolveNode* resolveNode = static_cast<ResolveNode*>(args->m_expr);
- isArgumentsApply = generator.willResolveToArguments(resolveNode->identifier());
- if (isArgumentsApply)
- generator.emitMove(argsRegister.get(), generator.uncheckedRegisterForArguments());
- }
- if (!isArgumentsApply)
- generator.emitNode(argsRegister.get(), args->m_expr);
- while ((args = args->m_next))
- generator.emitNode(args->m_expr);
-
- generator.emitLoadVarargs(argsCountRegister.get(), argsRegister.get());
- generator.emitCallVarargs(finalDestination.get(), realFunction.get(), thisRegister.get(), argsCountRegister.get(), divot(), startOffset(), endOffset());
- }
- generator.emitJump(end.get());
- }
- generator.emitLabel(realCall.get());
- {
- RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
- generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
- }
- generator.emitLabel(end.get());
- return finalDestination.get();
-}
-
-// ------------------------------ PostfixResolveNode ----------------------------------
-
-static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper)
-{
- return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst);
-}
-
-static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
-{
- if (srcDst == dst)
- return generator.emitToJSNumber(dst, srcDst);
- return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
-}
-
-RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (RegisterID* local = generator.registerFor(m_ident)) {
- if (generator.isLocalConstant(m_ident)) {
- if (dst == generator.ignoredResult())
- return 0;
- return generator.emitToJSNumber(generator.finalDestination(dst), local);
- }
-
- if (dst == generator.ignoredResult())
- return emitPreIncOrDec(generator, local, m_operator);
- return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator);
- }
-
- int index = 0;
- size_t depth = 0;
- JSObject* globalObject = 0;
- 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 == generator.ignoredResult()) {
- oldValue = 0;
- emitPreIncOrDec(generator, value.get(), m_operator);
- } else {
- oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
- }
- generator.emitPutScopedVar(depth, index, value.get(), globalObject);
- return oldValue;
- }
-
- 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 == generator.ignoredResult()) {
- oldValue = 0;
- emitPreIncOrDec(generator, value.get(), m_operator);
- } else {
- oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator);
- }
- generator.emitPutById(base.get(), m_ident, value.get());
- return oldValue;
-}
-
-// ------------------------------ PostfixBracketNode ----------------------------------
-
-RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> base = generator.emitNode(m_base);
- RefPtr<RegisterID> property = generator.emitNode(m_subscript);
-
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
- RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
- RegisterID* oldValue;
- if (dst == generator.ignoredResult()) {
- oldValue = 0;
- if (m_operator == OpPlusPlus)
- generator.emitPreInc(value.get());
- else
- generator.emitPreDec(value.get());
- } else {
- oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
- }
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitPutByVal(base.get(), property.get(), value.get());
- return oldValue;
-}
-
-// ------------------------------ PostfixDotNode ----------------------------------
-
-RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> base = generator.emitNode(m_base);
-
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
- RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
- RegisterID* oldValue;
- if (dst == generator.ignoredResult()) {
- oldValue = 0;
- if (m_operator == OpPlusPlus)
- generator.emitPreInc(value.get());
- else
- generator.emitPreDec(value.get());
- } else {
- oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
- }
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitPutById(base.get(), m_ident, value.get());
- return oldValue;
-}
-
-// ------------------------------ PostfixErrorNode -----------------------------------
-
-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::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (generator.registerFor(m_ident))
- return generator.emitLoad(generator.finalDestination(dst), false);
-
- 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::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> r0 = generator.emitNode(m_base);
- RegisterID* r1 = generator.emitNode(m_subscript);
-
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
-}
-
-// ------------------------------ DeleteDotNode -----------------------------------
-
-RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RegisterID* r0 = generator.emitNode(m_base);
-
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
-}
-
-// ------------------------------ DeleteValueNode -----------------------------------
-
-RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitNode(generator.ignoredResult(), m_expr);
-
- // delete on a non-location expression ignores the value and returns true
- return generator.emitLoad(generator.finalDestination(dst), true);
-}
-
-// ------------------------------ VoidNode -------------------------------------
-
-RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (dst == generator.ignoredResult()) {
- generator.emitNode(generator.ignoredResult(), m_expr);
- return 0;
- }
- RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
- return generator.emitLoad(dst, jsUndefined());
-}
-
-// ------------------------------ TypeOfValueNode -----------------------------------
-
-RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (RegisterID* local = generator.registerFor(m_ident)) {
- 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 == generator.ignoredResult())
- return 0;
- return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
-}
-
-// ------------------------------ TypeOfValueNode -----------------------------------
-
-RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (dst == generator.ignoredResult()) {
- generator.emitNode(generator.ignoredResult(), m_expr);
- return 0;
- }
- RefPtr<RegisterID> src = generator.emitNode(m_expr);
- return generator.emitTypeOf(generator.finalDestination(dst), src.get());
-}
-
-// ------------------------------ PrefixResolveNode ----------------------------------
-
-RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (RegisterID* local = generator.registerFor(m_ident)) {
- if (generator.isLocalConstant(m_ident)) {
- if (dst == generator.ignoredResult())
- return 0;
- RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
- return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
- }
-
- emitPreIncOrDec(generator, local, m_operator);
- return generator.moveToDestinationIfNeeded(dst, local);
- }
-
- int index = 0;
- size_t depth = 0;
- JSObject* globalObject = 0;
- if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
- RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
- emitPreIncOrDec(generator, propDst.get(), m_operator);
- generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
- return generator.moveToDestinationIfNeeded(dst, propDst.get());
- }
-
- 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);
- generator.emitPutById(base.get(), m_ident, propDst.get());
- return generator.moveToDestinationIfNeeded(dst, propDst.get());
-}
-
-// ------------------------------ PrefixBracketNode ----------------------------------
-
-RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> base = generator.emitNode(m_base);
- RefPtr<RegisterID> property = generator.emitNode(m_subscript);
- RefPtr<RegisterID> propDst = generator.tempDestination(dst);
-
- generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
- RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
- if (m_operator == OpPlusPlus)
- generator.emitPreInc(value);
- else
- generator.emitPreDec(value);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitPutByVal(base.get(), property.get(), value);
- return generator.moveToDestinationIfNeeded(dst, propDst.get());
-}
-
-// ------------------------------ PrefixDotNode ----------------------------------
-
-RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> base = generator.emitNode(m_base);
- RefPtr<RegisterID> propDst = generator.tempDestination(dst);
-
- 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(divot(), startOffset(), endOffset());
- generator.emitPutById(base.get(), m_ident, value);
- return generator.moveToDestinationIfNeeded(dst, propDst.get());
-}
-
-// ------------------------------ PrefixErrorNode -----------------------------------
-
-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::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RegisterID* src = generator.emitNode(m_expr);
- return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
-}
-
-// ------------------------------ Binary Operation Nodes -----------------------------------
-
-// BinaryOpNode::emitStrcat:
-//
-// This node generates an op_strcat operation. This opcode can handle concatenation of three or
-// more values, where we can determine a set of separate op_add operations would be operating on
-// string values.
-//
-// This function expects to be operating on a graph of AST nodes looking something like this:
-//
-// (a)... (b)
-// \ /
-// (+) (c)
-// \ /
-// [d] ((+))
-// \ /
-// [+=]
-//
-// The assignment operation is optional, if it exists the register holding the value on the
-// lefthand side of the assignment should be passing as the optional 'lhs' argument.
-//
-// The method should be called on the node at the root of the tree of regular binary add
-// operations (marked in the diagram with a double set of parentheses). This node must
-// be performing a string concatenation (determined by statically detecting that at least
-// one child must be a string).
-//
-// Since the minimum number of values being concatenated together is expected to be 3, if
-// a lhs to a concatenating assignment is not provided then the root add should have at
-// least one left child that is also an add that can be determined to be operating on strings.
-//
-RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
-{
- ASSERT(isAdd());
- ASSERT(resultDescriptor().definitelyIsString());
-
- // Create a list of expressions for all the adds in the tree of nodes we can convert into
- // a string concatenation. The rightmost node (c) is added first. The rightmost node is
- // added first, and the leftmost child is never added, so the vector produced for the
- // example above will be [ c, b ].
- Vector<ExpressionNode*, 16> reverseExpressionList;
- reverseExpressionList.append(m_expr2);
-
- // Examine the left child of the add. So long as this is a string add, add its right-child
- // to the list, and keep processing along the left fork.
- ExpressionNode* leftMostAddChild = m_expr1;
- while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
- reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
- leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
- }
-
- Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
-
- // If there is an assignment, allocate a temporary to hold the lhs after conversion.
- // We could possibly avoid this (the lhs is converted last anyway, we could let the
- // op_strcat node handle its conversion if required).
- if (lhs)
- temporaryRegisters.append(generator.newTemporary());
-
- // Emit code for the leftmost node ((a) in the example).
- temporaryRegisters.append(generator.newTemporary());
- RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
- generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
-
- // Note on ordering of conversions:
- //
- // We maintain the same ordering of conversions as we would see if the concatenations
- // was performed as a sequence of adds (otherwise this optimization could change
- // behaviour should an object have been provided a valueOf or toString method).
- //
- // Considering the above example, the sequnce of execution is:
- // * evaluate operand (a)
- // * evaluate operand (b)
- // * convert (a) to primitive <- (this would be triggered by the first add)
- // * convert (b) to primitive <- (ditto)
- // * evaluate operand (c)
- // * convert (c) to primitive <- (this would be triggered by the second add)
- // And optionally, if there is an assignment:
- // * convert (d) to primitive <- (this would be triggered by the assigning addition)
- //
- // As such we do not plant an op to convert the leftmost child now. Instead, use
- // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
- // once the second node has been generated. However, if the leftmost child is an
- // immediate we can trivially determine that no conversion will be required.
- // If this is the case
- if (leftMostAddChild->isString())
- leftMostAddChildTempRegister = 0;
-
- while (reverseExpressionList.size()) {
- ExpressionNode* node = reverseExpressionList.last();
- reverseExpressionList.removeLast();
-
- // Emit the code for the current node.
- temporaryRegisters.append(generator.newTemporary());
- generator.emitNode(temporaryRegisters.last().get(), node);
-
- // On the first iteration of this loop, when we first reach this point we have just
- // generated the second node, which means it is time to convert the leftmost operand.
- if (leftMostAddChildTempRegister) {
- generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
- leftMostAddChildTempRegister = 0; // Only do this once.
- }
- // Plant a conversion for this node, if necessary.
- if (!node->isString())
- generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
- }
- ASSERT(temporaryRegisters.size() >= 3);
-
- // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
- // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
- if (emitExpressionInfoForMe)
- generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
-
- // If there is an assignment convert the lhs now. This will also copy lhs to
- // the temporary register we allocated for it.
- if (lhs)
- generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
-
- return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
-}
-
-RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- OpcodeID opcodeID = this->opcodeID();
-
- if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString())
- return emitStrcat(generator, dst);
-
- if (opcodeID == op_neq) {
- if (m_expr1->isNull() || m_expr2->isNull()) {
- RefPtr<RegisterID> src = generator.tempDestination(dst);
- generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
- return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
- }
- }
-
- RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
- RegisterID* src2 = generator.emitNode(m_expr2);
- return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
-}
-
-RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (m_expr1->isNull() || m_expr2->isNull()) {
- RefPtr<RegisterID> src = generator.tempDestination(dst);
- generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
- return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
- }
-
- RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
- RegisterID* src2 = generator.emitNode(m_expr2);
- return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
-}
-
-RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
- RegisterID* src2 = generator.emitNode(m_expr2);
- return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
-}
-
-RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
- RegisterID* src2 = generator.emitNode(m_expr2);
- return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));
-}
-
-RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
- RegisterID* src2 = generator.emitNode(m_expr2);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
-}
-
-RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
- RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
-
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitGetByIdExceptionInfo(op_instanceof);
- RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype);
-
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype);
-}
-
-// ------------------------------ LogicalOpNode ----------------------------
-
-RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> temp = generator.tempDestination(dst);
- RefPtr<Label> target = generator.newLabel();
-
- generator.emitNode(temp.get(), m_expr1);
- if (m_operator == OpLogicalAnd)
- generator.emitJumpIfFalse(temp.get(), target.get());
- else
- generator.emitJumpIfTrue(temp.get(), target.get());
- generator.emitNode(temp.get(), m_expr2);
- generator.emitLabel(target.get());
-
- return generator.moveToDestinationIfNeeded(dst, temp.get());
-}
-
-// ------------------------------ ConditionalNode ------------------------------
-
-RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> newDst = generator.finalDestination(dst);
- RefPtr<Label> beforeElse = generator.newLabel();
- RefPtr<Label> afterElse = generator.newLabel();
-
- RegisterID* cond = generator.emitNode(m_logical);
- generator.emitJumpIfFalse(cond, beforeElse.get());
-
- generator.emitNode(newDst.get(), m_expr1);
- generator.emitJump(afterElse.get());
-
- generator.emitLabel(beforeElse.get());
- generator.emitNode(newDst.get(), m_expr2);
-
- generator.emitLabel(afterElse.get());
-
- return newDst.get();
-}
-
-// ------------------------------ ReadModifyResolveNode -----------------------------------
-
-// FIXME: should this be moved to be a method on BytecodeGenerator?
-static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0)
-{
- OpcodeID opcodeID;
- switch (oper) {
- case OpMultEq:
- opcodeID = op_mul;
- break;
- case OpDivEq:
- opcodeID = op_div;
- break;
- case OpPlusEq:
- if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString())
- return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
- opcodeID = op_add;
- break;
- case OpMinusEq:
- opcodeID = op_sub;
- break;
- case OpLShift:
- opcodeID = op_lshift;
- break;
- case OpRShift:
- opcodeID = op_rshift;
- break;
- case OpURShift:
- opcodeID = op_urshift;
- break;
- case OpAndEq:
- opcodeID = op_bitand;
- break;
- case OpXOrEq:
- opcodeID = op_bitxor;
- break;
- case OpOrEq:
- opcodeID = op_bitor;
- break;
- case OpModEq:
- opcodeID = op_mod;
- break;
- default:
- ASSERT_NOT_REACHED();
- return dst;
- }
-
- RegisterID* src2 = generator.emitNode(m_right);
-
- // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
- // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
- if (emitExpressionInfoForMe)
- generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
-
- return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
-}
-
-RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (RegisterID* local = generator.registerFor(m_ident)) {
- if (generator.isLocalConstant(m_ident)) {
- return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
- }
-
- if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
- RefPtr<RegisterID> result = generator.newTemporary();
- generator.emitMove(result.get(), local);
- emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
- generator.emitMove(local, result.get());
- return generator.moveToDestinationIfNeeded(dst, result.get());
- }
-
- RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
- return generator.moveToDestinationIfNeeded(dst, result);
- }
-
- int index = 0;
- size_t depth = 0;
- JSObject* globalObject = 0;
- if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
- RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
- RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
- generator.emitPutScopedVar(depth, index, result, globalObject);
- return result;
- }
-
- RefPtr<RegisterID> src1 = generator.tempDestination(dst);
- generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0);
- RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
- RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
- return generator.emitPutById(base.get(), m_ident, result);
-}
-
-// ------------------------------ AssignResolveNode -----------------------------------
-
-RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (RegisterID* local = generator.registerFor(m_ident)) {
- if (generator.isLocalConstant(m_ident))
- return generator.emitNode(dst, m_right);
-
- RegisterID* result = generator.emitNode(local, m_right);
- return generator.moveToDestinationIfNeeded(dst, result);
- }
-
- int index = 0;
- size_t depth = 0;
- JSObject* globalObject = 0;
- if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
- if (dst == generator.ignoredResult())
- dst = 0;
- RegisterID* value = generator.emitNode(dst, m_right);
- generator.emitPutScopedVar(depth, index, value, globalObject);
- return value;
- }
-
- RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
- if (dst == generator.ignoredResult())
- dst = 0;
- RegisterID* value = generator.emitNode(dst, m_right);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- return generator.emitPutById(base.get(), m_ident, value);
-}
-
-// ------------------------------ AssignDotNode -----------------------------------
-
-RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
- RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
- RegisterID* result = generator.emitNode(value.get(), m_right);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitPutById(base.get(), m_ident, result);
- return generator.moveToDestinationIfNeeded(dst, result);
-}
-
-// ------------------------------ ReadModifyDotNode -----------------------------------
-
-RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
-
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
- RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
- RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
-
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- return generator.emitPutById(base.get(), m_ident, updatedValue);
-}
-
-// ------------------------------ AssignErrorNode -----------------------------------
-
-RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
-{
- return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
-}
-
-// ------------------------------ AssignBracketNode -----------------------------------
-
-RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
- RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
- RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
- RegisterID* result = generator.emitNode(value.get(), m_right);
-
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitPutByVal(base.get(), property.get(), result);
- return generator.moveToDestinationIfNeeded(dst, result);
-}
-
-// ------------------------------ ReadModifyBracketNode -----------------------------------
-
-RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
- RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
-
- generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
- RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
- RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
-
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitPutByVal(base.get(), property.get(), updatedValue);
-
- return updatedValue;
-}
-
-// ------------------------------ CommaNode ------------------------------------
-
-RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- ASSERT(m_expressions.size() > 1);
- for (size_t i = 0; i < m_expressions.size() - 1; i++)
- generator.emitNode(generator.ignoredResult(), m_expressions[i]);
- return generator.emitNode(dst, m_expressions.last());
-}
-
-// ------------------------------ ConstDeclNode ------------------------------------
-
-RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
-{
- if (RegisterID* local = generator.constRegisterFor(m_ident)) {
- if (!m_init)
- return local;
-
- return generator.emitNode(local, m_init);
- }
-
- if (generator.codeType() != EvalCode) {
- if (m_init)
- return generator.emitNode(m_init);
- else
- return generator.emitResolve(generator.newTemporary(), m_ident);
- }
- // FIXME: While this code should only be hit in eval code, it will potentially
- // assign to the wrong base if m_ident exists in an intervening dynamic scope.
- RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
- RegisterID* value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
- return generator.emitPutById(base.get(), m_ident, value);
-}
-
-RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
-{
- RegisterID* result = 0;
- for (ConstDeclNode* n = this; n; n = n->m_next)
- result = n->emitCodeSingle(generator);
-
- return result;
-}
-
-// ------------------------------ ConstStatementNode -----------------------------
-
-RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
- return generator.emitNode(m_next);
-}
-
-// ------------------------------ SourceElements -------------------------------
-
-inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- size_t size = m_statements.size();
- for (size_t i = 0; i < size; ++i)
- generator.emitNode(dst, m_statements[i]);
-}
-
-// ------------------------------ BlockNode ------------------------------------
-
-inline StatementNode* BlockNode::lastStatement() const
-{
- return m_statements ? m_statements->lastStatement() : 0;
-}
-
-RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (m_statements)
- m_statements->emitBytecode(generator, dst);
- return 0;
-}
-
-// ------------------------------ EmptyStatementNode ---------------------------
-
-RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
- return dst;
-}
-
-// ------------------------------ DebuggerStatementNode ---------------------------
-
-RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine(), column());
- return dst;
-}
-
-// ------------------------------ ExprStatementNode ----------------------------
-
-RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- ASSERT(m_expr);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
- return generator.emitNode(dst, m_expr);
-}
-
-// ------------------------------ VarStatementNode ----------------------------
-
-RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
-{
- ASSERT(m_expr);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
- return generator.emitNode(m_expr);
-}
-
-// ------------------------------ IfNode ---------------------------------------
-
-RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- RefPtr<Label> afterThen = generator.newLabel();
-
- RegisterID* cond = generator.emitNode(m_condition);
- generator.emitJumpIfFalse(cond, afterThen.get());
-
- generator.emitNode(dst, m_ifBlock);
- generator.emitLabel(afterThen.get());
-
- // FIXME: This should return the last statement executed so that it can be returned as a Completion.
- return 0;
-}
-
-// ------------------------------ IfElseNode ---------------------------------------
-
-RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- RefPtr<Label> beforeElse = generator.newLabel();
- RefPtr<Label> afterElse = generator.newLabel();
-
- RegisterID* cond = generator.emitNode(m_condition);
- generator.emitJumpIfFalse(cond, beforeElse.get());
-
- generator.emitNode(dst, m_ifBlock);
- generator.emitJump(afterElse.get());
-
- generator.emitLabel(beforeElse.get());
-
- generator.emitNode(dst, m_elseBlock);
-
- generator.emitLabel(afterElse.get());
-
- // FIXME: This should return the last statement executed so that it can be returned as a Completion.
- return 0;
-}
-
-// ------------------------------ DoWhileNode ----------------------------------
-
-RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
-
- RefPtr<Label> topOfLoop = generator.newLabel();
- generator.emitLabel(topOfLoop.get());
-
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
-
- generator.emitLabel(scope->continueTarget());
-#ifndef QT_BUILD_SCRIPT_LIB
- generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), column());
-#endif
- RegisterID* cond = generator.emitNode(m_expr);
- generator.emitJumpIfTrue(cond, topOfLoop.get());
-
- generator.emitLabel(scope->breakTarget());
- return result.get();
-}
-
-// ------------------------------ WhileNode ------------------------------------
-
-RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
-#ifdef QT_BUILD_SCRIPT_LIB
- generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), column());
-#endif
- generator.emitJump(scope->continueTarget());
-
- RefPtr<Label> topOfLoop = generator.newLabel();
- generator.emitLabel(topOfLoop.get());
-
- generator.emitNode(dst, m_statement);
-
- generator.emitLabel(scope->continueTarget());
-#ifndef QT_BUILD_SCRIPT_LIB
- generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), column());
-#endif
- RegisterID* cond = generator.emitNode(m_expr);
- generator.emitJumpIfTrue(cond, topOfLoop.get());
-
- generator.emitLabel(scope->breakTarget());
-
- // FIXME: This should return the last statement executed so that it can be returned as a Completion
- return 0;
-}
-
-// ------------------------------ ForNode --------------------------------------
-
-RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
-
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- if (m_expr1)
- generator.emitNode(generator.ignoredResult(), m_expr1);
-
- RefPtr<Label> condition = generator.newLabel();
- generator.emitJump(condition.get());
-
- RefPtr<Label> topOfLoop = generator.newLabel();
- generator.emitLabel(topOfLoop.get());
-
- RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
-
- generator.emitLabel(scope->continueTarget());
-#ifndef QT_BUILD_SCRIPT_LIB
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-#endif
- if (m_expr3)
- generator.emitNode(generator.ignoredResult(), m_expr3);
-
- generator.emitLabel(condition.get());
- if (m_expr2) {
- RegisterID* cond = generator.emitNode(m_expr2);
- generator.emitJumpIfTrue(cond, topOfLoop.get());
- } else
- generator.emitJump(topOfLoop.get());
-
- generator.emitLabel(scope->breakTarget());
- return result.get();
-}
-
-// ------------------------------ ForInNode ------------------------------------
-
-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<Label> continueTarget = generator.newLabel();
-
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- if (m_init)
- generator.emitNode(generator.ignoredResult(), m_init);
- RegisterID* forInBase = generator.emitNode(m_expr);
- RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
- generator.emitJump(scope->continueTarget());
-
- RefPtr<Label> loopStart = generator.newLabel();
- generator.emitLabel(loopStart.get());
-
- RegisterID* propertyName;
- if (m_lexpr->isResolveNode()) {
- const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
- propertyName = generator.registerFor(ident);
- if (!propertyName) {
- propertyName = generator.newTemporary();
- RefPtr<RegisterID> protect = propertyName;
- RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
-
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitPutById(base, ident, propertyName);
- }
- } else if (m_lexpr->isDotAccessorNode()) {
- DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
- const Identifier& ident = assignNode->identifier();
- propertyName = generator.newTemporary();
- RefPtr<RegisterID> protect = propertyName;
- RegisterID* base = generator.emitNode(assignNode->base());
-
- generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
- generator.emitPutById(base, ident, propertyName);
- } else {
- ASSERT(m_lexpr->isBracketAccessorNode());
- BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
- propertyName = generator.newTemporary();
- RefPtr<RegisterID> protect = propertyName;
- RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
- RegisterID* subscript = generator.emitNode(assignNode->subscript());
-
- generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
- generator.emitPutByVal(base.get(), subscript, propertyName);
- }
-
- generator.emitNode(dst, m_statement);
-
- generator.emitLabel(scope->continueTarget());
- generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
-#ifndef QT_BUILD_SCRIPT_LIB
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-#endif
- generator.emitLabel(scope->breakTarget());
- return dst;
-}
-
-// ------------------------------ ContinueNode ---------------------------------
-
-// ECMA 12.7
-RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- LabelScope* scope = generator.continueTarget(m_ident);
-
- if (!scope)
- return m_ident.isEmpty()
- ? emitThrowError(generator, SyntaxError, "Invalid continue statement.")
- : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
-
- generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth());
- return dst;
-}
-
-// ------------------------------ BreakNode ------------------------------------
-
-// ECMA 12.8
-RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- LabelScope* scope = generator.breakTarget(m_ident);
-
- if (!scope)
- return m_ident.isEmpty()
- ? emitThrowError(generator, SyntaxError, "Invalid break statement.")
- : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident);
-
- generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth());
- return dst;
-}
-
-// ------------------------------ ReturnNode -----------------------------------
-
-RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
- if (generator.codeType() != FunctionCode)
- return emitThrowError(generator, SyntaxError, "Invalid return statement.");
-
- if (dst == generator.ignoredResult())
- dst = 0;
- RegisterID* r0 = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
- RefPtr<RegisterID> returnRegister;
- if (generator.scopeDepth()) {
- RefPtr<Label> l0 = generator.newLabel();
- if (generator.hasFinaliser() && !r0->isTemporary()) {
- returnRegister = generator.emitMove(generator.newTemporary(), r0);
- r0 = returnRegister.get();
- }
- generator.emitJumpScopes(l0.get(), 0);
- generator.emitLabel(l0.get());
- }
- generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), column());
- return generator.emitReturn(r0);
-}
-
-// ------------------------------ WithNode -------------------------------------
-
-RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- RefPtr<RegisterID> scope = generator.newTemporary();
- generator.emitNode(scope.get(), m_expr); // scope must be protected until popped
- generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
- generator.emitPushScope(scope.get());
- RegisterID* result = generator.emitNode(dst, m_statement);
- generator.emitPopScope();
- return result;
-}
-
-// ------------------------------ CaseClauseNode --------------------------------
-
-inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (m_statements)
- m_statements->emitBytecode(generator, dst);
-}
-
-// ------------------------------ CaseBlockNode --------------------------------
-
-enum SwitchKind {
- SwitchUnset = 0,
- SwitchNumber = 1,
- SwitchString = 2,
- SwitchNeither = 3
-};
-
-static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num)
-{
- for (; list; list = list->getNext()) {
- ExpressionNode* clauseExpression = list->getClause()->expr();
- literalVector.append(clauseExpression);
- if (clauseExpression->isNumber()) {
- double value = static_cast<NumberNode*>(clauseExpression)->value();
- int32_t intVal = static_cast<int32_t>(value);
- if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
- typeForTable = SwitchNeither;
- break;
- }
- if (intVal < min_num)
- min_num = intVal;
- if (intVal > max_num)
- max_num = intVal;
- typeForTable = SwitchNumber;
- continue;
- }
- if (clauseExpression->isString()) {
- if (typeForTable & ~SwitchString) {
- typeForTable = SwitchNeither;
- break;
- }
- const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
- if (singleCharacterSwitch &= value.size() == 1) {
- int32_t intVal = value.rep()->data()[0];
- if (intVal < min_num)
- min_num = intVal;
- if (intVal > max_num)
- max_num = intVal;
- }
- typeForTable = SwitchString;
- continue;
- }
- typeForTable = SwitchNeither;
- break;
- }
-}
-
-SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num)
-{
- SwitchKind typeForTable = SwitchUnset;
- bool singleCharacterSwitch = true;
-
- processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
- processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
-
- if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
- return SwitchInfo::SwitchNone;
-
- if (typeForTable == SwitchNumber) {
- int32_t range = max_num - min_num;
- if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
- return SwitchInfo::SwitchImmediate;
- return SwitchInfo::SwitchNone;
- }
-
- ASSERT(typeForTable == SwitchString);
-
- if (singleCharacterSwitch) {
- int32_t range = max_num - min_num;
- if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10)
- return SwitchInfo::SwitchCharacter;
- }
-
- return SwitchInfo::SwitchString;
-}
-
-RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
-{
- 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();
- SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num);
-
- if (switchType != SwitchInfo::SwitchNone) {
- // Prepare the various labels
- for (uint32_t i = 0; i < literalVector.size(); i++)
- labelVector.append(generator.newLabel());
- defaultLabel = generator.newLabel();
- generator.beginSwitch(switchExpression, switchType);
- } else {
- // Setup jumps
- for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
- RefPtr<RegisterID> clauseVal = generator.newTemporary();
- generator.emitNode(clauseVal.get(), list->getClause()->expr());
- generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
- labelVector.append(generator.newLabel());
- generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
- }
-
- for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
- RefPtr<RegisterID> clauseVal = generator.newTemporary();
- generator.emitNode(clauseVal.get(), list->getClause()->expr());
- generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
- labelVector.append(generator.newLabel());
- generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
- }
- defaultLabel = generator.newLabel();
- generator.emitJump(defaultLabel.get());
- }
-
- RegisterID* result = 0;
-
- size_t i = 0;
- for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
- generator.emitLabel(labelVector[i++].get());
- list->getClause()->emitBytecode(generator, dst);
- }
-
- if (m_defaultClause) {
- generator.emitLabel(defaultLabel.get());
- m_defaultClause->emitBytecode(generator, dst);
- }
-
- for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
- generator.emitLabel(labelVector[i++].get());
- list->getClause()->emitBytecode(generator, dst);
- }
- if (!m_defaultClause)
- generator.emitLabel(defaultLabel.get());
-
- ASSERT(i == labelVector.size());
- if (switchType != SwitchInfo::SwitchNone) {
- ASSERT(labelVector.size() == literalVector.size());
- generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num);
- }
- return result;
-}
-
-// ------------------------------ SwitchNode -----------------------------------
-
-RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
-
- RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
- RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
-
- generator.emitLabel(scope->breakTarget());
- return r1;
-}
-
-// ------------------------------ LabelNode ------------------------------------
-
-RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- if (generator.breakTarget(m_name))
- return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
-
- RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
- RegisterID* r0 = generator.emitNode(dst, m_statement);
-
- generator.emitLabel(scope->breakTarget());
- return r0;
-}
-
-// ------------------------------ ThrowNode ------------------------------------
-
-RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-
- if (dst == generator.ignoredResult())
- dst = 0;
- RefPtr<RegisterID> expr = generator.emitNode(m_expr);
- generator.emitExpressionInfo(divot(), startOffset(), endOffset());
- generator.emitThrow(expr.get());
- return 0;
-}
-
-// ------------------------------ TryNode --------------------------------------
-
-RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- // NOTE: The catch and finally blocks must be labeled explicitly, so the
- // optimizer knows they may be jumped to from anywhere.
-
-#ifndef QT_BUILD_SCRIPT_LIB
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
-#endif
-
- RefPtr<Label> tryStartLabel = generator.newLabel();
- RefPtr<Label> finallyStart;
- RefPtr<RegisterID> finallyReturnAddr;
- if (m_finallyBlock) {
- finallyStart = generator.newLabel();
- finallyReturnAddr = generator.newTemporary();
- generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
- }
-
- generator.emitLabel(tryStartLabel.get());
- generator.emitNode(dst, m_tryBlock);
-
- if (m_catchBlock) {
- RefPtr<Label> catchEndLabel = generator.newLabel();
-
- // Normal path: jump over the catch block.
- generator.emitJump(catchEndLabel.get());
-
- // Uncaught exception path: the catch block.
- RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
- RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
- if (m_catchHasEval) {
- RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
- generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
- generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get());
- generator.emitPushScope(exceptionRegister.get());
- } else
- generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
- generator.emitNode(dst, m_catchBlock);
- generator.emitPopScope();
- generator.emitLabel(catchEndLabel.get());
- }
-
- if (m_finallyBlock) {
- generator.popFinallyContext();
- // there may be important registers live at the time we jump
- // to a finally block (such as for a return or throw) so we
- // ref the highest register ever used as a conservative
- // approach to not clobbering anything important
- RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
- RefPtr<Label> finallyEndLabel = generator.newLabel();
-
- // Normal path: invoke the finally block, then jump over it.
- generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
- generator.emitJump(finallyEndLabel.get());
-
- // Uncaught exception path: invoke the finally block, then re-throw the exception.
- RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
- RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
- generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
- generator.emitThrow(tempExceptionRegister.get());
-
- // The finally block.
- generator.emitLabel(finallyStart.get());
- generator.emitNode(dst, m_finallyBlock);
- generator.emitSubroutineReturn(finallyReturnAddr.get());
-
- generator.emitLabel(finallyEndLabel.get());
- }
-
- return dst;
-}
-
// -----------------------------ScopeNodeData ---------------------------
ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, int numConstants)
@@ -1910,12 +104,6 @@ ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceE
{
}
-inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (m_data->m_statements)
- m_data->m_statements->emitBytecode(generator, dst);
-}
-
StatementNode* ScopeNode::singleStatement() const
{
return m_data->m_statements ? m_data->m_statements->singleStatement() : 0;
@@ -1939,19 +127,6 @@ PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElem
return node.release();
}
-RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
-{
- generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine(), column());
-
- RefPtr<RegisterID> dstRegister = generator.newTemporary();
- generator.emitLoad(dstRegister.get(), jsUndefined());
- emitStatementsBytecode(generator, dstRegister.get());
-
- generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine(), column());
- generator.emitEnd(dstRegister.get());
- return 0;
-}
-
// ------------------------------ EvalNode -----------------------------
inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
@@ -1970,19 +145,6 @@ PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, SourceElements*
return node.release();
}
-RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
-{
- generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine(), column());
-
- RefPtr<RegisterID> dstRegister = generator.newTemporary();
- generator.emitLoad(dstRegister.get(), jsUndefined());
- emitStatementsBytecode(generator, dstRegister.get());
-
- generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine(), column());
- generator.emitEnd(dstRegister.get());
- return 0;
-}
-
// ------------------------------ FunctionBodyNode -----------------------------
FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
@@ -2001,10 +163,6 @@ inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElemen
{
}
-FunctionBodyNode::~FunctionBodyNode()
-{
-}
-
void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident)
{
setSource(source);
@@ -2034,37 +192,4 @@ PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData,
return node.release();
}
-RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
-{
- generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine(), column());
- emitStatementsBytecode(generator, generator.ignoredResult());
- StatementNode* singleStatement = this->singleStatement();
- if (singleStatement && singleStatement->isBlock()) {
- StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement();
- if (lastStatementInBlock && lastStatementInBlock->isReturnNode())
- return 0;
- }
-
- RegisterID* r0 = generator.emitLoad(0, jsUndefined());
- generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), column());
- generator.emitReturn(r0);
- return 0;
-}
-
-// ------------------------------ FuncDeclNode ---------------------------------
-
-RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- if (dst == generator.ignoredResult())
- dst = 0;
- return dst;
-}
-
-// ------------------------------ FuncExprNode ---------------------------------
-
-RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
- return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
-}
-
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.h
index 2f8d850..c216ea8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Nodes.h
@@ -40,6 +40,7 @@ namespace JSC {
class ArgumentListNode;
class BytecodeGenerator;
class FunctionBodyNode;
+ class Label;
class PropertyListNode;
class ReadModifyResolveNode;
class RegisterID;
@@ -151,6 +152,9 @@ namespace JSC {
virtual bool isCommaNode() const { return false; }
virtual bool isSimpleArray() const { return false; }
virtual bool isAdd() const { return false; }
+ virtual bool hasConditionContextCodegen() const { return false; }
+
+ virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, bool) { ASSERT_NOT_REACHED(); }
virtual ExpressionNode* stripUnaryPlus() { return this; }
@@ -165,10 +169,9 @@ namespace JSC {
StatementNode(JSGlobalData*);
public:
- void setLoc(int firstLine, int lastLine, int column);
+ void setLoc(int firstLine, int lastLine);
int firstLine() const { return lineNo(); }
int lastLine() const { return m_lastLine; }
- int column() const { return m_column; }
virtual bool isEmptyStatement() const { return false; }
virtual bool isReturnNode() const { return false; }
@@ -178,7 +181,6 @@ namespace JSC {
private:
int m_lastLine;
- int m_column;
};
class NullNode : public ExpressionNode {
@@ -759,6 +761,7 @@ namespace JSC {
protected:
ExpressionNode* expr() { return m_expr; }
+ const ExpressionNode* expr() const { return m_expr; }
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -790,6 +793,9 @@ namespace JSC {
class LogicalNotNode : public UnaryOpNode {
public:
LogicalNotNode(JSGlobalData*, ExpressionNode*);
+ private:
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
+ virtual bool hasConditionContextCodegen() const { return expr()->hasConditionContextCodegen(); }
};
class BinaryOpNode : public ExpressionNode {
@@ -954,6 +960,8 @@ namespace JSC {
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
+ virtual bool hasConditionContextCodegen() const { return true; }
ExpressionNode* m_expr1;
ExpressionNode* m_expr2;
@@ -1460,8 +1468,6 @@ namespace JSC {
static FunctionBodyNode* create(JSGlobalData*);
static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
- virtual ~FunctionBodyNode();
-
FunctionParameters* parameters() const { return m_parameters.get(); }
size_t parameterCount() const { return m_parameters->size(); }
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.h
index 7f20480..894f709 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/Parser.h
@@ -83,8 +83,7 @@ namespace JSC {
source,
m_features,
m_numConstants);
- int column = m_source->startOffset(); //is it good way to find column number?
- result->setLoc(m_source->firstLine(), m_lastLine, column);
+ result->setLoc(m_source->firstLine(), m_lastLine);
}
m_arena.reset();
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.h
index 2fd4fc1..eef8e93 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/ParserArena.h
@@ -34,7 +34,7 @@ namespace JSC {
class ParserArenaDeletable;
class ParserArenaRefCounted;
- class IdentifierArena {
+ class IdentifierArena : public FastAllocBase {
public:
ALWAYS_INLINE const Identifier& makeIdentifier(JSGlobalData*, const UChar* characters, size_t length);
const Identifier& makeNumericIdentifier(JSGlobalData*, double number);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourceCode.h b/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourceCode.h
index 305b804..bef8e78 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourceCode.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/parser/SourceCode.h
@@ -37,7 +37,8 @@ namespace JSC {
class SourceCode {
public:
SourceCode()
- : m_startChar(0)
+ : m_provider(0)
+ , m_startChar(0)
, m_endChar(0)
, m_firstLine(0)
{
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/pcre/dftables b/src/3rdparty/javascriptcore/JavaScriptCore/pcre/dftables
index 1f0ea01..669b948 100755
--- a/src/3rdparty/javascriptcore/JavaScriptCore/pcre/dftables
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/pcre/dftables
@@ -269,4 +269,5 @@ sub readHeaderValues()
eval $content;
die "$@" if $@;
+ unlink $tempFile;
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/pcre/pcre.pri b/src/3rdparty/javascriptcore/JavaScriptCore/pcre/pcre.pri
index c33c67c..4f59e17 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/pcre/pcre.pri
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/pcre/pcre.pri
@@ -3,8 +3,6 @@ VPATH += $$PWD
INCLUDEPATH += $$PWD $$OUTPUT_DIR/JavaScriptCore/tmp
DEPENDPATH += $$PWD
-isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = tmp
-
SOURCES += \
pcre_compile.cpp \
pcre_exec.cpp \
@@ -12,24 +10,3 @@ SOURCES += \
pcre_ucp_searchfuncs.cpp \
pcre_xclass.cpp
-!CONFIG(QTDIR_build) {
- defineTest(addExtraCompiler) {
- QMAKE_EXTRA_COMPILERS += $$1
- generated_files.depends += compiler_$${1}_make_all
- export(QMAKE_EXTRA_COMPILERS)
- export(generated_files.depends)
- return(true)
- }
-}
-
-# GENERATOR: "chartables.c": compile and execute the chartables generator (and add it to sources)
-win32-msvc*|wince*: PREPROCESSOR = "--preprocessor=\"$$QMAKE_CC /E\""
-DFTABLES = $$PWD/dftables
-ctgen.input = DFTABLES
-ctgen.output = $$GENERATED_SOURCES_DIR/chartables.c
-ctgen.commands = perl $$DFTABLES ${QMAKE_FILE_OUT} $$PREPROCESSOR
-ctgen.CONFIG += target_predeps no_link
-ctgen.variable_out = GENERATED_SOURCES
-ctgen.dependency_type = TYPE_C
-ctgen.clean = ${QMAKE_FILE_OUT} ${QMAKE_VAR_GENERATED_SOURCES_DIR}${QMAKE_FILE_BASE}
-addExtraCompiler(ctgen)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/pcre/pcre_exec.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/pcre/pcre_exec.cpp
index 16619d4..8ca2eb4 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/pcre/pcre_exec.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/pcre/pcre_exec.cpp
@@ -2164,14 +2164,14 @@ void Histogram::add(const JSRegExp* re, double elapsedTime)
HistogramTimeLogger::HistogramTimeLogger(const JSRegExp* re)
: m_re(re)
- , m_startTime(getCurrentUTCTimeWithMicroseconds())
+ , m_startTime(currentTimeMS())
{
}
HistogramTimeLogger::~HistogramTimeLogger()
{
static Histogram histogram;
- histogram.add(m_re, getCurrentUTCTimeWithMicroseconds() - m_startTime);
+ histogram.add(m_re, currentTimeMS() - m_startTime);
}
#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/HeavyProfile.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/HeavyProfile.cpp
deleted file mode 100644
index e69de29..0000000
--- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/HeavyProfile.cpp
+++ /dev/null
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/HeavyProfile.h b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/HeavyProfile.h
deleted file mode 100644
index e69de29..0000000
--- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/HeavyProfile.h
+++ /dev/null
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.cpp
index dc68ecb..17d37d7 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileGenerator.cpp
@@ -63,7 +63,7 @@ void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
JSValue function;
exec->interpreter()->retrieveLastCaller(exec, lineNumber, sourceID, sourceURL, function);
- m_currentNode = ProfileNode::create(Profiler::createCallIdentifier(&exec->globalData(), function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
+ m_currentNode = ProfileNode::create(Profiler::createCallIdentifier(exec, function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
m_head->insertNode(m_currentNode.get());
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileNode.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileNode.cpp
index 19050aa..fb126b3 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileNode.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/ProfileNode.cpp
@@ -33,15 +33,17 @@
#include <stdio.h>
#include <wtf/DateMath.h>
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#include <windows.h>
#endif
+using namespace WTF;
+
namespace JSC {
static double getCount()
{
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
static LARGE_INTEGER frequency = {0};
if (!frequency.QuadPart)
QueryPerformanceFrequency(&frequency);
@@ -49,7 +51,7 @@ static double getCount()
QueryPerformanceCounter(&counter);
return static_cast<double>(counter.QuadPart) / frequency.QuadPart;
#else
- return WTF::getCurrentUTCTimeWithMicroseconds();
+ return currentTimeMS();
#endif
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.cpp
index 6f72e08..fe8727a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.cpp
@@ -46,7 +46,7 @@ static const char* GlobalCodeExecution = "(program)";
static const char* AnonymousFunction = "(anonymous function)";
static unsigned ProfilesUID = 0;
-static CallIdentifier createCallIdentifierFromFunctionImp(JSGlobalData*, JSFunction*);
+static CallIdentifier createCallIdentifierFromFunctionImp(ExecState*, JSFunction*);
Profiler* Profiler::s_sharedProfiler = 0;
Profiler* Profiler::s_sharedEnabledProfilerReference = 0;
@@ -109,14 +109,14 @@ void Profiler::willExecute(ExecState* exec, JSValue function)
{
ASSERT(!m_currentProfiles.isEmpty());
- dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(&exec->globalData(), function, "", 0), exec->lexicalGlobalObject()->profileGroup());
+ dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::willExecute, createCallIdentifier(exec, function, "", 0), exec->lexicalGlobalObject()->profileGroup());
}
void Profiler::willExecute(ExecState* exec, const UString& sourceURL, int startingLineNumber)
{
ASSERT(!m_currentProfiles.isEmpty());
- CallIdentifier callIdentifier = createCallIdentifier(&exec->globalData(), JSValue(), sourceURL, startingLineNumber);
+ CallIdentifier callIdentifier = createCallIdentifier(exec, JSValue(), sourceURL, startingLineNumber);
dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, exec->lexicalGlobalObject()->profileGroup());
}
@@ -125,17 +125,17 @@ void Profiler::didExecute(ExecState* exec, JSValue function)
{
ASSERT(!m_currentProfiles.isEmpty());
- dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(&exec->globalData(), function, "", 0), exec->lexicalGlobalObject()->profileGroup());
+ dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(exec, function, "", 0), exec->lexicalGlobalObject()->profileGroup());
}
void Profiler::didExecute(ExecState* exec, const UString& sourceURL, int startingLineNumber)
{
ASSERT(!m_currentProfiles.isEmpty());
- dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(&exec->globalData(), JSValue(), sourceURL, startingLineNumber), exec->lexicalGlobalObject()->profileGroup());
+ dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(exec, JSValue(), sourceURL, startingLineNumber), exec->lexicalGlobalObject()->profileGroup());
}
-CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSValue functionValue, const UString& defaultSourceURL, int defaultLineNumber)
+CallIdentifier Profiler::createCallIdentifier(ExecState* exec, JSValue functionValue, const UString& defaultSourceURL, int defaultLineNumber)
{
if (!functionValue)
return CallIdentifier(GlobalCodeExecution, defaultSourceURL, defaultLineNumber);
@@ -144,17 +144,17 @@ CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSValue
if (asObject(functionValue)->inherits(&JSFunction::info)) {
JSFunction* function = asFunction(functionValue);
if (!function->executable()->isHostFunction())
- return createCallIdentifierFromFunctionImp(globalData, function);
+ return createCallIdentifierFromFunctionImp(exec, function);
}
if (asObject(functionValue)->inherits(&InternalFunction::info))
- return CallIdentifier(static_cast<InternalFunction*>(asObject(functionValue))->name(globalData), defaultSourceURL, defaultLineNumber);
- return CallIdentifier("(" + asObject(functionValue)->className() + " object)", defaultSourceURL, defaultLineNumber);
+ return CallIdentifier(static_cast<InternalFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber);
+ return CallIdentifier(makeString("(", asObject(functionValue)->className(), " object)"), defaultSourceURL, defaultLineNumber);
}
-CallIdentifier createCallIdentifierFromFunctionImp(JSGlobalData* globalData, JSFunction* function)
+CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSFunction* function)
{
ASSERT(!function->isHostFunction());
- const UString& name = function->calculatedDisplayName(globalData);
+ const UString& name = function->calculatedDisplayName(exec);
return CallIdentifier(name.isEmpty() ? AnonymousFunction : name, function->jsExecutable()->sourceURL(), function->jsExecutable()->lineNo());
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.h b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.h
index 21621bf..4b8b4a0 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/Profiler.h
@@ -52,7 +52,7 @@ namespace JSC {
}
static Profiler* profiler();
- static CallIdentifier createCallIdentifier(JSGlobalData*, JSValue, const UString& sourceURL, int lineNumber);
+ static CallIdentifier createCallIdentifier(ExecState* exec, JSValue, const UString& sourceURL, int lineNumber);
void startProfiling(ExecState*, const UString& title);
PassRefPtr<Profile> stopProfiling(ExecState*, const UString& title);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/TreeProfile.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/TreeProfile.cpp
deleted file mode 100644
index e69de29..0000000
--- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/TreeProfile.cpp
+++ /dev/null
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/TreeProfile.h b/src/3rdparty/javascriptcore/JavaScriptCore/profiler/TreeProfile.h
deleted file mode 100644
index e69de29..0000000
--- a/src/3rdparty/javascriptcore/JavaScriptCore/profiler/TreeProfile.h
+++ /dev/null
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h
index 3227770..8e1fdbe 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArgList.h
@@ -104,7 +104,11 @@ namespace JSC {
void append(JSValue v)
{
ASSERT(!m_isReadOnly);
-
+
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!v.isZombie());
+#endif
+
if (m_isUsingInlineBuffer && m_size < inlineCapacity) {
m_vector.uncheckedAppend(v);
++m_size;
@@ -187,6 +191,10 @@ namespace JSC {
: m_args(args)
, m_argCount(argCount)
{
+#if ENABLE(JSC_ZOMBIES)
+ for (size_t i = 0; i < argCount; i++)
+ ASSERT(!m_args[i].isZombie());
+#endif
}
ArgList(Register* args, int argCount)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp
index d90ea15..bb30e3b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.cpp
@@ -204,6 +204,19 @@ bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& prop
return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
+void Arguments::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+ if (mode == IncludeDontEnumProperties) {
+ for (unsigned i = 0; i < d->numArguments; ++i) {
+ if (!d->deletedArguments || !d->deletedArguments[i])
+ propertyNames.add(Identifier(exec, UString::from(i)));
+ }
+ propertyNames.add(exec->propertyNames().callee);
+ propertyNames.add(exec->propertyNames().length);
+ }
+ JSObject::getOwnPropertyNames(exec, propertyNames, mode);
+}
+
void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& slot)
{
if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
@@ -244,7 +257,7 @@ void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue val
JSObject::put(exec, propertyName, value, slot);
}
-bool Arguments::deleteProperty(ExecState* exec, unsigned i, bool checkDontDelete)
+bool Arguments::deleteProperty(ExecState* exec, unsigned i)
{
if (i < d->numArguments) {
if (!d->deletedArguments) {
@@ -257,10 +270,10 @@ bool Arguments::deleteProperty(ExecState* exec, unsigned i, bool checkDontDelete
}
}
- return JSObject::deleteProperty(exec, Identifier(exec, UString::from(i)), checkDontDelete);
+ return JSObject::deleteProperty(exec, Identifier(exec, UString::from(i)));
}
-bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
bool isArrayIndex;
unsigned i = propertyName.toArrayIndex(&isArrayIndex);
@@ -285,17 +298,7 @@ bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName,
return true;
}
- return JSObject::deleteProperty(exec, propertyName, checkDontDelete);
-}
-
-bool Arguments::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
-{
- if ((propertyName == exec->propertyNames().length)
- || (propertyName == exec->propertyNames().callee)) {
- attributes = DontEnum;
- return true;
- }
- return JSObject::getPropertyAttributes(exec, propertyName, attributes);
+ return JSObject::deleteProperty(exec, propertyName);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h
index 2aa0921..d4a8c95 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Arguments.h
@@ -85,19 +85,22 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
+
private:
void getArgumentsData(CallFrame*, JSObject*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
+ virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&);
- virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
- virtual bool deleteProperty(ExecState*, unsigned propertyName, bool checkDontDelete = true);
- virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+ virtual bool deleteProperty(ExecState*, unsigned propertyName);
virtual const ClassInfo* classInfo() const { return &info; }
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp
index c60cb0e..fb44494 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -37,7 +37,7 @@ ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor);
static JSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState*, JSObject*, JSValue, const ArgList&);
-ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> structure, ArrayPrototype* arrayPrototype, Structure* prototypeFunctionStructure)
+ArrayConstructor::ArrayConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, ArrayPrototype* arrayPrototype, Structure* prototypeFunctionStructure)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, arrayPrototype->classInfo()->className))
{
// ECMA 15.4.3.1 Array.prototype
@@ -50,7 +50,7 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> struct
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().isArray, arrayConstructorIsArray), DontEnum);
}
-static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
+static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
{
// a single numeric argument denotes the array size (!)
if (args.size() == 1 && args.at(0).isNumber()) {
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h
index 2b79510..6d25400 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class ArrayConstructor : public InternalFunction {
public:
- ArrayConstructor(ExecState*, PassRefPtr<Structure>, ArrayPrototype*, Structure*);
+ ArrayConstructor(ExecState*, NonNullPassRefPtr<Structure>, ArrayPrototype*, Structure*);
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp
index c453b22..ce814b2 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -115,7 +115,7 @@ const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::a
*/
// ECMA 15.4.4
-ArrayPrototype::ArrayPrototype(PassRefPtr<Structure> structure)
+ArrayPrototype::ArrayPrototype(NonNullPassRefPtr<Structure> structure)
: JSArray(structure)
{
}
@@ -204,8 +204,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue
buffer.append(rep->data(), rep->size());
}
ASSERT(buffer.size() == totalSize);
- unsigned finalSize = buffer.size();
- return jsString(exec, UString(buffer.releaseBuffer(), finalSize, false));
+ return jsString(exec, UString::adopt(buffer));
}
JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -745,8 +744,8 @@ JSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue th
cachedCall.setArgument(0, array->getIndex(k));
cachedCall.setArgument(1, jsNumber(exec, k));
cachedCall.setArgument(2, thisObj);
-
- if (!cachedCall.call().toBoolean(exec))
+ JSValue result = cachedCall.call();
+ if (!result.toBoolean(cachedCall.newCallFrame(exec)))
return jsBoolean(false);
}
}
@@ -846,8 +845,8 @@ JSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue thi
cachedCall.setArgument(0, array->getIndex(k));
cachedCall.setArgument(1, jsNumber(exec, k));
cachedCall.setArgument(2, thisObj);
-
- if (cachedCall.call().toBoolean(exec))
+ JSValue result = cachedCall.call();
+ if (result.toBoolean(cachedCall.newCallFrame(exec)))
return jsBoolean(true);
}
}
@@ -1034,7 +1033,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue
JSValue e = getProperty(exec, thisObj, index);
if (!e)
continue;
- if (JSValue::strictEqual(searchElement, e))
+ if (JSValue::strictEqual(exec, searchElement, e))
return jsNumber(exec, index);
}
@@ -1065,7 +1064,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSVa
JSValue e = getProperty(exec, thisObj, index);
if (!e)
continue;
- if (JSValue::strictEqual(searchElement, e))
+ if (JSValue::strictEqual(exec, searchElement, e))
return jsNumber(exec, index);
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h
index 6f7ed12..e52914c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ArrayPrototype.h
@@ -28,7 +28,7 @@ namespace JSC {
class ArrayPrototype : public JSArray {
public:
- explicit ArrayPrototype(PassRefPtr<Structure>);
+ explicit ArrayPrototype(NonNullPassRefPtr<Structure>);
bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
index 929a5e7..74089a5 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BatchedTransitionOptimizer.h
@@ -43,7 +43,7 @@ namespace JSC {
~BatchedTransitionOptimizer()
{
- m_object->setStructure(Structure::fromDictionaryTransition(m_object->structure()));
+ m_object->flattenDictionaryObject();
}
private:
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.cpp
index 9fcba37..b0d8df3 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.cpp
@@ -28,7 +28,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor);
-BooleanConstructor::BooleanConstructor(ExecState* exec, PassRefPtr<Structure> structure, BooleanPrototype* booleanPrototype)
+BooleanConstructor::BooleanConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, BooleanPrototype* booleanPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, booleanPrototype->classInfo()->className))
{
putDirectWithoutTransition(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.h
index d9f51ab..1d8a26a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class BooleanConstructor : public InternalFunction {
public:
- BooleanConstructor(ExecState*, PassRefPtr<Structure>, BooleanPrototype*);
+ BooleanConstructor(ExecState*, NonNullPassRefPtr<Structure>, BooleanPrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.cpp
index 01f695a..c9b3846 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.cpp
+++ b/src/3rdparty/javascriptcore/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<Structure> structure)
+BooleanObject::BooleanObject(NonNullPassRefPtr<Structure> structure)
: JSWrapperObject(structure)
{
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h
index 5f3e5f0..69c2e51 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanObject.h
@@ -27,14 +27,14 @@ namespace JSC {
class BooleanObject : public JSWrapperObject {
public:
- explicit BooleanObject(PassRefPtr<Structure>);
+ explicit BooleanObject(NonNullPassRefPtr<Structure>);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
};
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp
index cf4fbd7..8d338f9 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.cpp
@@ -37,7 +37,7 @@ static JSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState*, JSObject*, JSVa
// ECMA 15.6.4
-BooleanPrototype::BooleanPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
+BooleanPrototype::BooleanPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
: BooleanObject(structure)
{
setInternalValue(jsBoolean(false));
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.h
index 16f80b5..cc69b3f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/BooleanPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class BooleanPrototype : public BooleanObject {
public:
- BooleanPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
+ BooleanPrototype(ExecState*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure);
};
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h
index ef4988b..32e1e52 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CallData.h
@@ -60,12 +60,12 @@ namespace JSC {
}
inline operator NativeFunction() const {return ptr;}
inline operator bool() const {return ptr;}
-
+
JSValue operator()(ExecState* exec, JSObject* jsobj, JSValue thisValue, const ArgList& argList) const;
};
#endif
-#if defined(QT_BUILD_SCRIPT_LIB) && PLATFORM(SOLARIS)
+#if defined(QT_BUILD_SCRIPT_LIB) && OS(SOLARIS)
struct
#else
union
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
index abe15c8..29df7a5 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
@@ -32,6 +32,7 @@
#include "JSONObject.h"
#include "JSString.h"
#include "JSValue.h"
+#include "JSZombie.h"
#include "MarkStack.h"
#include "Nodes.h"
#include "Tracing.h"
@@ -44,7 +45,7 @@
#include <wtf/UnusedParam.h>
#include <wtf/VMTags.h>
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
#include <mach/mach_init.h>
#include <mach/mach_port.h>
@@ -52,29 +53,29 @@
#include <mach/thread_act.h>
#include <mach/vm_map.h>
-#elif PLATFORM(SYMBIAN)
+#elif OS(SYMBIAN)
#include <e32std.h>
#include <e32cmn.h>
#include <unistd.h>
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
#include <windows.h>
#include <malloc.h>
-#elif PLATFORM(HAIKU)
+#elif OS(HAIKU)
#include <OS.h>
-#elif PLATFORM(UNIX)
+#elif OS(UNIX)
#include <stdlib.h>
-#if !PLATFORM(HAIKU)
+#if !OS(HAIKU)
#include <sys/mman.h>
#endif
#include <unistd.h>
-#if PLATFORM(SOLARIS)
+#if OS(SOLARIS)
#include <thread.h>
#else
#include <pthread.h>
@@ -84,7 +85,7 @@
#include <pthread_np.h>
#endif
-#if PLATFORM(QNX)
+#if OS(QNX)
#include <fcntl.h>
#include <sys/procfs.h>
#include <stdio.h>
@@ -103,26 +104,22 @@ namespace JSC {
const size_t GROWTH_FACTOR = 2;
const size_t LOW_WATER_FACTOR = 4;
-const size_t ALLOCATIONS_PER_COLLECTION = 4000;
+const size_t ALLOCATIONS_PER_COLLECTION = 3600;
// This value has to be a macro to be used in max() without introducing
// a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
#define MIN_ARRAY_SIZE (static_cast<size_t>(14))
-#if PLATFORM(SYMBIAN)
+#if OS(SYMBIAN)
const size_t MAX_NUM_BLOCKS = 256; // Max size of collector heap set to 16 MB
static RHeap* userChunk = 0;
#endif
#if ENABLE(JSC_MULTIPLE_THREADS)
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
typedef mach_port_t PlatformThread;
-#elif PLATFORM(WIN_OS)
-struct PlatformThread {
- PlatformThread(DWORD _id, HANDLE _handle) : id(_id), handle(_handle) {}
- DWORD id;
- HANDLE handle;
-};
+#elif OS(WINDOWS)
+typedef HANDLE PlatformThread;
#endif
class Heap::Thread {
@@ -151,8 +148,8 @@ Heap::Heap(JSGlobalData* globalData)
, m_globalData(globalData)
{
ASSERT(globalData);
-
-#if PLATFORM(SYMBIAN)
+
+#if OS(SYMBIAN)
// Symbian OpenC supports mmap but currently not the MAP_ANON flag.
// Using fastMalloc() does not properly align blocks on 64k boundaries
// and previous implementation was flawed/incomplete.
@@ -170,10 +167,10 @@ Heap::Heap(JSGlobalData* globalData)
if (!userChunk)
CRASH();
}
-#endif // PLATFORM(SYMBIAN)
+#endif // OS(SYMBIAN)
- memset(&primaryHeap, 0, sizeof(CollectorHeap));
- memset(&numberHeap, 0, sizeof(CollectorHeap));
+ memset(&m_heap, 0, sizeof(CollectorHeap));
+ allocateBlock();
}
Heap::~Heap()
@@ -189,6 +186,9 @@ void Heap::destroy()
if (!m_globalData)
return;
+ ASSERT(!m_globalData->dynamicGlobalObject);
+ ASSERT(!isBusy());
+
// The global object is not GC protected at this point, so sweeping may delete it
// (and thus the global data) before other objects that may use the global data.
RefPtr<JSGlobalData> protect(m_globalData);
@@ -196,13 +196,7 @@ void Heap::destroy()
delete m_markListSet;
m_markListSet = 0;
- sweep<PrimaryHeap>();
- // No need to sweep number heap, because the JSNumber destructor doesn't do anything.
-
- ASSERT(!primaryHeap.numLiveObjects);
-
- freeBlocks(&primaryHeap);
- freeBlocks(&numberHeap);
+ freeBlocks();
#if ENABLE(JSC_MULTIPLE_THREADS)
if (m_currentThreadRegistrar) {
@@ -221,27 +215,23 @@ void Heap::destroy()
m_globalData = 0;
}
-template <HeapType heapType>
NEVER_INLINE CollectorBlock* Heap::allocateBlock()
{
// Disable the use of vm_map for the Qt build on Darwin, because when compiled on 10.4
// it crashes on 10.5
-#if PLATFORM(DARWIN) && !PLATFORM(QT)
+#if OS(DARWIN) && !PLATFORM(QT)
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 | VM_TAG_FOR_COLLECTOR_MEMORY, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
-#elif PLATFORM(SYMBIAN)
+#elif OS(SYMBIAN)
// Allocate a 64 kb aligned CollectorBlock
unsigned char* mask = reinterpret_cast<unsigned char*>(userChunk->Alloc(BLOCK_SIZE));
if (!mask)
CRASH();
uintptr_t address = reinterpret_cast<uintptr_t>(mask);
-
- memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE);
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
void* address = VirtualAlloc(NULL, BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
-#elif PLATFORM(WIN_OS)
-#if COMPILER(MINGW) && !PLATFORM(X86_64)
+#elif OS(WINDOWS)
+#if COMPILER(MINGW) && !CPU(X86_64)
void* address = __mingw_aligned_malloc(BLOCK_SIZE, BLOCK_SIZE);
#else
void* address = _aligned_malloc(BLOCK_SIZE, BLOCK_SIZE);
@@ -250,7 +240,6 @@ NEVER_INLINE CollectorBlock* Heap::allocateBlock()
#elif HAVE(POSIX_MEMALIGN)
void* address;
posix_memalign(&address, BLOCK_SIZE, BLOCK_SIZE);
- memset(address, 0, BLOCK_SIZE);
#else
#if ENABLE(JSC_MULTIPLE_THREADS)
@@ -276,58 +265,66 @@ NEVER_INLINE CollectorBlock* Heap::allocateBlock()
munmap(reinterpret_cast<char*>(address + adjust + BLOCK_SIZE), extra - adjust);
address += adjust;
- memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE);
#endif
+ // Initialize block.
+
CollectorBlock* block = reinterpret_cast<CollectorBlock*>(address);
- block->freeList = block->cells;
block->heap = this;
- block->type = heapType;
+ clearMarkBits(block);
- CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap;
- size_t numBlocks = heap.numBlocks;
- if (heap.usedBlocks == numBlocks) {
+ Structure* dummyMarkableCellStructure = m_globalData->dummyMarkableCellStructure.get();
+ for (size_t i = 0; i < HeapConstants::cellsPerBlock; ++i)
+ new (block->cells + i) JSCell(dummyMarkableCellStructure);
+
+ // Add block to blocks vector.
+
+ size_t numBlocks = m_heap.numBlocks;
+ if (m_heap.usedBlocks == numBlocks) {
static const size_t maxNumBlocks = ULONG_MAX / sizeof(CollectorBlock*) / GROWTH_FACTOR;
if (numBlocks > maxNumBlocks)
CRASH();
numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR);
- heap.numBlocks = numBlocks;
- heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, numBlocks * sizeof(CollectorBlock*)));
+ m_heap.numBlocks = numBlocks;
+ m_heap.blocks = static_cast<CollectorBlock**>(fastRealloc(m_heap.blocks, numBlocks * sizeof(CollectorBlock*)));
}
- heap.blocks[heap.usedBlocks++] = block;
+ m_heap.blocks[m_heap.usedBlocks++] = block;
return block;
}
-template <HeapType heapType>
NEVER_INLINE void Heap::freeBlock(size_t block)
{
- CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap;
+ m_heap.didShrink = true;
- freeBlock(heap.blocks[block]);
+ ObjectIterator it(m_heap, block);
+ ObjectIterator end(m_heap, block + 1);
+ for ( ; it != end; ++it)
+ (*it)->~JSCell();
+ freeBlockPtr(m_heap.blocks[block]);
// swap with the last block so we compact as we go
- heap.blocks[block] = heap.blocks[heap.usedBlocks - 1];
- heap.usedBlocks--;
+ m_heap.blocks[block] = m_heap.blocks[m_heap.usedBlocks - 1];
+ m_heap.usedBlocks--;
- if (heap.numBlocks > MIN_ARRAY_SIZE && heap.usedBlocks < heap.numBlocks / LOW_WATER_FACTOR) {
- heap.numBlocks = heap.numBlocks / GROWTH_FACTOR;
- heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, heap.numBlocks * sizeof(CollectorBlock*)));
+ if (m_heap.numBlocks > MIN_ARRAY_SIZE && m_heap.usedBlocks < m_heap.numBlocks / LOW_WATER_FACTOR) {
+ m_heap.numBlocks = m_heap.numBlocks / GROWTH_FACTOR;
+ m_heap.blocks = static_cast<CollectorBlock**>(fastRealloc(m_heap.blocks, m_heap.numBlocks * sizeof(CollectorBlock*)));
}
}
-NEVER_INLINE void Heap::freeBlock(CollectorBlock* block)
+NEVER_INLINE void Heap::freeBlockPtr(CollectorBlock* block)
{
// Disable the use of vm_deallocate for the Qt build on Darwin, because when compiled on 10.4
// it crashes on 10.5
-#if PLATFORM(DARWIN) && !PLATFORM(QT)
+#if OS(DARWIN) && !PLATFORM(QT)
vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(block), BLOCK_SIZE);
-#elif PLATFORM(SYMBIAN)
+#elif OS(SYMBIAN)
userChunk->Free(reinterpret_cast<TAny*>(block));
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
VirtualFree(block, 0, MEM_RELEASE);
-#elif PLATFORM(WIN_OS)
-#if COMPILER(MINGW) && !PLATFORM(X86_64)
+#elif OS(WINDOWS)
+#if COMPILER(MINGW) && !CPU(X86_64)
__mingw_aligned_free(block);
#else
_aligned_free(block);
@@ -339,13 +336,34 @@ NEVER_INLINE void Heap::freeBlock(CollectorBlock* block)
#endif
}
-void Heap::freeBlocks(CollectorHeap* heap)
+void Heap::freeBlocks()
{
- for (size_t i = 0; i < heap->usedBlocks; ++i)
- if (heap->blocks[i])
- freeBlock(heap->blocks[i]);
- fastFree(heap->blocks);
- memset(heap, 0, sizeof(CollectorHeap));
+ ProtectCountSet protectedValuesCopy = m_protectedValues;
+
+ clearMarkBits();
+ ProtectCountSet::iterator protectedValuesEnd = protectedValuesCopy.end();
+ for (ProtectCountSet::iterator it = protectedValuesCopy.begin(); it != protectedValuesEnd; ++it)
+ markCell(it->first);
+
+ m_heap.nextCell = 0;
+ m_heap.nextBlock = 0;
+ DeadObjectIterator it(m_heap, m_heap.nextBlock, m_heap.nextCell);
+ DeadObjectIterator end(m_heap, m_heap.usedBlocks);
+ for ( ; it != end; ++it)
+ (*it)->~JSCell();
+
+ ASSERT(!protectedObjectCount());
+
+ protectedValuesEnd = protectedValuesCopy.end();
+ for (ProtectCountSet::iterator it = protectedValuesCopy.begin(); it != protectedValuesEnd; ++it)
+ it->first->~JSCell();
+
+ for (size_t block = 0; block < m_heap.usedBlocks; ++block)
+ freeBlockPtr(m_heap.blocks[block]);
+
+ fastFree(m_heap.blocks);
+
+ memset(&m_heap, 0, sizeof(CollectorHeap));
}
void Heap::recordExtraCost(size_t cost)
@@ -360,123 +378,109 @@ void Heap::recordExtraCost(size_t cost)
// are either very short lived temporaries, or have extremely long lifetimes. So
// if a large value survives one garbage collection, there is not much point to
// collecting more frequently as long as it stays alive.
- // NOTE: we target the primaryHeap unconditionally as JSNumber doesn't modify cost
- primaryHeap.extraCost += cost;
+ if (m_heap.extraCost > maxExtraCost && m_heap.extraCost > m_heap.usedBlocks * BLOCK_SIZE / 2) {
+ // If the last iteration through the heap deallocated blocks, we need
+ // to clean up remaining garbage before marking. Otherwise, the conservative
+ // marking mechanism might follow a pointer to unmapped memory.
+ if (m_heap.didShrink)
+ sweep();
+ reset();
+ }
+ m_heap.extraCost += cost;
}
-template <HeapType heapType> ALWAYS_INLINE void* Heap::heapAllocate(size_t s)
+void* Heap::allocate(size_t s)
{
- typedef typename HeapConstants<heapType>::Block Block;
- typedef typename HeapConstants<heapType>::Cell Cell;
-
- CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap;
+ typedef HeapConstants::Block Block;
+ typedef HeapConstants::Cell Cell;
+
ASSERT(JSLock::lockCount() > 0);
ASSERT(JSLock::currentThreadIsHoldingLock());
- ASSERT_UNUSED(s, s <= HeapConstants<heapType>::cellSize);
+ ASSERT_UNUSED(s, s <= HeapConstants::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 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.
+ ASSERT(m_heap.operationInProgress == NoOperation);
#if COLLECT_ON_EVERY_ALLOCATION
- collect();
+ collectAllGarbage();
+ ASSERT(m_heap.operationInProgress == NoOperation);
#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) {
- size_t numLiveObjectsAtLastCollect = heap.numLiveObjectsAtLastCollect;
- size_t numNewObjects = numLiveObjects - numLiveObjectsAtLastCollect;
- const size_t newCost = numNewObjects + heap.extraCost;
- if (newCost >= ALLOCATIONS_PER_COLLECTION && newCost >= numLiveObjectsAtLastCollect)
- goto collect;
- }
+allocate:
- ASSERT(heap.operationInProgress == NoOperation);
-#ifndef NDEBUG
- // FIXME: Consider doing this in NDEBUG builds too (see comment above).
- heap.operationInProgress = Allocation;
-#endif
+ // Fast case: find the next garbage cell and recycle it.
-scan:
- Block* targetBlock;
- size_t targetBlockUsedCells;
- if (i != usedBlocks) {
- targetBlock = reinterpret_cast<Block*>(heap.blocks[i]);
- targetBlockUsedCells = targetBlock->usedCells;
- ASSERT(targetBlockUsedCells <= HeapConstants<heapType>::cellsPerBlock);
- while (targetBlockUsedCells == HeapConstants<heapType>::cellsPerBlock) {
- if (++i == usedBlocks)
- goto collect;
- targetBlock = reinterpret_cast<Block*>(heap.blocks[i]);
- targetBlockUsedCells = targetBlock->usedCells;
- ASSERT(targetBlockUsedCells <= HeapConstants<heapType>::cellsPerBlock);
- }
- heap.firstBlockWithPossibleSpace = i;
- } else {
+ do {
+ ASSERT(m_heap.nextBlock < m_heap.usedBlocks);
+ Block* block = reinterpret_cast<Block*>(m_heap.blocks[m_heap.nextBlock]);
+ do {
+ ASSERT(m_heap.nextCell < HeapConstants::cellsPerBlock);
+ if (!block->marked.get(m_heap.nextCell)) { // Always false for the last cell in the block
+ Cell* cell = block->cells + m_heap.nextCell;
-collect:
- size_t numLiveObjectsAtLastCollect = heap.numLiveObjectsAtLastCollect;
- size_t numNewObjects = numLiveObjects - numLiveObjectsAtLastCollect;
- const size_t newCost = numNewObjects + heap.extraCost;
+ m_heap.operationInProgress = Allocation;
+ JSCell* imp = reinterpret_cast<JSCell*>(cell);
+ imp->~JSCell();
+ m_heap.operationInProgress = NoOperation;
- if (newCost >= ALLOCATIONS_PER_COLLECTION && newCost >= numLiveObjectsAtLastCollect) {
-#ifndef NDEBUG
- heap.operationInProgress = NoOperation;
-#endif
- bool foundGarbage = collect();
- numLiveObjects = heap.numLiveObjects;
- usedBlocks = heap.usedBlocks;
- i = heap.firstBlockWithPossibleSpace;
-#ifndef NDEBUG
- heap.operationInProgress = Allocation;
-#endif
- if (foundGarbage)
- goto scan;
- }
+ ++m_heap.nextCell;
+ return cell;
+ }
+ } while (++m_heap.nextCell != HeapConstants::cellsPerBlock);
+ m_heap.nextCell = 0;
+ } while (++m_heap.nextBlock != m_heap.usedBlocks);
- // didn't find a block, and GC didn't reclaim anything, need to allocate a new block
- targetBlock = reinterpret_cast<Block*>(allocateBlock<heapType>());
- heap.firstBlockWithPossibleSpace = heap.usedBlocks - 1;
- targetBlockUsedCells = 0;
- }
+ // Slow case: reached the end of the heap. Mark live objects and start over.
- // find a free spot in the block and detach it from the free list
- Cell* newCell = targetBlock->freeList;
+ reset();
+ goto allocate;
+}
- // "next" field is a cell offset -- 0 means next cell, so a zeroed block is already initialized
- targetBlock->freeList = (newCell + 1) + newCell->u.freeCell.next;
+void Heap::resizeBlocks()
+{
+ m_heap.didShrink = false;
- targetBlock->usedCells = static_cast<uint32_t>(targetBlockUsedCells + 1);
- heap.numLiveObjects = numLiveObjects + 1;
+ size_t usedCellCount = markedCells();
+ size_t minCellCount = usedCellCount + max(ALLOCATIONS_PER_COLLECTION, usedCellCount);
+ size_t minBlockCount = (minCellCount + HeapConstants::cellsPerBlock - 1) / HeapConstants::cellsPerBlock;
-#ifndef NDEBUG
- // FIXME: Consider doing this in NDEBUG builds too (see comment above).
- heap.operationInProgress = NoOperation;
-#endif
+ size_t maxCellCount = 1.25f * minCellCount;
+ size_t maxBlockCount = (maxCellCount + HeapConstants::cellsPerBlock - 1) / HeapConstants::cellsPerBlock;
- return newCell;
+ if (m_heap.usedBlocks < minBlockCount)
+ growBlocks(minBlockCount);
+ else if (m_heap.usedBlocks > maxBlockCount)
+ shrinkBlocks(maxBlockCount);
}
-void* Heap::allocate(size_t s)
+void Heap::growBlocks(size_t neededBlocks)
{
- return heapAllocate<PrimaryHeap>(s);
+ ASSERT(m_heap.usedBlocks < neededBlocks);
+ while (m_heap.usedBlocks < neededBlocks)
+ allocateBlock();
}
-void* Heap::allocateNumber(size_t s)
+void Heap::shrinkBlocks(size_t neededBlocks)
{
- return heapAllocate<NumberHeap>(s);
+ ASSERT(m_heap.usedBlocks > neededBlocks);
+
+ // Clear the always-on last bit, so isEmpty() isn't fooled by it.
+ for (size_t i = 0; i < m_heap.usedBlocks; ++i)
+ m_heap.blocks[i]->marked.clear(HeapConstants::cellsPerBlock - 1);
+
+ for (size_t i = 0; i != m_heap.usedBlocks && m_heap.usedBlocks != neededBlocks; ) {
+ if (m_heap.blocks[i]->marked.isEmpty()) {
+ freeBlock(i);
+ } else
+ ++i;
+ }
+
+ // Reset the always-on last bit.
+ for (size_t i = 0; i < m_heap.usedBlocks; ++i)
+ m_heap.blocks[i]->marked.set(HeapConstants::cellsPerBlock - 1);
}
-#if PLATFORM(WINCE)
+#if OS(WINCE)
void* g_stackBase = 0;
inline bool isPageWritable(void* page)
@@ -532,7 +536,8 @@ static void* getStackBase(void* previousFrame)
}
}
#endif
-#if PLATFORM(HPUX)
+
+#if OS(HPUX)
struct hpux_get_stack_base_data
{
pthread_t thread;
@@ -576,7 +581,7 @@ static void *hpux_get_stack_base()
}
#endif
-#if PLATFORM(QNX)
+#if OS(QNX)
static inline void *currentThreadStackBaseQNX()
{
static void* stackBase = 0;
@@ -605,10 +610,10 @@ static inline void *currentThreadStackBaseQNX()
static inline void* currentThreadStackBase()
{
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
pthread_t thread = pthread_self();
return pthread_get_stackaddr_np(thread);
-#elif PLATFORM(WIN_OS) && PLATFORM(X86) && COMPILER(MSVC)
+#elif OS(WINDOWS) && CPU(X86) && COMPILER(MSVC)
// offset 0x18 from the FS segment register gives a pointer to
// the thread information block for the current thread
NT_TIB* pTib;
@@ -617,10 +622,11 @@ static inline void* currentThreadStackBase()
MOV pTib, EAX
}
return static_cast<void*>(pTib->StackBase);
-#elif PLATFORM(WIN_OS) && PLATFORM(X86_64) && (COMPILER(MSVC) ||COMPILER(GCC))
+#elif OS(WINDOWS) && CPU(X86_64) && (COMPILER(MSVC) || COMPILER(GCC))
+ // FIXME: why only for MSVC?
PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
return reinterpret_cast<void*>(pTib->StackBase);
-#elif PLATFORM(WIN_OS) && PLATFORM(X86) && COMPILER(GCC)
+#elif OS(WINDOWS) && CPU(X86) && COMPILER(GCC)
// offset 0x18 from the FS segment register gives a pointer to
// the thread information block for the current thread
NT_TIB* pTib;
@@ -628,15 +634,15 @@ static inline void* currentThreadStackBase()
: "=r" (pTib)
);
return static_cast<void*>(pTib->StackBase);
-#elif PLATFORM(QNX)
- return currentThreadStackBaseQNX();
-#elif PLATFORM(HPUX)
+#elif OS(HPUX)
return hpux_get_stack_base();
-#elif PLATFORM(SOLARIS)
+#elif OS(QNX)
+ return currentThreadStackBaseQNX();
+#elif OS(SOLARIS)
stack_t s;
thr_stksegment(&s);
return s.ss_sp;
-#elif PLATFORM(AIX)
+#elif OS(AIX)
pthread_t thread = pthread_self();
struct __pthrdsinfo threadinfo;
char regbuf[256];
@@ -648,12 +654,12 @@ static inline void* currentThreadStackBase()
return threadinfo.__pi_stackaddr;
return 0;
-#elif PLATFORM(OPENBSD)
+#elif OS(OPENBSD)
pthread_t thread = pthread_self();
stack_t stack;
pthread_stackseg_np(thread, &stack);
return stack.ss_sp;
-#elif PLATFORM(SYMBIAN)
+#elif OS(SYMBIAN)
static void* stackBase = 0;
if (stackBase == 0) {
TThreadStackInfo info;
@@ -662,11 +668,11 @@ static inline void* currentThreadStackBase()
stackBase = (void*)info.iBase;
}
return (void*)stackBase;
-#elif PLATFORM(HAIKU)
+#elif OS(HAIKU)
thread_info threadInfo;
get_thread_info(find_thread(NULL), &threadInfo);
return threadInfo.stack_end;
-#elif PLATFORM(UNIX)
+#elif OS(UNIX)
static void* stackBase = 0;
static size_t stackSize = 0;
static pthread_t stackThread;
@@ -674,7 +680,7 @@ static inline void* currentThreadStackBase()
if (stackBase == 0 || thread != stackThread) {
pthread_attr_t sattr;
pthread_attr_init(&sattr);
-#if HAVE(PTHREAD_NP_H) || PLATFORM(NETBSD)
+#if HAVE(PTHREAD_NP_H) || OS(NETBSD)
// e.g. on FreeBSD 5.4, neundorf@kde.org
pthread_attr_get_np(thread, &sattr);
#else
@@ -688,7 +694,7 @@ static inline void* currentThreadStackBase()
stackThread = thread;
}
return static_cast<char*>(stackBase) + stackSize;
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
if (g_stackBase)
return g_stackBase;
else {
@@ -704,11 +710,10 @@ static inline void* currentThreadStackBase()
static inline PlatformThread getCurrentPlatformThread()
{
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
return pthread_mach_thread_np(pthread_self());
-#elif PLATFORM(WIN_OS)
- HANDLE threadHandle = pthread_getw32threadhandle_np(pthread_self());
- return PlatformThread(GetCurrentThreadId(), threadHandle);
+#elif OS(WINDOWS)
+ return pthread_getw32threadhandle_np(pthread_self());
#endif
}
@@ -777,10 +782,37 @@ void Heap::registerThread()
#endif
-#define IS_POINTER_ALIGNED(p) (((intptr_t)(p) & (sizeof(char*) - 1)) == 0)
+inline bool isPointerAligned(void* p)
+{
+ return (((intptr_t)(p) & (sizeof(char*) - 1)) == 0);
+}
-// cell size needs to be a power of two for this to be valid
-#define IS_HALF_CELL_ALIGNED(p) (((intptr_t)(p) & (CELL_MASK >> 1)) == 0)
+// Cell size needs to be a power of two for isPossibleCell to be valid.
+COMPILE_ASSERT(sizeof(CollectorCell) % 2 == 0, Collector_cell_size_is_power_of_two);
+
+#if USE(JSVALUE32)
+static bool isHalfCellAligned(void *p)
+{
+ return (((intptr_t)(p) & (CELL_MASK >> 1)) == 0);
+}
+
+static inline bool isPossibleCell(void* p)
+{
+ return isHalfCellAligned(p) && p;
+}
+
+#else
+
+static inline bool isCellAligned(void *p)
+{
+ return (((intptr_t)(p) & CELL_MASK) == 0);
+}
+
+static inline bool isPossibleCell(void* p)
+{
+ return isCellAligned(p) && p;
+}
+#endif // USE(JSVALUE32)
void Heap::markConservatively(MarkStack& markStack, void* start, void* end)
{
@@ -791,46 +823,33 @@ void Heap::markConservatively(MarkStack& markStack, void* start, void* end)
}
ASSERT((static_cast<char*>(end) - static_cast<char*>(start)) < 0x1000000);
- ASSERT(IS_POINTER_ALIGNED(start));
- ASSERT(IS_POINTER_ALIGNED(end));
+ ASSERT(isPointerAligned(start));
+ ASSERT(isPointerAligned(end));
char** p = static_cast<char**>(start);
char** e = static_cast<char**>(end);
- size_t usedPrimaryBlocks = primaryHeap.usedBlocks;
- size_t usedNumberBlocks = numberHeap.usedBlocks;
- CollectorBlock** primaryBlocks = primaryHeap.blocks;
- CollectorBlock** numberBlocks = numberHeap.blocks;
-
- const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1);
-
+ CollectorBlock** blocks = m_heap.blocks;
while (p != e) {
char* x = *p++;
- if (IS_HALF_CELL_ALIGNED(x) && x) {
+ if (isPossibleCell(x)) {
+ size_t usedBlocks;
uintptr_t xAsBits = reinterpret_cast<uintptr_t>(x);
xAsBits &= CELL_ALIGN_MASK;
+
uintptr_t offset = xAsBits & BLOCK_OFFSET_MASK;
+ const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1);
+ if (offset > lastCellOffset)
+ continue;
+
CollectorBlock* blockAddr = reinterpret_cast<CollectorBlock*>(xAsBits - offset);
- // Mark the the number heap, we can mark these Cells directly to avoid the virtual call cost
- for (size_t block = 0; block < usedNumberBlocks; block++) {
- if ((numberBlocks[block] == blockAddr) & (offset <= lastCellOffset)) {
- Heap::markCell(reinterpret_cast<JSCell*>(xAsBits));
- goto endMarkLoop;
- }
+ usedBlocks = m_heap.usedBlocks;
+ for (size_t block = 0; block < usedBlocks; block++) {
+ if (blocks[block] != blockAddr)
+ continue;
+ markStack.append(reinterpret_cast<JSCell*>(xAsBits));
+ markStack.drain();
}
-
- // Mark the primary heap
- for (size_t block = 0; block < usedPrimaryBlocks; block++) {
- if ((primaryBlocks[block] == blockAddr) & (offset <= lastCellOffset)) {
- if (reinterpret_cast<CollectorCell*>(xAsBits)->u.freeCell.zeroIfFree) {
- markStack.append(reinterpret_cast<JSCell*>(xAsBits));
- markStack.drain();
- }
- break;
- }
- }
- endMarkLoop:
- ;
}
}
}
@@ -869,10 +888,10 @@ void Heap::markCurrentThreadConservatively(MarkStack& markStack)
static inline void suspendThread(const PlatformThread& platformThread)
{
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
thread_suspend(platformThread);
-#elif PLATFORM(WIN_OS)
- SuspendThread(platformThread.handle);
+#elif OS(WINDOWS)
+ SuspendThread(platformThread);
#else
#error Need a way to suspend threads on this platform
#endif
@@ -880,10 +899,10 @@ static inline void suspendThread(const PlatformThread& platformThread)
static inline void resumeThread(const PlatformThread& platformThread)
{
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
thread_resume(platformThread);
-#elif PLATFORM(WIN_OS)
- ResumeThread(platformThread.handle);
+#elif OS(WINDOWS)
+ ResumeThread(platformThread);
#else
#error Need a way to resume threads on this platform
#endif
@@ -891,23 +910,23 @@ static inline void resumeThread(const PlatformThread& platformThread)
typedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
-#if PLATFORM(X86)
+#if CPU(X86)
typedef i386_thread_state_t PlatformThreadRegisters;
-#elif PLATFORM(X86_64)
+#elif CPU(X86_64)
typedef x86_thread_state64_t PlatformThreadRegisters;
-#elif PLATFORM(PPC)
+#elif CPU(PPC)
typedef ppc_thread_state_t PlatformThreadRegisters;
-#elif PLATFORM(PPC64)
+#elif CPU(PPC64)
typedef ppc_thread_state64_t PlatformThreadRegisters;
-#elif PLATFORM(ARM)
+#elif CPU(ARM)
typedef arm_thread_state_t PlatformThreadRegisters;
#else
#error Unknown Architecture
#endif
-#elif PLATFORM(WIN_OS)&& PLATFORM(X86)
+#elif OS(WINDOWS) && CPU(X86)
typedef CONTEXT PlatformThreadRegisters;
#else
#error Need a thread register struct for this platform
@@ -915,21 +934,21 @@ typedef CONTEXT PlatformThreadRegisters;
static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs)
{
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
-#if PLATFORM(X86)
+#if CPU(X86)
unsigned user_count = sizeof(regs)/sizeof(int);
thread_state_flavor_t flavor = i386_THREAD_STATE;
-#elif PLATFORM(X86_64)
+#elif CPU(X86_64)
unsigned user_count = x86_THREAD_STATE64_COUNT;
thread_state_flavor_t flavor = x86_THREAD_STATE64;
-#elif PLATFORM(PPC)
+#elif CPU(PPC)
unsigned user_count = PPC_THREAD_STATE_COUNT;
thread_state_flavor_t flavor = PPC_THREAD_STATE;
-#elif PLATFORM(PPC64)
+#elif CPU(PPC64)
unsigned user_count = PPC_THREAD_STATE64_COUNT;
thread_state_flavor_t flavor = PPC_THREAD_STATE64;
-#elif PLATFORM(ARM)
+#elif CPU(ARM)
unsigned user_count = ARM_THREAD_STATE_COUNT;
thread_state_flavor_t flavor = ARM_THREAD_STATE;
#else
@@ -943,11 +962,11 @@ static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, P
CRASH();
}
return user_count * sizeof(usword_t);
-// end PLATFORM(DARWIN)
+// end OS(DARWIN)
-#elif PLATFORM(WIN_OS) && PLATFORM(X86)
+#elif OS(WINDOWS) && CPU(X86)
regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_SEGMENTS;
- GetThreadContext(platformThread.handle, &regs);
+ GetThreadContext(platformThread, &regs);
return sizeof(CONTEXT);
#else
#error Need a way to get thread registers on this platform
@@ -956,17 +975,17 @@ static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, P
static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
{
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
#if __DARWIN_UNIX03
-#if PLATFORM(X86)
+#if CPU(X86)
return reinterpret_cast<void*>(regs.__esp);
-#elif PLATFORM(X86_64)
+#elif CPU(X86_64)
return reinterpret_cast<void*>(regs.__rsp);
-#elif PLATFORM(PPC) || PLATFORM(PPC64)
+#elif CPU(PPC) || CPU(PPC64)
return reinterpret_cast<void*>(regs.__r1);
-#elif PLATFORM(ARM)
+#elif CPU(ARM)
return reinterpret_cast<void*>(regs.__sp);
#else
#error Unknown Architecture
@@ -974,11 +993,11 @@ static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
#else // !__DARWIN_UNIX03
-#if PLATFORM(X86)
+#if CPU(X86)
return reinterpret_cast<void*>(regs.esp);
-#elif PLATFORM(X86_64)
+#elif CPU(X86_64)
return reinterpret_cast<void*>(regs.rsp);
-#elif (PLATFORM(PPC) || PLATFORM(PPC64))
+#elif CPU(PPC) || CPU(PPC64)
return reinterpret_cast<void*>(regs.r1);
#else
#error Unknown Architecture
@@ -986,8 +1005,8 @@ static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
#endif // __DARWIN_UNIX03
-// end PLATFORM(DARWIN)
-#elif PLATFORM(X86) && PLATFORM(WIN_OS)
+// end OS(DARWIN)
+#elif CPU(X86) && OS(WINDOWS)
return reinterpret_cast<void*>((uintptr_t) regs.Esp);
#else
#error Need a way to get the stack pointer for another thread on this platform
@@ -1041,16 +1060,6 @@ void Heap::markStackObjectsConservatively(MarkStack& markStack)
#endif
}
-void Heap::setGCProtectNeedsLocking()
-{
- // Most clients do not need to call this, with the notable exception of WebCore.
- // Clients that use shared heap have JSLock protection, while others are supposed
- // to do explicit locking. WebCore violates this contract in Database code,
- // which calls gcUnprotect from a secondary thread.
- if (!m_protectedValuesMutex)
- m_protectedValuesMutex.set(new Mutex);
-}
-
void Heap::protect(JSValue k)
{
ASSERT(k);
@@ -1059,13 +1068,7 @@ void Heap::protect(JSValue k)
if (!k.isCell())
return;
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->lock();
-
m_protectedValues.add(k.asCell());
-
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->unlock();
}
void Heap::unprotect(JSValue k)
@@ -1076,133 +1079,80 @@ void Heap::unprotect(JSValue k)
if (!k.isCell())
return;
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->lock();
-
m_protectedValues.remove(k.asCell());
-
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->unlock();
}
void Heap::markProtectedObjects(MarkStack& markStack)
{
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->lock();
-
ProtectCountSet::iterator end = m_protectedValues.end();
for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) {
markStack.append(it->first);
markStack.drain();
}
+}
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->unlock();
+void Heap::clearMarkBits()
+{
+ for (size_t i = 0; i < m_heap.usedBlocks; ++i)
+ clearMarkBits(m_heap.blocks[i]);
}
-template <HeapType heapType> size_t Heap::sweep()
+void Heap::clearMarkBits(CollectorBlock* block)
{
- typedef typename HeapConstants<heapType>::Block Block;
- typedef typename HeapConstants<heapType>::Cell Cell;
+ // allocate assumes that the last cell in every block is marked.
+ block->marked.clearAll();
+ block->marked.set(HeapConstants::cellsPerBlock - 1);
+}
- // SWEEP: delete everything with a zero refcount (garbage) and unmark everything else
- CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap;
-
- size_t emptyBlocks = 0;
- size_t numLiveObjects = heap.numLiveObjects;
-
- for (size_t block = 0; block < heap.usedBlocks; block++) {
- Block* curBlock = reinterpret_cast<Block*>(heap.blocks[block]);
-
- size_t usedCells = curBlock->usedCells;
- Cell* freeList = curBlock->freeList;
-
- if (usedCells == HeapConstants<heapType>::cellsPerBlock) {
- // special case with a block where all cells are used -- testing indicates this happens often
- for (size_t i = 0; i < HeapConstants<heapType>::cellsPerBlock; i++) {
- if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
- Cell* cell = curBlock->cells + i;
-
- if (heapType != NumberHeap) {
- JSCell* imp = reinterpret_cast<JSCell*>(cell);
- // special case for allocated but uninitialized object
- // (We don't need this check earlier because nothing prior this point
- // assumes the object has a valid vptr.)
- if (cell->u.freeCell.zeroIfFree == 0)
- continue;
-
- imp->~JSCell();
- }
-
- --usedCells;
- --numLiveObjects;
-
- // put cell on the free list
- cell->u.freeCell.zeroIfFree = 0;
- cell->u.freeCell.next = freeList - (cell + 1);
- freeList = cell;
- }
- }
- } else {
- size_t minimumCellsToProcess = usedCells;
- for (size_t i = 0; (i < minimumCellsToProcess) & (i < HeapConstants<heapType>::cellsPerBlock); i++) {
- Cell* cell = curBlock->cells + i;
- if (cell->u.freeCell.zeroIfFree == 0) {
- ++minimumCellsToProcess;
- } else {
- if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
- if (heapType != NumberHeap) {
- JSCell* imp = reinterpret_cast<JSCell*>(cell);
- imp->~JSCell();
- }
- --usedCells;
- --numLiveObjects;
-
- // put cell on the free list
- cell->u.freeCell.zeroIfFree = 0;
- cell->u.freeCell.next = freeList - (cell + 1);
- freeList = cell;
- }
- }
- }
- }
-
- curBlock->usedCells = static_cast<uint32_t>(usedCells);
- curBlock->freeList = freeList;
- curBlock->marked.clearAll();
-
- if (!usedCells)
- ++emptyBlocks;
- }
-
- if (heap.numLiveObjects != numLiveObjects)
- heap.firstBlockWithPossibleSpace = 0;
-
- heap.numLiveObjects = numLiveObjects;
- heap.numLiveObjectsAtLastCollect = numLiveObjects;
- heap.extraCost = 0;
-
- if (!emptyBlocks)
- return numLiveObjects;
+size_t Heap::markedCells(size_t startBlock, size_t startCell) const
+{
+ ASSERT(startBlock <= m_heap.usedBlocks);
+ ASSERT(startCell < HeapConstants::cellsPerBlock);
- size_t neededCells = 1.25f * (numLiveObjects + max(ALLOCATIONS_PER_COLLECTION, numLiveObjects));
- size_t neededBlocks = (neededCells + HeapConstants<heapType>::cellsPerBlock - 1) / HeapConstants<heapType>::cellsPerBlock;
- for (size_t block = 0; block < heap.usedBlocks; block++) {
- if (heap.usedBlocks <= neededBlocks)
- break;
+ if (startBlock >= m_heap.usedBlocks)
+ return 0;
+
+ size_t result = 0;
+ result += m_heap.blocks[startBlock]->marked.count(startCell);
+ for (size_t i = startBlock + 1; i < m_heap.usedBlocks; ++i)
+ result += m_heap.blocks[i]->marked.count();
+
+ return result;
+}
- Block* curBlock = reinterpret_cast<Block*>(heap.blocks[block]);
- if (curBlock->usedCells)
- continue;
+void Heap::sweep()
+{
+ ASSERT(m_heap.operationInProgress == NoOperation);
+ if (m_heap.operationInProgress != NoOperation)
+ CRASH();
+ m_heap.operationInProgress = Collection;
+
+#if !ENABLE(JSC_ZOMBIES)
+ Structure* dummyMarkableCellStructure = m_globalData->dummyMarkableCellStructure.get();
+#endif
- freeBlock<heapType>(block);
- block--; // Don't move forward a step in this case
+ DeadObjectIterator it(m_heap, m_heap.nextBlock, m_heap.nextCell);
+ DeadObjectIterator end(m_heap, m_heap.usedBlocks);
+ for ( ; it != end; ++it) {
+ JSCell* cell = *it;
+#if ENABLE(JSC_ZOMBIES)
+ if (!cell->isZombie()) {
+ const ClassInfo* info = cell->classInfo();
+ cell->~JSCell();
+ new (cell) JSZombie(info, JSZombie::leakedZombieStructure());
+ Heap::markCell(cell);
+ }
+#else
+ cell->~JSCell();
+ // Callers of sweep assume it's safe to mark any cell in the heap.
+ new (cell) JSCell(dummyMarkableCellStructure);
+#endif
}
- return numLiveObjects;
+ m_heap.operationInProgress = NoOperation;
}
-bool Heap::collect()
+void Heap::markRoots()
{
#ifndef NDEBUG
if (m_globalData->isSharedInstance) {
@@ -1211,27 +1161,34 @@ bool Heap::collect()
}
#endif
- ASSERT((primaryHeap.operationInProgress == NoOperation) | (numberHeap.operationInProgress == NoOperation));
- if ((primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation))
+ ASSERT(m_heap.operationInProgress == NoOperation);
+ if (m_heap.operationInProgress != NoOperation)
CRASH();
- JAVASCRIPTCORE_GC_BEGIN();
- primaryHeap.operationInProgress = Collection;
- numberHeap.operationInProgress = Collection;
+ m_heap.operationInProgress = Collection;
- // MARK: first mark all referenced objects recursively starting out from the set of root objects
MarkStack& markStack = m_globalData->markStack;
+
+ // Reset mark bits.
+ clearMarkBits();
+
+ // Mark stack roots.
markStackObjectsConservatively(markStack);
+ m_globalData->interpreter->registerFile().markCallFrames(markStack, this);
+
+ // Mark explicitly registered roots.
markProtectedObjects(markStack);
+
#if QT_BUILD_SCRIPT_LIB
if (m_globalData->clientData)
m_globalData->clientData->mark(markStack);
#endif
+
+ // Mark misc. other roots.
if (m_markListSet && m_markListSet->size())
MarkedArgumentBuffer::markLists(markStack, *m_markListSet);
if (m_globalData->exception)
markStack.append(m_globalData->exception);
- m_globalData->interpreter->registerFile().markCallFrames(markStack, this);
m_globalData->smallStrings.markChildren(markStack);
if (m_globalData->functionCodeBlockBeingReparsed)
m_globalData->functionCodeBlockBeingReparsed->markAggregate(markStack);
@@ -1240,41 +1197,28 @@ bool Heap::collect()
markStack.drain();
markStack.compact();
- JAVASCRIPTCORE_GC_MARKED();
-
- size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects;
- size_t numLiveObjects = sweep<PrimaryHeap>();
- numLiveObjects += sweep<NumberHeap>();
-
- primaryHeap.operationInProgress = NoOperation;
- numberHeap.operationInProgress = NoOperation;
- JAVASCRIPTCORE_GC_END(originalLiveObjects, numLiveObjects);
- return numLiveObjects < originalLiveObjects;
+ m_heap.operationInProgress = NoOperation;
}
-size_t Heap::objectCount()
+size_t Heap::objectCount() const
{
- return primaryHeap.numLiveObjects + numberHeap.numLiveObjects - m_globalData->smallStrings.count();
+ return m_heap.nextBlock * HeapConstants::cellsPerBlock // allocated full blocks
+ + m_heap.nextCell // allocated cells in current block
+ + markedCells(m_heap.nextBlock, m_heap.nextCell) // marked cells in remainder of m_heap
+ - m_heap.usedBlocks; // 1 cell per block is a dummy sentinel
}
-template <HeapType heapType>
-static void addToStatistics(Heap::Statistics& statistics, const CollectorHeap& heap)
+void Heap::addToStatistics(Heap::Statistics& statistics) const
{
- 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;
- }
- }
+ statistics.size += m_heap.usedBlocks * BLOCK_SIZE;
+ statistics.free += m_heap.usedBlocks * BLOCK_SIZE - (objectCount() * HeapConstants::cellSize);
}
Heap::Statistics Heap::statistics() const
{
Statistics statistics = { 0, 0 };
- JSC::addToStatistics<PrimaryHeap>(statistics, primaryHeap);
- JSC::addToStatistics<NumberHeap>(statistics, numberHeap);
+ addToStatistics(statistics);
return statistics;
}
@@ -1293,9 +1237,6 @@ size_t Heap::globalObjectCount()
size_t Heap::protectedGlobalObjectCount()
{
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->lock();
-
size_t count = 0;
if (JSGlobalObject* head = m_globalData->head) {
JSGlobalObject* o = head;
@@ -1306,23 +1247,12 @@ size_t Heap::protectedGlobalObjectCount()
} while (o != head);
}
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->unlock();
-
return count;
}
size_t Heap::protectedObjectCount()
{
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->lock();
-
- size_t result = m_protectedValues.size();
-
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->unlock();
-
- return result;
+ return m_protectedValues.size();
}
static const char* typeName(JSCell* cell)
@@ -1335,6 +1265,10 @@ static const char* typeName(JSCell* cell)
#endif
if (cell->isGetterSetter())
return "gettersetter";
+ if (cell->isAPIValueWrapper())
+ return "value wrapper";
+ if (cell->isPropertyNameIterator())
+ return "for-in iterator";
ASSERT(cell->isObject());
const ClassInfo* info = cell->classInfo();
return info ? info->className : "Object";
@@ -1344,32 +1278,70 @@ HashCountedSet<const char*>* Heap::protectedObjectTypeCounts()
{
HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->lock();
-
ProtectCountSet::iterator end = m_protectedValues.end();
for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
counts->add(typeName(it->first));
- if (m_protectedValuesMutex)
- m_protectedValuesMutex->unlock();
-
return counts;
}
bool Heap::isBusy()
{
- return (primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation);
+ return m_heap.operationInProgress != NoOperation;
+}
+
+void Heap::reset()
+{
+ JAVASCRIPTCORE_GC_BEGIN();
+
+ markRoots();
+
+ JAVASCRIPTCORE_GC_MARKED();
+
+ m_heap.nextCell = 0;
+ m_heap.nextBlock = 0;
+ m_heap.nextNumber = 0;
+ m_heap.extraCost = 0;
+#if ENABLE(JSC_ZOMBIES)
+ sweep();
+#endif
+ resizeBlocks();
+
+ JAVASCRIPTCORE_GC_END();
+}
+
+void Heap::collectAllGarbage()
+{
+ JAVASCRIPTCORE_GC_BEGIN();
+
+ // If the last iteration through the heap deallocated blocks, we need
+ // to clean up remaining garbage before marking. Otherwise, the conservative
+ // marking mechanism might follow a pointer to unmapped memory.
+ if (m_heap.didShrink)
+ sweep();
+
+ markRoots();
+
+ JAVASCRIPTCORE_GC_MARKED();
+
+ m_heap.nextCell = 0;
+ m_heap.nextBlock = 0;
+ m_heap.nextNumber = 0;
+ m_heap.extraCost = 0;
+ sweep();
+ resizeBlocks();
+
+ JAVASCRIPTCORE_GC_END();
}
-Heap::iterator Heap::primaryHeapBegin()
+LiveObjectIterator Heap::primaryHeapBegin()
{
- return iterator(primaryHeap.blocks, primaryHeap.blocks + primaryHeap.usedBlocks);
+ return LiveObjectIterator(m_heap, 0);
}
-Heap::iterator Heap::primaryHeapEnd()
+LiveObjectIterator Heap::primaryHeapEnd()
{
- return iterator(primaryHeap.blocks + primaryHeap.usedBlocks, primaryHeap.blocks + primaryHeap.usedBlocks);
+ return LiveObjectIterator(m_heap, m_heap.usedBlocks);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
index 0ecff19..7f7a679 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.h
@@ -28,9 +28,9 @@
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
+#include <wtf/StdLibExtras.h>
#include <wtf/Threading.h>
-// This is supremely lame that we require pthreads to build on windows.
#if ENABLE(JSC_MULTIPLE_THREADS)
#include <pthread.h>
#endif
@@ -47,19 +47,21 @@ namespace JSC {
class MarkStack;
enum OperationInProgress { NoOperation, Allocation, Collection };
- enum HeapType { PrimaryHeap, NumberHeap };
- template <HeapType> class CollectorHeapIterator;
+ class LiveObjectIterator;
struct CollectorHeap {
+ size_t nextBlock;
+ size_t nextCell;
CollectorBlock** blocks;
+
+ void* nextNumber;
+
size_t numBlocks;
size_t usedBlocks;
- size_t firstBlockWithPossibleSpace;
- size_t numLiveObjects;
- size_t numLiveObjectsAtLastCollect;
size_t extraCost;
+ bool didShrink;
OperationInProgress operationInProgress;
};
@@ -67,36 +69,27 @@ namespace JSC {
class Heap : public Noncopyable {
public:
class Thread;
- typedef CollectorHeapIterator<PrimaryHeap> iterator;
void destroy();
-#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
- // We can inline these functions because everything is compiled as
- // one file, so the heapAllocate template definitions are available.
- // However, allocateNumber is used via jsNumberCell outside JavaScriptCore.
- // Thus allocateNumber needs to provide a non-inline version too.
- void* inlineAllocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); }
- void* inlineAllocate(size_t s) { return heapAllocate<PrimaryHeap>(s); }
-#endif
void* allocateNumber(size_t);
void* allocate(size_t);
- bool collect();
bool isBusy(); // true if an allocation or collection is in progress
+ void collectAllGarbage();
- static const size_t minExtraCostSize = 256;
+ static const size_t minExtraCost = 256;
+ static const size_t maxExtraCost = 1024 * 1024;
void reportExtraMemoryCost(size_t cost);
- size_t objectCount();
+ size_t objectCount() const;
struct Statistics {
size_t size;
size_t free;
};
Statistics statistics() const;
- void setGCProtectNeedsLocking();
void protect(JSValue);
void unprotect(JSValue);
@@ -120,13 +113,12 @@ namespace JSC {
JSGlobalData* globalData() const { return m_globalData; }
static bool isNumber(JSCell*);
- // Iterators for the object heap.
- iterator primaryHeapBegin();
- iterator primaryHeapEnd();
+ LiveObjectIterator primaryHeapBegin();
+ LiveObjectIterator primaryHeapEnd();
private:
- template <HeapType heapType> void* heapAllocate(size_t);
- template <HeapType heapType> size_t sweep();
+ void reset();
+ void sweep();
static CollectorBlock* cellBlock(const JSCell*);
static size_t cellOffset(const JSCell*);
@@ -134,12 +126,22 @@ namespace JSC {
Heap(JSGlobalData*);
~Heap();
- template <HeapType heapType> NEVER_INLINE CollectorBlock* allocateBlock();
- template <HeapType heapType> NEVER_INLINE void freeBlock(size_t);
- NEVER_INLINE void freeBlock(CollectorBlock*);
- void freeBlocks(CollectorHeap*);
+ NEVER_INLINE CollectorBlock* allocateBlock();
+ NEVER_INLINE void freeBlock(size_t);
+ NEVER_INLINE void freeBlockPtr(CollectorBlock*);
+ void freeBlocks();
+ void resizeBlocks();
+ void growBlocks(size_t neededBlocks);
+ void shrinkBlocks(size_t neededBlocks);
+ void clearMarkBits();
+ void clearMarkBits(CollectorBlock*);
+ size_t markedCells(size_t startBlock = 0, size_t startCell = 0) const;
void recordExtraCost(size_t);
+
+ void addToStatistics(Statistics&) const;
+
+ void markRoots();
void markProtectedObjects(MarkStack&);
void markCurrentThreadConservatively(MarkStack&);
void markCurrentThreadConservativelyInternal(MarkStack&);
@@ -148,10 +150,8 @@ namespace JSC {
typedef HashCountedSet<JSCell*> ProtectCountSet;
- CollectorHeap primaryHeap;
- CollectorHeap numberHeap;
+ CollectorHeap m_heap;
- OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking().
ProtectCountSet m_protectedValues;
HashSet<MarkedArgumentBuffer*>* m_markListSet;
@@ -181,7 +181,7 @@ namespace JSC {
#endif
template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; };
-#if PLATFORM(WINCE) || PLATFORM(SYMBIAN)
+#if OS(WINCE) || OS(SYMBIAN)
const size_t BLOCK_SIZE = 64 * 1024; // 64k
#else
const size_t BLOCK_SIZE = 64 * 4096; // 256k
@@ -196,87 +196,60 @@ namespace JSC {
const size_t SMALL_CELL_SIZE = CELL_SIZE / 2;
const size_t CELL_MASK = CELL_SIZE - 1;
const size_t CELL_ALIGN_MASK = ~CELL_MASK;
- const size_t CELLS_PER_BLOCK = (BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof(void *) * 8 - 2 * (7 + 3 * 8)) / (CELL_SIZE * 8 + 2);
- const size_t SMALL_CELLS_PER_BLOCK = 2 * CELLS_PER_BLOCK;
+ const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*)) * 8 * CELL_SIZE / (8 * CELL_SIZE + 1) / CELL_SIZE; // one bitmap byte can represent 8 cells.
+
const size_t BITMAP_SIZE = (CELLS_PER_BLOCK + 7) / 8;
const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t);
-
+
struct CollectorBitmap {
uint32_t bits[BITMAP_WORDS];
bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); }
void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); }
void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); }
void clearAll() { memset(bits, 0, sizeof(bits)); }
+ size_t count(size_t startCell = 0)
+ {
+ size_t result = 0;
+ for ( ; (startCell & 0x1F) != 0; ++startCell) {
+ if (get(startCell))
+ ++result;
+ }
+ for (size_t i = startCell >> 5; i < BITMAP_WORDS; ++i)
+ result += WTF::bitCount(bits[i]);
+ return result;
+ }
+ size_t isEmpty() // Much more efficient than testing count() == 0.
+ {
+ for (size_t i = 0; i < BITMAP_WORDS; ++i)
+ if (bits[i] != 0)
+ return false;
+ return true;
+ }
};
struct CollectorCell {
- union {
- double memory[CELL_ARRAY_LENGTH];
- struct {
- void* zeroIfFree;
- ptrdiff_t next;
- } freeCell;
- } u;
- };
-
- struct SmallCollectorCell {
- union {
- double memory[CELL_ARRAY_LENGTH / 2];
- struct {
- void* zeroIfFree;
- ptrdiff_t next;
- } freeCell;
- } u;
+ double memory[CELL_ARRAY_LENGTH];
};
class CollectorBlock {
public:
CollectorCell cells[CELLS_PER_BLOCK];
- uint32_t usedCells;
- CollectorCell* freeList;
- CollectorBitmap marked;
- Heap* heap;
- HeapType type;
- };
-
- class SmallCellCollectorBlock {
- public:
- SmallCollectorCell cells[SMALL_CELLS_PER_BLOCK];
- uint32_t usedCells;
- SmallCollectorCell* freeList;
CollectorBitmap marked;
Heap* heap;
- HeapType type;
};
-
- template <HeapType heapType> struct HeapConstants;
- template <> struct HeapConstants<PrimaryHeap> {
+ struct HeapConstants {
static const size_t cellSize = CELL_SIZE;
static const size_t cellsPerBlock = CELLS_PER_BLOCK;
- static const size_t bitmapShift = 0;
typedef CollectorCell Cell;
typedef CollectorBlock Block;
};
- template <> struct HeapConstants<NumberHeap> {
- static const size_t cellSize = SMALL_CELL_SIZE;
- static const size_t cellsPerBlock = SMALL_CELLS_PER_BLOCK;
- static const size_t bitmapShift = 1;
- typedef SmallCollectorCell Cell;
- typedef SmallCellCollectorBlock Block;
- };
-
inline CollectorBlock* Heap::cellBlock(const JSCell* cell)
{
return reinterpret_cast<CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK);
}
- inline bool Heap::isNumber(JSCell* cell)
- {
- return Heap::cellBlock(cell)->type == NumberHeap;
- }
-
inline size_t Heap::cellOffset(const JSCell* cell)
{
return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
@@ -294,8 +267,20 @@ namespace JSC {
inline void Heap::reportExtraMemoryCost(size_t cost)
{
- if (cost > minExtraCostSize)
- recordExtraCost(cost / (CELL_SIZE * 2));
+ if (cost > minExtraCost)
+ recordExtraCost(cost);
+ }
+
+ inline void* Heap::allocateNumber(size_t s)
+ {
+ if (void* result = m_heap.nextNumber) {
+ m_heap.nextNumber = 0;
+ return result;
+ }
+
+ void* result = allocate(s);
+ m_heap.nextNumber = static_cast<char*>(result) + (CELL_SIZE / 2);
+ return result;
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CollectorHeapIterator.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CollectorHeapIterator.h
index e38a852..e4f2f91 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CollectorHeapIterator.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CollectorHeapIterator.h
@@ -31,58 +31,108 @@
namespace JSC {
- template <HeapType heapType> class CollectorHeapIterator {
+ class CollectorHeapIterator {
public:
- CollectorHeapIterator(CollectorBlock** block, CollectorBlock** endBlock);
-
- bool operator!=(const CollectorHeapIterator<heapType>& other) { return m_block != other.m_block || m_cell != other.m_cell; }
- CollectorHeapIterator<heapType>& operator++();
+ bool operator!=(const CollectorHeapIterator& other);
JSCell* operator*() const;
- private:
- typedef typename HeapConstants<heapType>::Block Block;
- typedef typename HeapConstants<heapType>::Cell Cell;
-
- Block** m_block;
- Block** m_endBlock;
- Cell* m_cell;
- Cell* m_endCell;
+ protected:
+ CollectorHeapIterator(CollectorHeap&, size_t startBlock, size_t startCell);
+ void advance(size_t cellsPerBlock);
+
+ CollectorHeap& m_heap;
+ size_t m_block;
+ size_t m_cell;
+ };
+
+ class LiveObjectIterator : public CollectorHeapIterator {
+ public:
+ LiveObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0);
+ LiveObjectIterator& operator++();
+ };
+
+ class DeadObjectIterator : public CollectorHeapIterator {
+ public:
+ DeadObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0);
+ DeadObjectIterator& operator++();
+ };
+
+ class ObjectIterator : public CollectorHeapIterator {
+ public:
+ ObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0);
+ ObjectIterator& operator++();
};
- template <HeapType heapType>
- CollectorHeapIterator<heapType>::CollectorHeapIterator(CollectorBlock** block, CollectorBlock** endBlock)
- : m_block(reinterpret_cast<Block**>(block))
- , m_endBlock(reinterpret_cast<Block**>(endBlock))
- , m_cell(m_block == m_endBlock ? 0 : (*m_block)->cells)
- , m_endCell(m_block == m_endBlock ? 0 : (*m_block)->cells + HeapConstants<heapType>::cellsPerBlock)
+ inline CollectorHeapIterator::CollectorHeapIterator(CollectorHeap& heap, size_t startBlock, size_t startCell)
+ : m_heap(heap)
+ , m_block(startBlock)
+ , m_cell(startCell)
+ {
+ }
+
+ inline bool CollectorHeapIterator::operator!=(const CollectorHeapIterator& other)
+ {
+ return m_block != other.m_block || m_cell != other.m_cell;
+ }
+
+ inline JSCell* CollectorHeapIterator::operator*() const
+ {
+ return reinterpret_cast<JSCell*>(m_heap.blocks[m_block]->cells + m_cell);
+ }
+
+ inline void CollectorHeapIterator::advance(size_t cellsPerBlock)
+ {
+ ++m_cell;
+ if (m_cell == cellsPerBlock) {
+ m_cell = 0;
+ ++m_block;
+ }
+ }
+
+ inline LiveObjectIterator::LiveObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell)
+ : CollectorHeapIterator(heap, startBlock, startCell - 1)
+ {
+ ++(*this);
+ }
+
+ inline LiveObjectIterator& LiveObjectIterator::operator++()
+ {
+ if (m_block < m_heap.nextBlock || m_cell < m_heap.nextCell) {
+ advance(HeapConstants::cellsPerBlock);
+ return *this;
+ }
+
+ do {
+ advance(HeapConstants::cellsPerBlock);
+ } while (m_block < m_heap.usedBlocks && !m_heap.blocks[m_block]->marked.get(m_cell));
+ return *this;
+ }
+
+ inline DeadObjectIterator::DeadObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell)
+ : CollectorHeapIterator(heap, startBlock, startCell - 1)
{
- if (m_cell && m_cell->u.freeCell.zeroIfFree == 0)
- ++*this;
+ ++(*this);
}
- template <HeapType heapType>
- CollectorHeapIterator<heapType>& CollectorHeapIterator<heapType>::operator++()
+ inline DeadObjectIterator& DeadObjectIterator::operator++()
{
do {
- for (++m_cell; m_cell != m_endCell; ++m_cell)
- if (m_cell->u.freeCell.zeroIfFree != 0) {
- return *this;
- }
-
- if (++m_block != m_endBlock) {
- m_cell = (*m_block)->cells;
- m_endCell = (*m_block)->cells + HeapConstants<heapType>::cellsPerBlock;
- }
- } while(m_block != m_endBlock);
-
- m_cell = 0;
+ advance(HeapConstants::cellsPerBlock);
+ ASSERT(m_block > m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell >= m_heap.nextCell));
+ } while (m_block < m_heap.usedBlocks && m_heap.blocks[m_block]->marked.get(m_cell));
return *this;
}
- template <HeapType heapType>
- JSCell* CollectorHeapIterator<heapType>::operator*() const
+ inline ObjectIterator::ObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell)
+ : CollectorHeapIterator(heap, startBlock, startCell - 1)
{
- return reinterpret_cast<JSCell*>(m_cell);
+ ++(*this);
+ }
+
+ inline ObjectIterator& ObjectIterator::operator++()
+ {
+ advance(HeapConstants::cellsPerBlock);
+ return *this;
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h
index abe5038..de24f4a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -50,6 +50,7 @@
macro(get) \
macro(getPrototypeOf) \
macro(getOwnPropertyDescriptor) \
+ macro(getOwnPropertyNames) \
macro(hasOwnProperty) \
macro(ignoreCase) \
macro(index) \
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp
index 3ad467d..2f88df9 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Completion.cpp
@@ -31,18 +31,15 @@
#include "Debugger.h"
#include <stdio.h>
-#ifdef QT_BUILD_SCRIPT_LIB
-#include "DebuggerCallFrame.h"
-#endif
-
namespace JSC {
Completion checkSyntax(ExecState* exec, const SourceCode& source)
{
JSLock lock(exec);
+ ASSERT(exec->globalData().identifierTable == currentIdentifierTable());
- ProgramExecutable program(exec, source);
- JSObject* error = program.checkSyntax(exec);
+ RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
+ JSObject* error = program->checkSyntax(exec);
if (error)
return Completion(Throw, error);
@@ -52,23 +49,23 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source)
Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue thisValue)
{
JSLock lock(exec);
+ ASSERT(exec->globalData().identifierTable == currentIdentifierTable());
- ProgramExecutable program(exec, source);
- JSObject* error = program.compile(exec, scopeChain.node());
+ RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
+ JSObject* error = program->compile(exec, scopeChain.node());
if (error)
return Completion(Throw, error);
JSObject* thisObj = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
JSValue exception;
- JSValue result = exec->interpreter()->execute(&program, exec, scopeChain.node(), thisObj, &exception);
+ JSValue result = exec->interpreter()->execute(program.get(), exec, scopeChain.node(), thisObj, &exception);
if (exception) {
if (exception.isObject() && asObject(exception)->isWatchdogException())
return Completion(Interrupted, exception);
return Completion(Throw, exception);
}
-
return Completion(Normal, result);
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.cpp
index 3dfc918..06f9459 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.cpp
@@ -28,7 +28,6 @@
#include "JSFunction.h"
-
#ifdef QT_BUILD_SCRIPT_LIB
#include "Debugger.h"
#include "DebuggerCallFrame.h"
@@ -53,13 +52,13 @@ JSObject* JSC::NativeConstrWrapper::operator() (ExecState* exec, JSObject* jsobj
}
#endif
-JSObject* construct(ExecState* exec, JSValue callee, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
+JSObject* construct(ExecState* exec, JSValue object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
{
if (constructType == ConstructTypeHost)
- return constructData.native.function(exec, asObject(callee), args);
+ return constructData.native.function(exec, asObject(object), args);
ASSERT(constructType == ConstructTypeJS);
// FIXME: Can this be done more efficiently using the constructData?
- return asFunction(callee)->construct(exec, args);
+ return asFunction(object)->construct(exec, args);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h
index 1dcfb00..9298f51 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ConstructData.h
@@ -70,7 +70,7 @@ namespace JSC {
};
#endif
-#if defined(QT_BUILD_SCRIPT_LIB) && PLATFORM(SOLARIS)
+#if defined(QT_BUILD_SCRIPT_LIB) && OS(SOLARIS)
struct
#else
union
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp
index 1879c3f..2e476b3 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.cpp
@@ -35,7 +35,7 @@
#include <wtf/DateMath.h>
#include <wtf/MathExtras.h>
-#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if OS(WINCE) && !PLATFORM(QT)
extern "C" time_t time(time_t* timer); // Provided by libce.
#endif
@@ -57,7 +57,7 @@ static JSValue JSC_HOST_CALL dateParse(ExecState*, JSObject*, JSValue, const Arg
static JSValue JSC_HOST_CALL dateNow(ExecState*, JSObject*, JSValue, const ArgList&);
static JSValue JSC_HOST_CALL dateUTC(ExecState*, JSObject*, JSValue, const ArgList&);
-DateConstructor::DateConstructor(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, DatePrototype* datePrototype)
+DateConstructor::DateConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, DatePrototype* datePrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, datePrototype->classInfo()->className))
{
putDirectWithoutTransition(exec->propertyNames().prototype, datePrototype, DontEnum|DontDelete|ReadOnly);
@@ -77,14 +77,14 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
double value;
if (numArgs == 0) // new Date() ECMA 15.9.3.3
- value = getCurrentUTCTime();
+ value = jsCurrentTime();
else if (numArgs == 1) {
if (args.at(0).inherits(&DateInstance::info))
value = asDateInstance(args.at(0))->internalNumber();
else {
JSValue primitive = args.at(0).toPrimitive(exec);
if (primitive.isString())
- value = parseDate(primitive.getString());
+ value = parseDate(exec, primitive.getString(exec));
else
value = primitive.toNumber(exec);
}
@@ -108,13 +108,11 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
t.second = args.at(5).toInt32(exec);
t.isDST = -1;
double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0;
- value = gregorianDateTimeToMS(t, ms, false);
+ value = gregorianDateTimeToMS(exec, t, ms, false);
}
}
- DateInstance* result = new (exec) DateInstance(exec->lexicalGlobalObject()->dateStructure());
- result->setInternalValue(jsNumber(exec, timeClip(value)));
- return result;
+ return new (exec) DateInstance(exec, value);
}
static JSObject* constructWithDateConstructor(ExecState* exec, JSObject*, const ArgList& args)
@@ -134,8 +132,12 @@ static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const
time_t localTime = time(0);
tm localTM;
getLocalTime(&localTime, &localTM);
- GregorianDateTime ts(localTM);
- return jsNontrivialString(exec, formatDate(ts) + " " + formatTime(ts, false));
+ GregorianDateTime ts(exec, localTM);
+ DateConversionBuffer date;
+ DateConversionBuffer time;
+ formatDate(ts, date);
+ formatTime(ts, time);
+ return jsNontrivialString(exec, makeString(date, " ", time));
}
CallType DateConstructor::getCallData(CallData& callData)
@@ -146,12 +148,12 @@ CallType DateConstructor::getCallData(CallData& callData)
static JSValue JSC_HOST_CALL dateParse(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, parseDate(args.at(0).toString(exec)));
+ return jsNumber(exec, parseDate(exec, args.at(0).toString(exec)));
}
static JSValue JSC_HOST_CALL dateNow(ExecState* exec, JSObject*, JSValue, const ArgList&)
{
- return jsNumber(exec, getCurrentUTCTime());
+ return jsNumber(exec, jsCurrentTime());
}
static JSValue JSC_HOST_CALL dateUTC(ExecState* exec, JSObject*, JSValue, const ArgList& args)
@@ -175,7 +177,7 @@ static JSValue JSC_HOST_CALL dateUTC(ExecState* exec, JSObject*, JSValue, const
t.minute = args.at(4).toInt32(exec);
t.second = args.at(5).toInt32(exec);
double ms = (n >= 7) ? args.at(6).toNumber(exec) : 0;
- return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
+ return jsNumber(exec, gregorianDateTimeToMS(exec, t, ms, true));
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.h
index dcef3cc..10e450e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class DateConstructor : public InternalFunction {
public:
- DateConstructor(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure, DatePrototype*);
+ DateConstructor(ExecState*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure, DatePrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.cpp
index a725478..f129407 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.cpp
@@ -43,6 +43,7 @@
#include "config.h"
#include "DateConversion.h"
+#include "CallFrame.h"
#include "UString.h"
#include <wtf/DateMath.h>
#include <wtf/StringExtras.h>
@@ -51,51 +52,51 @@ using namespace WTF;
namespace JSC {
-double parseDate(const UString &date)
+double parseDate(ExecState* exec, const UString &date)
{
- return parseDateFromNullTerminatedCharacters(date.UTF8String().c_str());
+ if (date == exec->globalData().cachedDateString)
+ return exec->globalData().cachedDateStringValue;
+ double value = parseDateFromNullTerminatedCharacters(exec, date.UTF8String().c_str());
+ exec->globalData().cachedDateString = date;
+ exec->globalData().cachedDateStringValue = value;
+ return value;
}
-UString formatDate(const GregorianDateTime &t)
+void formatDate(const GregorianDateTime &t, DateConversionBuffer& buffer)
{
- char buffer[100];
- snprintf(buffer, sizeof(buffer), "%s %s %02d %04d",
+ snprintf(buffer, DateConversionBufferSize, "%s %s %02d %04d",
weekdayName[(t.weekDay + 6) % 7],
monthName[t.month], t.monthDay, t.year + 1900);
- return buffer;
}
-UString formatDateUTCVariant(const GregorianDateTime &t)
+void formatDateUTCVariant(const GregorianDateTime &t, DateConversionBuffer& buffer)
{
- char buffer[100];
- snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d",
+ snprintf(buffer, DateConversionBufferSize, "%s, %02d %s %04d",
weekdayName[(t.weekDay + 6) % 7],
t.monthDay, monthName[t.month], t.year + 1900);
- return buffer;
}
-UString formatTime(const GregorianDateTime &t, bool utc)
+void formatTime(const GregorianDateTime &t, DateConversionBuffer& buffer)
{
- char buffer[100];
- if (utc) {
- snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
- } else {
- int offset = abs(gmtoffset(t));
- char timeZoneName[70];
- struct tm gtm = t;
- strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
+ int offset = abs(gmtoffset(t));
+ char timeZoneName[70];
+ struct tm gtm = t;
+ strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
- if (timeZoneName[0]) {
- snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
- t.hour, t.minute, t.second,
- gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName);
- } else {
- snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",
- t.hour, t.minute, t.second,
- gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
- }
+ if (timeZoneName[0]) {
+ snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d (%s)",
+ t.hour, t.minute, t.second,
+ gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName);
+ } else {
+ snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d",
+ t.hour, t.minute, t.second,
+ gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
}
- return UString(buffer);
+}
+
+void formatTimeUTC(const GregorianDateTime &t, DateConversionBuffer& buffer)
+{
+ snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.h
index 0d12815..ff32b50 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateConversion.h
@@ -42,18 +42,21 @@
#ifndef DateConversion_h
#define DateConversion_h
-namespace WTF {
- struct GregorianDateTime;
-}
+#include "UString.h"
namespace JSC {
-class UString;
+class ExecState;
+struct GregorianDateTime;
-double parseDate(const UString&);
-UString formatDate(const WTF::GregorianDateTime&);
-UString formatDateUTCVariant(const WTF::GregorianDateTime&);
-UString formatTime(const WTF::GregorianDateTime&, bool inputIsUTC);
+static const unsigned DateConversionBufferSize = 100;
+typedef char DateConversionBuffer[DateConversionBufferSize];
+
+double parseDate(ExecState* exec, const UString&);
+void formatDate(const GregorianDateTime&, DateConversionBuffer&);
+void formatDateUTCVariant(const GregorianDateTime&, DateConversionBuffer&);
+void formatTime(const GregorianDateTime&, DateConversionBuffer&);
+void formatTimeUTC(const GregorianDateTime&, DateConversionBuffer&);
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.cpp
index 62791ae..77a92be 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.cpp
@@ -22,6 +22,8 @@
#include "config.h"
#include "DateInstance.h"
+#include "JSGlobalObject.h"
+
#include <math.h>
#include <wtf/DateMath.h>
#include <wtf/MathExtras.h>
@@ -30,89 +32,50 @@ using namespace WTF;
namespace JSC {
-struct DateInstance::Cache {
- double m_gregorianDateTimeCachedForMS;
- GregorianDateTime m_cachedGregorianDateTime;
- double m_gregorianDateTimeUTCCachedForMS;
- GregorianDateTime m_cachedGregorianDateTimeUTC;
-};
-
const ClassInfo DateInstance::info = {"Date", 0, 0, 0};
-DateInstance::DateInstance(PassRefPtr<Structure> structure)
+DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure)
: JSWrapperObject(structure)
- , m_cache(0)
{
+ setInternalValue(jsNaN(exec));
}
-DateInstance::~DateInstance()
+DateInstance::DateInstance(ExecState* exec, double time)
+ : JSWrapperObject(exec->lexicalGlobalObject()->dateStructure())
{
- delete m_cache;
+ setInternalValue(jsNumber(exec, timeClip(time)));
}
-void DateInstance::msToGregorianDateTime(double milli, bool outputIsUTC, GregorianDateTime& t) const
-{
- if (!m_cache) {
- m_cache = new Cache;
- m_cache->m_gregorianDateTimeCachedForMS = NaN;
- m_cache->m_gregorianDateTimeUTCCachedForMS = NaN;
- }
-
- if (outputIsUTC) {
- if (m_cache->m_gregorianDateTimeUTCCachedForMS != milli) {
- WTF::msToGregorianDateTime(milli, true, m_cache->m_cachedGregorianDateTimeUTC);
- m_cache->m_gregorianDateTimeUTCCachedForMS = milli;
- }
- t.copyFrom(m_cache->m_cachedGregorianDateTimeUTC);
- } else {
- if (m_cache->m_gregorianDateTimeCachedForMS != milli) {
- WTF::msToGregorianDateTime(milli, false, m_cache->m_cachedGregorianDateTime);
- m_cache->m_gregorianDateTimeCachedForMS = milli;
- }
- t.copyFrom(m_cache->m_cachedGregorianDateTime);
- }
-}
-
-bool DateInstance::getTime(GregorianDateTime& t, int& offset) const
+const GregorianDateTime* DateInstance::calculateGregorianDateTime(ExecState* exec) const
{
double milli = internalNumber();
if (isnan(milli))
- return false;
-
- msToGregorianDateTime(milli, false, t);
- offset = gmtoffset(t);
- return true;
+ return 0;
+
+ if (!m_data)
+ m_data = exec->globalData().dateInstanceCache.add(milli);
+
+ if (m_data->m_gregorianDateTimeCachedForMS != milli) {
+ msToGregorianDateTime(exec, milli, false, m_data->m_cachedGregorianDateTime);
+ m_data->m_gregorianDateTimeCachedForMS = milli;
+ }
+ return &m_data->m_cachedGregorianDateTime;
}
-bool DateInstance::getUTCTime(GregorianDateTime& t) const
+const GregorianDateTime* DateInstance::calculateGregorianDateTimeUTC(ExecState* exec) const
{
double milli = internalNumber();
if (isnan(milli))
- return false;
-
- msToGregorianDateTime(milli, true, t);
- return true;
-}
+ return 0;
-bool DateInstance::getTime(double& milli, int& offset) const
-{
- milli = internalNumber();
- if (isnan(milli))
- return false;
-
- GregorianDateTime t;
- msToGregorianDateTime(milli, false, t);
- offset = gmtoffset(t);
- return true;
-}
+ if (!m_data)
+ m_data = exec->globalData().dateInstanceCache.add(milli);
-bool DateInstance::getUTCTime(double& milli) const
-{
- milli = internalNumber();
- if (isnan(milli))
- return false;
-
- return true;
+ if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) {
+ msToGregorianDateTime(exec, milli, true, m_data->m_cachedGregorianDateTimeUTC);
+ m_data->m_gregorianDateTimeUTCCachedForMS = milli;
+ }
+ return &m_data->m_cachedGregorianDateTimeUTC;
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.h
index 3b73521..44b7521 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstance.h
@@ -31,27 +31,41 @@ namespace JSC {
class DateInstance : public JSWrapperObject {
public:
- explicit DateInstance(PassRefPtr<Structure>);
- virtual ~DateInstance();
+ DateInstance(ExecState*, double);
+ explicit DateInstance(ExecState*, NonNullPassRefPtr<Structure>);
double internalNumber() const { return internalValue().uncheckedGetNumber(); }
- bool getTime(WTF::GregorianDateTime&, int& offset) const;
- bool getUTCTime(WTF::GregorianDateTime&) const;
- bool getTime(double& milliseconds, int& offset) const;
- bool getUTCTime(double& milliseconds) const;
-
- static const ClassInfo info;
-
- void msToGregorianDateTime(double, bool outputIsUTC, WTF::GregorianDateTime&) const;
+ static JS_EXPORTDATA const ClassInfo info;
+
+ const GregorianDateTime* gregorianDateTime(ExecState* exec) const
+ {
+ if (m_data && m_data->m_gregorianDateTimeCachedForMS == internalNumber())
+ return &m_data->m_cachedGregorianDateTime;
+ return calculateGregorianDateTime(exec);
+ }
+
+ const GregorianDateTime* gregorianDateTimeUTC(ExecState* exec) const
+ {
+ if (m_data && m_data->m_gregorianDateTimeUTCCachedForMS == internalNumber())
+ return &m_data->m_cachedGregorianDateTimeUTC;
+ return calculateGregorianDateTimeUTC(exec);
+ }
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
+ }
+
+ protected:
+ static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags;
private:
+ const GregorianDateTime* calculateGregorianDateTime(ExecState*) const;
+ const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const;
virtual const ClassInfo* classInfo() const { return &info; }
- using JSWrapperObject::internalValue;
-
- struct Cache;
- mutable Cache* m_cache;
+ mutable RefPtr<DateInstanceData> m_data;
};
DateInstance* asDateInstance(JSValue);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstanceCache.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstanceCache.h
new file mode 100644
index 0000000..d208580
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DateInstanceCache.h
@@ -0,0 +1,94 @@
+/*
+ * 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 DateInstanceCache_h
+#define DateInstanceCache_h
+
+#include <wtf/DateMath.h>
+#include <wtf/HashFunctions.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace JSC {
+
+ extern const double NaN;
+
+ class DateInstanceData : public RefCounted<DateInstanceData> {
+ public:
+ static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); }
+
+ double m_gregorianDateTimeCachedForMS;
+ GregorianDateTime m_cachedGregorianDateTime;
+ double m_gregorianDateTimeUTCCachedForMS;
+ GregorianDateTime m_cachedGregorianDateTimeUTC;
+
+ private:
+ DateInstanceData()
+ : m_gregorianDateTimeCachedForMS(NaN)
+ , m_gregorianDateTimeUTCCachedForMS(NaN)
+ {
+ }
+ };
+
+ class DateInstanceCache {
+ public:
+ DateInstanceCache()
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ for (size_t i = 0; i < cacheSize; ++i)
+ m_cache[i].key = NaN;
+ }
+
+ DateInstanceData* add(double d)
+ {
+ CacheEntry& entry = lookup(d);
+ if (d == entry.key)
+ return entry.value.get();
+
+ entry.key = d;
+ entry.value = DateInstanceData::create();
+ return entry.value.get();
+ }
+
+ private:
+ static const size_t cacheSize = 16;
+
+ struct CacheEntry {
+ double key;
+ RefPtr<DateInstanceData> value;
+ };
+
+ CacheEntry& lookup(double d) { return m_cache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
+
+ CacheEntry m_cache[cacheSize];
+ };
+
+} // namespace JSC
+
+#endif // DateInstanceCache_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp
index c6f7dec..ca9d4ea 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.cpp
@@ -28,7 +28,6 @@
#include "JSString.h"
#include "ObjectPrototype.h"
#include "DateInstance.h"
-#include <float.h>
#if !PLATFORM(MAC) && HAVE(LANGINFO_H)
#include <langinfo.h>
@@ -60,7 +59,7 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
-#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if OS(WINCE) && !PLATFORM(QT)
extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); //provided by libce
#endif
@@ -198,7 +197,7 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L
{
#if HAVE(LANGINFO_H)
static const nl_item formats[] = { D_T_FMT, D_FMT, T_FMT };
-#elif (PLATFORM(WINCE) && !PLATFORM(QT)) || PLATFORM(SYMBIAN)
+#elif (OS(WINCE) && !PLATFORM(QT)) || OS(SYMBIAN)
// strftime() does not support '#' on WinCE or Symbian
static const char* const formatStrings[] = { "%c", "%x", "%X" };
#else
@@ -251,12 +250,12 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L
return jsNontrivialString(exec, timebuffer);
}
-static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double timeInMilliseconds, LocaleDateTimeFormat format, const ArgList&)
+static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double, LocaleDateTimeFormat format, const ArgList&)
{
- GregorianDateTime gregorianDateTime;
- const bool notUTC = false;
- dateObject->msToGregorianDateTime(timeInMilliseconds, notUTC, gregorianDateTime);
- return formatLocaleDate(exec, gregorianDateTime, format);
+ const GregorianDateTime* gregorianDateTime = dateObject->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNontrivialString(exec, "Invalid Date");
+ return formatLocaleDate(exec, *gregorianDateTime, format);
}
#endif // !PLATFORM(MAC)
@@ -395,10 +394,9 @@ const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState
// ECMA 15.9.4
-DatePrototype::DatePrototype(ExecState* exec, PassRefPtr<Structure> structure)
- : DateInstance(structure)
+DatePrototype::DatePrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure)
+ : DateInstance(exec, structure)
{
- setInternalValue(jsNaN(exec));
// The constructor will be added later, after DateConstructor has been built.
}
@@ -420,16 +418,16 @@ JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNontrivialString(exec, "Invalid Date");
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNontrivialString(exec, formatDate(t) + " " + formatTime(t, utc));
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNontrivialString(exec, "Invalid Date");
+ DateConversionBuffer date;
+ DateConversionBuffer time;
+ formatDate(*gregorianDateTime, date);
+ formatTime(*gregorianDateTime, time);
+ return jsNontrivialString(exec, makeString(date, " ", time));
}
JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -437,16 +435,16 @@ JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSVal
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = true;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNontrivialString(exec, "Invalid Date");
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
+ if (!gregorianDateTime)
+ return jsNontrivialString(exec, "Invalid Date");
+ DateConversionBuffer date;
+ DateConversionBuffer time;
+ formatDateUTCVariant(*gregorianDateTime, date);
+ formatTimeUTC(*gregorianDateTime, time);
+ return jsNontrivialString(exec, makeString(date, " ", time));
}
JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -454,19 +452,15 @@ JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSVal
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = true;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (!isfinite(milli))
- return jsNontrivialString(exec, "Invalid Date");
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
+ if (!gregorianDateTime)
+ return jsNontrivialString(exec, "Invalid Date");
// Maximum amount of space we need in buffer: 6 (max. digits in year) + 2 * 5 (2 characters each for month, day, hour, minute, second) + 4 (. + 3 digits for milliseconds)
// 6 for formatting and one for null termination = 27. We add one extra character to allow us to force null termination.
char buffer[28];
- snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + t.year, t.month + 1, t.monthDay, t.hour, t.minute, t.second, static_cast<int>(fmod(milli, 1000)));
+ snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + gregorianDateTime->year, gregorianDateTime->month + 1, gregorianDateTime->monthDay, gregorianDateTime->hour, gregorianDateTime->minute, gregorianDateTime->second, static_cast<int>(fmod(thisDateObj->internalNumber(), 1000)));
buffer[sizeof(buffer) - 1] = 0;
return jsNontrivialString(exec, buffer);
}
@@ -476,16 +470,14 @@ JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSVa
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNontrivialString(exec, "Invalid Date");
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNontrivialString(exec, formatDate(t));
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNontrivialString(exec, "Invalid Date");
+ DateConversionBuffer date;
+ formatDate(*gregorianDateTime, date);
+ return jsNontrivialString(exec, date);
}
JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -493,16 +485,14 @@ JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSVa
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNontrivialString(exec, "Invalid Date");
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNontrivialString(exec, formatTime(t, utc));
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNontrivialString(exec, "Invalid Date");
+ DateConversionBuffer time;
+ formatTime(*gregorianDateTime, time);
+ return jsNontrivialString(exec, time);
}
JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -511,11 +501,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JS
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNontrivialString(exec, "Invalid Date");
-
- return formatLocaleDate(exec, thisDateObj, milli, LocaleDateAndTime, args);
+ return formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleDateAndTime, args);
}
JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -524,11 +510,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNontrivialString(exec, "Invalid Date");
-
- return formatLocaleDate(exec, thisDateObj, milli, LocaleDate, args);
+ return formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleDate, args);
}
JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -537,11 +519,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*
return throwError(exec, TypeError);
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNontrivialString(exec, "Invalid Date");
-
- return formatLocaleDate(exec, thisDateObj, milli, LocaleTime, args);
+ return formatLocaleDate(exec, thisDateObj, thisDateObj->internalNumber(), LocaleTime, args);
}
JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -549,12 +527,7 @@ JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue t
if (!thisValue.inherits(&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 asDateInstance(thisValue)->internalValue();
}
JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -562,16 +535,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSVal
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, 1900 + t.year);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, 1900 + gregorianDateTime->year);
}
JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -579,16 +548,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JS
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = true;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, 1900 + t.year);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, 1900 + gregorianDateTime->year);
}
JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -596,16 +561,16 @@ JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSVal
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = true;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNontrivialString(exec, "Invalid Date");
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
+ if (!gregorianDateTime)
+ return jsNontrivialString(exec, "Invalid Date");
+ DateConversionBuffer date;
+ DateConversionBuffer time;
+ formatDateUTCVariant(*gregorianDateTime, date);
+ formatTimeUTC(*gregorianDateTime, time);
+ return jsNontrivialString(exec, makeString(date, " ", time));
}
JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -613,16 +578,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.month);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->month);
}
JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -630,16 +591,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSVal
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = true;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.month);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->month);
}
JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -647,16 +604,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue t
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.monthDay);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->monthDay);
}
JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -664,16 +617,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValu
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = true;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.monthDay);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->monthDay);
}
JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -681,16 +630,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue th
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.weekDay);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->weekDay);
}
JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -698,16 +643,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = true;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.weekDay);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->weekDay);
}
JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -715,16 +656,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.hour);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->hour);
}
JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -732,16 +669,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSVal
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = true;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.hour);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->hour);
}
JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -749,16 +682,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValu
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.minute);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->minute);
}
JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -766,16 +695,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSV
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = true;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.minute);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->minute);
}
JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -783,16 +708,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValu
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.second);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->second);
}
JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -800,16 +721,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSV
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = true;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, t.second);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, gregorianDateTime->second);
}
JSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -847,16 +764,12 @@ JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*,
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(exec, -gmtoffset(t) / minutesPerHour);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
+ return jsNumber(exec, -gregorianDateTime->utcOffset / minutesPerHour);
}
JSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -889,16 +802,21 @@ static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const
double secs = floor(milli / msPerSecond);
double ms = milli - secs * msPerSecond;
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t);
+ const GregorianDateTime* other = inputIsUTC
+ ? thisDateObj->gregorianDateTimeUTC(exec)
+ : thisDateObj->gregorianDateTime(exec);
+ if (!other)
+ return jsNaN(exec);
- if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) {
+ GregorianDateTime gregorianDateTime;
+ gregorianDateTime.copyFrom(*other);
+ if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &gregorianDateTime)) {
JSValue result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
- JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
+ JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
@@ -916,26 +834,28 @@ static JSValue setNewValueFromDateArgs(ExecState* exec, JSValue thisValue, const
}
double milli = thisDateObj->internalNumber();
- double ms = 0;
-
- GregorianDateTime t;
- if (numArgsToUse == 3 && isnan(milli))
- // Based on ECMA 262 15.9.5.40 - .41 (set[UTC]FullYear)
- // the time must be reset to +0 if it is NaN.
- thisDateObj->msToGregorianDateTime(0, true, t);
- else {
- double secs = floor(milli / msPerSecond);
- ms = milli - secs * msPerSecond;
- thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t);
+ double ms = 0;
+
+ GregorianDateTime gregorianDateTime;
+ if (numArgsToUse == 3 && isnan(milli))
+ msToGregorianDateTime(exec, 0, true, gregorianDateTime);
+ else {
+ ms = milli - floor(milli / msPerSecond) * msPerSecond;
+ const GregorianDateTime* other = inputIsUTC
+ ? thisDateObj->gregorianDateTimeUTC(exec)
+ : thisDateObj->gregorianDateTime(exec);
+ if (!other)
+ return jsNaN(exec);
+ gregorianDateTime.copyFrom(*other);
}
- if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) {
+ if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &gregorianDateTime)) {
JSValue result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
- JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
+ JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
@@ -1029,8 +949,6 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
if (args.isEmpty()) {
JSValue result = jsNaN(exec);
@@ -1041,15 +959,16 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t
double milli = thisDateObj->internalNumber();
double ms = 0;
- GregorianDateTime t;
+ GregorianDateTime gregorianDateTime;
if (isnan(milli))
// Based on ECMA 262 B.2.5 (setYear)
// the time must be reset to +0 if it is NaN.
- thisDateObj->msToGregorianDateTime(0, true, t);
+ msToGregorianDateTime(exec, 0, true, gregorianDateTime);
else {
double secs = floor(milli / msPerSecond);
ms = milli - secs * msPerSecond;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
+ if (const GregorianDateTime* other = thisDateObj->gregorianDateTime(exec))
+ gregorianDateTime.copyFrom(*other);
}
bool ok = true;
@@ -1060,8 +979,8 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t
return result;
}
- t.year = (year > 99 || year < 0) ? year - 1900 : year;
- JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc));
+ gregorianDateTime.year = (year > 99 || year < 0) ? year - 1900 : year;
+ JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, false));
thisDateObj->setInternalValue(result);
return result;
}
@@ -1071,18 +990,14 @@ JSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue t
if (!thisValue.inherits(&DateInstance::info))
return throwError(exec, TypeError);
- const bool utc = false;
-
DateInstance* thisDateObj = asDateInstance(thisValue);
- double milli = thisDateObj->internalNumber();
- if (isnan(milli))
- return jsNaN(exec);
- GregorianDateTime t;
- thisDateObj->msToGregorianDateTime(milli, utc, t);
+ const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return jsNaN(exec);
// NOTE: IE returns the full year even in getYear.
- return jsNumber(exec, t.year);
+ return jsNumber(exec, gregorianDateTime->year);
}
JSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h
index 12fabda..f565775 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/DatePrototype.h
@@ -29,7 +29,7 @@ namespace JSC {
class DatePrototype : public DateInstance {
public:
- DatePrototype(ExecState*, PassRefPtr<Structure>);
+ DatePrototype(ExecState*, NonNullPassRefPtr<Structure>);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
@@ -39,8 +39,12 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultGetPropertyNames));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
+
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags;
+
};
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.cpp
index 07b7e23..b9c3f58 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.cpp
@@ -29,7 +29,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(ErrorConstructor);
-ErrorConstructor::ErrorConstructor(ExecState* exec, PassRefPtr<Structure> structure, ErrorPrototype* errorPrototype)
+ErrorConstructor::ErrorConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, ErrorPrototype* errorPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, errorPrototype->classInfo()->className))
{
// ECMA 15.11.3.1 Error.prototype
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.h
index 2dd4124..e3d789b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorConstructor.h
@@ -30,7 +30,7 @@ namespace JSC {
class ErrorConstructor : public InternalFunction {
public:
- ErrorConstructor(ExecState*, PassRefPtr<Structure>, ErrorPrototype*);
+ ErrorConstructor(ExecState*, NonNullPassRefPtr<Structure>, ErrorPrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.cpp
index 2e2cdce..1cdb87a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.cpp
@@ -25,7 +25,7 @@ namespace JSC {
const ClassInfo ErrorInstance::info = { "Error", 0, 0, 0 };
-ErrorInstance::ErrorInstance(PassRefPtr<Structure> structure)
+ErrorInstance::ErrorInstance(NonNullPassRefPtr<Structure> structure)
: JSObject(structure)
{
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.h
index 6f9d262..9f53b51 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorInstance.h
@@ -27,7 +27,7 @@ namespace JSC {
class ErrorInstance : public JSObject {
public:
- explicit ErrorInstance(PassRefPtr<Structure>);
+ explicit ErrorInstance(NonNullPassRefPtr<Structure>);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.cpp
index 599390e..be9e4b8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -34,7 +34,7 @@ ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
static JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
// ECMA 15.9.4
-ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
+ErrorPrototype::ErrorPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
: ErrorInstance(structure)
{
// The constructor will be added later in ErrorConstructor's constructor
@@ -48,21 +48,19 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure,
JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
JSObject* thisObj = thisValue.toThisObject(exec);
+ JSValue name = thisObj->get(exec, exec->propertyNames().name);
+ JSValue message = thisObj->get(exec, exec->propertyNames().message);
- UString s = "Error";
+ // Mozilla-compatible format.
- JSValue v = thisObj->get(exec, exec->propertyNames().name);
- if (!v.isUndefined())
- s = v.toString(exec);
-
- v = thisObj->get(exec, exec->propertyNames().message);
- if (!v.isUndefined()) {
- // Mozilla-compatible format.
- s += ": ";
- s += v.toString(exec);
+ if (!name.isUndefined()) {
+ if (!message.isUndefined())
+ return jsNontrivialString(exec, makeString(name.toString(exec), ": ", message.toString(exec)));
+ return jsNontrivialString(exec, name.toString(exec));
}
-
- return jsNontrivialString(exec, s);
+ if (!message.isUndefined())
+ return jsNontrivialString(exec, makeString("Error: ", message.toString(exec)));
+ return jsNontrivialString(exec, "Error");
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.h
index 53d12d9..a561590 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ErrorPrototype.h
@@ -29,7 +29,7 @@ namespace JSC {
class ErrorPrototype : public ErrorInstance {
public:
- ErrorPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
+ ErrorPrototype(ExecState*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure);
};
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp
index cc18b95..9bb740e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -66,15 +66,18 @@ JSValue createStackOverflowError(ExecState* exec)
return createError(exec, RangeError, "Maximum call stack size exceeded.");
}
+JSValue createTypeError(ExecState* exec, const char* message)
+{
+ return createError(exec, TypeError, message);
+}
+
JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
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->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
+ JSObject* exception = Error::create(exec, ReferenceError, makeString("Can't find variable: ", ident.ustring()), line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->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);
@@ -83,59 +86,36 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u
static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValue value, UString error)
{
- if (!expressionStop || expressionStart > codeBlock->source()->length()) {
- UString errorText = value.toString(exec);
- errorText.append(" is ");
- errorText.append(error);
- return errorText;
- }
+ if (!expressionStop || expressionStart > codeBlock->source()->length())
+ return makeString(value.toString(exec), " is ", error);
+ if (expressionStart < expressionStop)
+ return makeString("Result of expression '", codeBlock->source()->getRange(expressionStart, expressionStop), "' [", value.toString(exec), "] is ", error, ".");
- UString errorText = "Result of expression ";
-
- if (expressionStart < expressionStop) {
- errorText.append('\'');
- errorText.append(codeBlock->source()->getRange(expressionStart, expressionStop));
- errorText.append("' [");
- 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();
- 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.
- // then strip whitespace.
- while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n')
- start--;
- while (start < (expressionStart - 1) && isStrWhiteSpace(data[start]))
- start++;
- while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n')
- stop++;
- while (stop > expressionStart && isStrWhiteSpace(data[stop]))
- stop--;
- errorText.append("near '...");
- errorText.append(codeBlock->source()->getRange(start, stop));
- errorText.append("...' [");
- errorText.append(value.toString(exec));
- errorText.append("] is ");
- }
- errorText.append(error);
- errorText.append(".");
- return errorText;
+ // No range information, so give a few characters of context
+ 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.
+ // then strip whitespace.
+ while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n')
+ start--;
+ while (start < (expressionStart - 1) && isStrWhiteSpace(data[start]))
+ start++;
+ while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n')
+ stop++;
+ while (stop > expressionStart && isStrWhiteSpace(data[stop]))
+ stop--;
+ return makeString("Result of expression near '...", codeBlock->source()->getRange(start, stop), "...' [", value.toString(exec), "] is ", error, ".");
}
JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
- UString message = "not a valid argument for '";
- message.append(op);
- message.append("'");
-
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
- UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, message);
+ UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, makeString("not a valid argument for '", op, "'"));
JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h
index 4c5bec1..e739d09 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -44,6 +44,7 @@ namespace JSC {
JSValue createInterruptedExecutionException(JSGlobalData*);
JSValue createStackOverflowError(ExecState*);
+ JSValue createTypeError(ExecState*, const char* message);
JSValue createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*);
JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState*, bool isNull);
JSObject* createInvalidParamError(ExecState*, const char* op, JSValue, unsigned bytecodeOffset, CodeBlock*);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp
index 7586746..bc18cc9 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.cpp
@@ -30,6 +30,7 @@
#include "CodeBlock.h"
#include "JIT.h"
#include "Parser.h"
+#include "StringBuilder.h"
#include "Vector.h"
namespace JSC {
@@ -265,14 +266,13 @@ PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifi
UString FunctionExecutable::paramString() const
{
FunctionParameters& parameters = *m_parameters;
- UString s("");
+ StringBuilder builder;
for (size_t pos = 0; pos < parameters.size(); ++pos) {
- if (!s.isEmpty())
- s += ", ";
- s += parameters[pos].ustring();
+ if (!builder.isEmpty())
+ builder.append(", ");
+ builder.append(parameters[pos].ustring());
}
-
- return s;
+ return builder.release();
}
};
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h
index 76764f9..d1d38de 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Executable.h
@@ -158,11 +158,6 @@ namespace JSC {
class EvalExecutable : public ScriptExecutable {
public:
- EvalExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec, source)
- , m_evalCodeBlock(0)
- {
- }
~EvalExecutable();
@@ -181,6 +176,11 @@ namespace JSC {
static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source) { return adoptRef(new EvalExecutable(exec, source)); }
private:
+ EvalExecutable(ExecState* exec, const SourceCode& source)
+ : ScriptExecutable(exec, source)
+ , m_evalCodeBlock(0)
+ {
+ }
EvalCodeBlock* m_evalCodeBlock;
#if ENABLE(JIT)
@@ -199,12 +199,11 @@ namespace JSC {
class ProgramExecutable : public ScriptExecutable {
public:
- ProgramExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec, source)
- , m_programCodeBlock(0)
+ static PassRefPtr<ProgramExecutable> create(ExecState* exec, const SourceCode& source)
{
+ return adoptRef(new ProgramExecutable(exec, source));
}
-
+
~ProgramExecutable();
ProgramCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
@@ -223,6 +222,11 @@ namespace JSC {
ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) { ASSERT_NOT_REACHED(); return 0; }
private:
+ ProgramExecutable(ExecState* exec, const SourceCode& source)
+ : ScriptExecutable(exec, source)
+ , m_programCodeBlock(0)
+ {
+ }
ProgramCodeBlock* m_programCodeBlock;
#if ENABLE(JIT)
@@ -282,7 +286,9 @@ namespace JSC {
size_t parameterCount() const { return m_parameters->size(); }
size_t variableCount() const { return m_numVariables; }
UString paramString() const;
+#ifdef QT_BUILD_SCRIPT_LIB
UString parameterName(int i) const { return (*m_parameters)[i].ustring(); }
+#endif
void recompile(ExecState*);
ExceptionInfo* reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp
index d5eb20f..9d55dd1 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -21,20 +21,21 @@
#include "config.h"
#include "FunctionConstructor.h"
+#include "Debugger.h"
#include "FunctionPrototype.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSString.h"
-#include "Parser.h"
-#include "Debugger.h"
#include "Lexer.h"
#include "Nodes.h"
+#include "Parser.h"
+#include "StringBuilder.h"
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor);
-FunctionConstructor::FunctionConstructor(ExecState* exec, PassRefPtr<Structure> structure, FunctionPrototype* functionPrototype)
+FunctionConstructor::FunctionConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, FunctionPrototype* functionPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, functionPrototype->classInfo()->className))
{
putDirectWithoutTransition(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
@@ -76,12 +77,19 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
if (args.isEmpty())
program = "(function() { \n})";
else if (args.size() == 1)
- program = "(function() { " + args.at(0).toString(exec) + "\n})";
+ program = makeString("(function() { ", args.at(0).toString(exec), "\n})");
else {
- program = "(function(" + args.at(0).toString(exec);
- for (size_t i = 1; i < args.size() - 1; i++)
- program += "," + args.at(i).toString(exec);
- program += ") { " + args.at(args.size() - 1).toString(exec) + "\n})";
+ StringBuilder builder;
+ builder.append("(function(");
+ builder.append(args.at(0).toString(exec));
+ for (size_t i = 1; i < args.size() - 1; i++) {
+ builder.append(",");
+ builder.append(args.at(i).toString(exec));
+ }
+ builder.append(") { ");
+ builder.append(args.at(args.size() - 1).toString(exec));
+ builder.append("\n})");
+ program = builder.release();
}
int errLine;
@@ -92,7 +100,7 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
- ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue());
+ ScopeChain scopeChain(globalObject, globalObject->globalData(), globalObject, exec->globalThisValue());
return new (exec) JSFunction(exec, function, scopeChain.node());
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h
index e8486dc..197f320 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class FunctionConstructor : public InternalFunction {
public:
- FunctionConstructor(ExecState*, PassRefPtr<Structure>, FunctionPrototype*);
+ FunctionConstructor(ExecState*, NonNullPassRefPtr<Structure>, FunctionPrototype*);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp
index 1df998d..00f307e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -37,7 +37,7 @@ static JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState*, JSObject*, JS
static JSValue JSC_HOST_CALL functionProtoFuncApply(ExecState*, JSObject*, JSValue, const ArgList&);
static JSValue JSC_HOST_CALL functionProtoFuncCall(ExecState*, JSObject*, JSValue, const ArgList&);
-FunctionPrototype::FunctionPrototype(ExecState* exec, PassRefPtr<Structure> structure)
+FunctionPrototype::FunctionPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure)
: InternalFunction(&exec->globalData(), structure, exec->propertyNames().nullIdentifier)
{
putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
@@ -76,7 +76,7 @@ static inline void insertSemicolonIfNeeded(UString& functionBody)
UChar ch = functionBody[i];
if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) {
if (ch != ';' && ch != '}')
- functionBody = functionBody.substr(0, i + 1) + ";" + functionBody.substr(i + 1, functionBody.size() - (i + 1));
+ functionBody = makeString(functionBody.substr(0, i + 1), ";", functionBody.substr(i + 1, functionBody.size() - (i + 1)));
return;
}
}
@@ -90,13 +90,13 @@ JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSVa
FunctionExecutable* executable = function->jsExecutable();
UString sourceString = executable->source().toString();
insertSemicolonIfNeeded(sourceString);
- return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + executable->paramString() + ") " + sourceString);
+ return jsString(exec, makeString("function ", function->name(exec), "(", executable->paramString(), ") ", sourceString));
}
}
if (thisValue.inherits(&InternalFunction::info)) {
InternalFunction* function = asInternalFunction(thisValue);
- return jsString(exec, "function " + function->name(&exec->globalData()) + "() {\n [native code]\n}");
+ return jsString(exec, makeString("function ", function->name(exec), "() {\n [native code]\n}"));
}
#ifdef QT_BUILD_SCRIPT_LIB //same error message as in the old engine, and in mozilla
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h
index 469191e..d1d6a1d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/FunctionPrototype.h
@@ -29,12 +29,12 @@ namespace JSC {
class FunctionPrototype : public InternalFunction {
public:
- FunctionPrototype(ExecState*, PassRefPtr<Structure>);
+ FunctionPrototype(ExecState*, NonNullPassRefPtr<Structure>);
void addFunctionProperties(ExecState*, Structure* prototypeFunctionStructure, NativeFunctionWrapper** callFunction, NativeFunctionWrapper** applyFunction);
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames));
+ return Structure::create(proto, TypeInfo(ObjectType, StructureFlags));
}
private:
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h
index 73dd854..68e9ea3 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GetterSetter.h
@@ -50,7 +50,7 @@ namespace JSC {
void setSetter(JSObject* setter) { m_setter = setter; }
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(GetterSetterType));
+ return Structure::create(prototype, TypeInfo(GetterSetterType, OverridesMarkChildren));
}
private:
virtual bool isGetterSetter() const;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp
index 3074f95..c26002b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.cpp
@@ -32,7 +32,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(GlobalEvalFunction);
-GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, PassRefPtr<Structure> structure, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
+GlobalEvalFunction::GlobalEvalFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int len, const Identifier& name, NativeFunction function, JSGlobalObject* cachedGlobalObject)
: PrototypeFunction(exec, structure, len, name, function)
, m_cachedGlobalObject(cachedGlobalObject)
{
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h
index c56b0dc..389b1c3 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/GlobalEvalFunction.h
@@ -32,14 +32,17 @@ namespace JSC {
class GlobalEvalFunction : public PrototypeFunction {
public:
- GlobalEvalFunction(ExecState*, PassRefPtr<Structure>, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
+ GlobalEvalFunction(ExecState*, NonNullPassRefPtr<Structure>, int len, const Identifier&, NativeFunction, JSGlobalObject* expectedThisObject);
JSGlobalObject* cachedGlobalObject() const { return m_cachedGlobalObject; }
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
+ protected:
+ static const unsigned StructureFlags = ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | PrototypeFunction::StructureFlags;
+
private:
virtual void markChildren(MarkStack&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.cpp
index 7db723b..747c4ac 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.cpp
@@ -28,6 +28,8 @@
#include <wtf/FastMalloc.h>
#include <wtf/HashSet.h>
+using WTF::ThreadSpecific;
+
namespace JSC {
typedef HashMap<const char*, RefPtr<UString::Rep>, PtrHash<const char*> > LiteralIdentifierTable;
@@ -38,13 +40,13 @@ public:
{
HashSet<UString::Rep*>::iterator end = m_table.end();
for (HashSet<UString::Rep*>::iterator iter = m_table.begin(); iter != end; ++iter)
- (*iter)->setIdentifierTable(0);
+ (*iter)->setIsIdentifier(false);
}
std::pair<HashSet<UString::Rep*>::iterator, bool> add(UString::Rep* value)
{
std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add(value);
- (*result.first)->setIdentifierTable(this);
+ (*result.first)->setIsIdentifier(true);
return result;
}
@@ -52,7 +54,7 @@ public:
std::pair<HashSet<UString::Rep*>::iterator, bool> add(U value)
{
std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add<U, V>(value);
- (*result.first)->setIdentifierTable(this);
+ (*result.first)->setIsIdentifier(true);
return result;
}
@@ -77,7 +79,7 @@ void deleteIdentifierTable(IdentifierTable* table)
bool Identifier::equal(const UString::Rep* r, const char* s)
{
- int length = r->len;
+ int length = r->size();
const UChar* d = r->data();
for (int i = 0; i != length; ++i)
if (d[i] != (unsigned char)s[i])
@@ -87,7 +89,7 @@ bool Identifier::equal(const UString::Rep* r, const char* s)
bool Identifier::equal(const UString::Rep* r, const UChar* s, int length)
{
- if (r->len != length)
+ if (r->size() != length)
return false;
const UChar* d = r->data();
for (int i = 0; i != length; ++i)
@@ -110,13 +112,11 @@ struct CStringTranslator {
static void translate(UString::Rep*& location, const char* c, unsigned hash)
{
size_t length = strlen(c);
- UChar* d = static_cast<UChar*>(fastMalloc(sizeof(UChar) * length));
+ UChar* d;
+ UString::Rep* r = UString::Rep::createUninitialized(length, d).releaseRef();
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
-
- UString::Rep* r = UString::Rep::create(d, static_cast<int>(length)).releaseRef();
- r->_hash = hash;
-
+ r->setHash(hash);
location = r;
}
};
@@ -175,13 +175,11 @@ struct UCharBufferTranslator {
static void translate(UString::Rep*& location, const UCharBuffer& buf, unsigned hash)
{
- UChar* d = static_cast<UChar*>(fastMalloc(sizeof(UChar) * buf.length));
+ UChar* d;
+ UString::Rep* r = UString::Rep::createUninitialized(buf.length, d).releaseRef();
for (unsigned i = 0; i != buf.length; i++)
d[i] = buf.s[i];
-
- UString::Rep* r = UString::Rep::create(d, buf.length).releaseRef();
- r->_hash = hash;
-
+ r->setHash(hash);
location = r;
}
};
@@ -212,19 +210,19 @@ PassRefPtr<UString::Rep> Identifier::add(ExecState* exec, const UChar* s, int le
PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UString::Rep* r)
{
- ASSERT(!r->identifierTable());
- if (r->len == 1) {
+ ASSERT(!r->isIdentifier());
+ if (r->size() == 1) {
UChar c = r->data()[0];
if (c <= 0xFF)
r = globalData->smallStrings.singleCharacterStringRep(c);
- if (r->identifierTable()) {
+ if (r->isIdentifier()) {
#ifndef NDEBUG
checkSameIdentifierTable(globalData, r);
#endif
return r;
}
}
- if (!r->len) {
+ if (!r->size()) {
UString::Rep::empty().hash();
return &UString::Rep::empty();
}
@@ -238,19 +236,19 @@ PassRefPtr<UString::Rep> Identifier::addSlowCase(ExecState* exec, UString::Rep*
void Identifier::remove(UString::Rep* r)
{
- r->identifierTable()->remove(r);
+ currentIdentifierTable()->remove(r);
}
#ifndef NDEBUG
-void Identifier::checkSameIdentifierTable(ExecState* exec, UString::Rep* rep)
+void Identifier::checkSameIdentifierTable(ExecState* exec, UString::Rep*)
{
- ASSERT(rep->identifierTable() == exec->globalData().identifierTable);
+ ASSERT_UNUSED(exec, exec->globalData().identifierTable == currentIdentifierTable());
}
-void Identifier::checkSameIdentifierTable(JSGlobalData* globalData, UString::Rep* rep)
+void Identifier::checkSameIdentifierTable(JSGlobalData* globalData, UString::Rep*)
{
- ASSERT(rep->identifierTable() == globalData->identifierTable);
+ ASSERT_UNUSED(globalData, globalData->identifierTable == currentIdentifierTable());
}
#else
@@ -265,4 +263,30 @@ void Identifier::checkSameIdentifierTable(JSGlobalData*, UString::Rep*)
#endif
+ThreadSpecific<ThreadIdentifierTableData>* g_identifierTableSpecific = 0;
+
+#if ENABLE(JSC_MULTIPLE_THREADS)
+
+pthread_once_t createIdentifierTableSpecificOnce = PTHREAD_ONCE_INIT;
+static void createIdentifierTableSpecificCallback()
+{
+ ASSERT(!g_identifierTableSpecific);
+ g_identifierTableSpecific = new ThreadSpecific<ThreadIdentifierTableData>();
+}
+void createIdentifierTableSpecific()
+{
+ pthread_once(&createIdentifierTableSpecificOnce, createIdentifierTableSpecificCallback);
+ ASSERT(g_identifierTableSpecific);
+}
+
+#else
+
+void createIdentifierTableSpecific()
+{
+ ASSERT(!g_identifierTableSpecific);
+ g_identifierTableSpecific = new ThreadSpecific<ThreadIdentifierTableData>();
+}
+
+#endif
+
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h
index 2249179..1d1bd18 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Identifier.h
@@ -22,6 +22,7 @@
#define Identifier_h
#include "JSGlobalData.h"
+#include "ThreadSpecific.h"
#include "UString.h"
namespace JSC {
@@ -92,7 +93,7 @@ namespace JSC {
static PassRefPtr<UString::Rep> add(ExecState* exec, UString::Rep* r)
{
- if (r->identifierTable()) {
+ if (r->isIdentifier()) {
#ifndef NDEBUG
checkSameIdentifierTable(exec, r);
#endif
@@ -102,7 +103,7 @@ namespace JSC {
}
static PassRefPtr<UString::Rep> add(JSGlobalData* globalData, UString::Rep* r)
{
- if (r->identifierTable()) {
+ if (r->isIdentifier()) {
#ifndef NDEBUG
checkSameIdentifierTable(globalData, r);
#endif
@@ -141,6 +142,67 @@ namespace JSC {
IdentifierTable* createIdentifierTable();
void deleteIdentifierTable(IdentifierTable*);
+ struct ThreadIdentifierTableData {
+ ThreadIdentifierTableData()
+ : defaultIdentifierTable(0)
+ , currentIdentifierTable(0)
+ {
+ }
+
+ IdentifierTable* defaultIdentifierTable;
+ IdentifierTable* currentIdentifierTable;
+ };
+
+ extern WTF::ThreadSpecific<ThreadIdentifierTableData>* g_identifierTableSpecific;
+ void createIdentifierTableSpecific();
+
+ inline IdentifierTable* defaultIdentifierTable()
+ {
+ if (!g_identifierTableSpecific)
+ createIdentifierTableSpecific();
+ ThreadIdentifierTableData& data = **g_identifierTableSpecific;
+
+ return data.defaultIdentifierTable;
+ }
+
+ inline void setDefaultIdentifierTable(IdentifierTable* identifierTable)
+ {
+ if (!g_identifierTableSpecific)
+ createIdentifierTableSpecific();
+ ThreadIdentifierTableData& data = **g_identifierTableSpecific;
+
+ data.defaultIdentifierTable = identifierTable;
+ }
+
+ inline IdentifierTable* currentIdentifierTable()
+ {
+ if (!g_identifierTableSpecific)
+ createIdentifierTableSpecific();
+ ThreadIdentifierTableData& data = **g_identifierTableSpecific;
+
+ return data.currentIdentifierTable;
+ }
+
+ inline IdentifierTable* setCurrentIdentifierTable(IdentifierTable* identifierTable)
+ {
+ if (!g_identifierTableSpecific)
+ createIdentifierTableSpecific();
+ ThreadIdentifierTableData& data = **g_identifierTableSpecific;
+
+ IdentifierTable* oldIdentifierTable = data.currentIdentifierTable;
+ data.currentIdentifierTable = identifierTable;
+ return oldIdentifierTable;
+ }
+
+ inline void resetCurrentIdentifierTable()
+ {
+ if (!g_identifierTableSpecific)
+ createIdentifierTableSpecific();
+ ThreadIdentifierTableData& data = **g_identifierTableSpecific;
+
+ data.currentIdentifierTable = data.defaultIdentifierTable;
+ }
+
} // namespace JSC
#endif // Identifier_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp
index fea89f8..2605a9a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -41,7 +41,7 @@ using namespace WTF;
namespace JSC {
-#if PLATFORM(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS)
+#if OS(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS)
static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT;
#endif
@@ -49,15 +49,16 @@ static void initializeThreadingOnce()
{
WTF::initializeThreading();
initializeUString();
+ JSGlobalData::storeVPtrs();
#if ENABLE(JSC_MULTIPLE_THREADS)
s_dtoaP5Mutex = new Mutex;
- WTF::initializeDates();
+ initializeDates();
#endif
}
void initializeThreading()
{
-#if PLATFORM(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS)
+#if OS(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS)
pthread_once(&initializeThreadingKeyOnce, initializeThreadingOnce);
#else
static bool initializedThreading = false;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.cpp
index b5c9571..c48d628 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.cpp
@@ -37,35 +37,35 @@ const ClassInfo* InternalFunction::classInfo() const
return &info;
}
-InternalFunction::InternalFunction(JSGlobalData* globalData, PassRefPtr<Structure> structure, const Identifier& name)
+InternalFunction::InternalFunction(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure, const Identifier& name)
: JSObject(structure)
{
putDirect(globalData->propertyNames->name, jsString(globalData, name.ustring()), DontDelete | ReadOnly | DontEnum);
}
-const UString& InternalFunction::name(JSGlobalData* globalData)
+const UString& InternalFunction::name(ExecState* exec)
{
- return asString(getDirect(globalData->propertyNames->name))->value();
+ return asString(getDirect(exec->globalData().propertyNames->name))->value(exec);
}
-const UString InternalFunction::displayName(JSGlobalData* globalData)
+const UString InternalFunction::displayName(ExecState* exec)
{
- JSValue displayName = getDirect(globalData->propertyNames->displayName);
+ JSValue displayName = getDirect(exec->globalData().propertyNames->displayName);
- if (displayName && isJSString(globalData, displayName))
- return asString(displayName)->value();
+ if (displayName && isJSString(&exec->globalData(), displayName))
+ return asString(displayName)->value(exec);
return UString::null();
}
-const UString InternalFunction::calculatedDisplayName(JSGlobalData* globalData)
+const UString InternalFunction::calculatedDisplayName(ExecState* exec)
{
- const UString explicitName = displayName(globalData);
+ const UString explicitName = displayName(exec);
if (!explicitName.isEmpty())
return explicitName;
- return name(globalData);
+ return name(exec);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h
index 37077f6..fa1e5aa 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/InternalFunction.h
@@ -36,18 +36,20 @@ namespace JSC {
virtual const ClassInfo* classInfo() const;
static JS_EXPORTDATA const ClassInfo info;
- const UString& name(JSGlobalData*);
- const UString displayName(JSGlobalData*);
- const UString calculatedDisplayName(JSGlobalData*);
+ const UString& name(ExecState*);
+ const UString displayName(ExecState*);
+ const UString calculatedDisplayName(ExecState*);
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot | HasDefaultMark));
+ return Structure::create(proto, TypeInfo(ObjectType, StructureFlags));
}
protected:
- InternalFunction(PassRefPtr<Structure> structure) : JSObject(structure) { }
- InternalFunction(JSGlobalData*, PassRefPtr<Structure>, const Identifier&);
+ static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
+
+ InternalFunction(NonNullPassRefPtr<Structure> structure) : JSObject(structure) { }
+ InternalFunction(JSGlobalData*, NonNullPassRefPtr<Structure>, const Identifier&);
private:
virtual CallType getCallData(CallData&) = 0;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.h
index 88a8493..aca550e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSAPIValueWrapper.h
@@ -39,7 +39,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(CompoundType));
+ return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames));
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp
index d989a89..22fdaaf 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.cpp
@@ -39,7 +39,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSActivation);
const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 };
-JSActivation::JSActivation(CallFrame* callFrame, PassRefPtr<FunctionExecutable> functionExecutable)
+JSActivation::JSActivation(CallFrame* callFrame, NonNullPassRefPtr<FunctionExecutable> functionExecutable)
: Base(callFrame->globalData().activationStructure, new JSActivationData(functionExecutable, callFrame->registers()))
{
}
@@ -121,12 +121,12 @@ void JSActivation::putWithAttributes(ExecState* exec, const Identifier& property
JSObject::putWithAttributes(exec, propertyName, value, attributes, true, slot);
}
-bool JSActivation::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+bool JSActivation::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
if (propertyName == exec->propertyNames().arguments)
return false;
- return Base::deleteProperty(exec, propertyName, checkDontDelete);
+ return Base::deleteProperty(exec, propertyName);
}
JSObject* JSActivation::toThisObject(ExecState* exec) const
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h
index 90815a1..ee98191 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSActivation.h
@@ -43,7 +43,7 @@ namespace JSC {
class JSActivation : public JSVariableObject {
typedef JSVariableObject Base;
public:
- JSActivation(CallFrame*, PassRefPtr<FunctionExecutable>);
+ JSActivation(CallFrame*, NonNullPassRefPtr<FunctionExecutable>);
virtual ~JSActivation();
virtual void markChildren(MarkStack&);
@@ -57,7 +57,7 @@ namespace JSC {
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
- virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual JSObject* toThisObject(ExecState*) const;
@@ -66,11 +66,14 @@ namespace JSC {
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); }
+
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
private:
struct JSActivationData : public JSVariableObjectData {
- JSActivationData(PassRefPtr<FunctionExecutable> _functionExecutable, Register* registers)
+ JSActivationData(NonNullPassRefPtr<FunctionExecutable> _functionExecutable, Register* registers)
: JSVariableObjectData(_functionExecutable->generatedBytecode().symbolTable(), registers)
, functionExecutable(_functionExecutable)
{
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp
index 9e0ab59..2be7371 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.cpp
@@ -130,7 +130,7 @@ inline void JSArray::checkConsistency(ConsistencyCheckType)
#endif
-JSArray::JSArray(PassRefPtr<Structure> structure)
+JSArray::JSArray(NonNullPassRefPtr<Structure> structure)
: JSObject(structure)
{
unsigned initialCapacity = 0;
@@ -141,7 +141,7 @@ JSArray::JSArray(PassRefPtr<Structure> structure)
checkConsistency();
}
-JSArray::JSArray(PassRefPtr<Structure> structure, unsigned initialLength)
+JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength)
: JSObject(structure)
{
unsigned initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
@@ -152,6 +152,7 @@ JSArray::JSArray(PassRefPtr<Structure> structure, unsigned initialLength)
m_storage->m_numValuesInVector = 0;
m_storage->m_sparseValueMap = 0;
m_storage->lazyCreationData = 0;
+ m_storage->reportedMapCapacity = 0;
JSValue* vector = m_storage->m_vector;
for (size_t i = 0; i < initialCapacity; ++i)
@@ -162,7 +163,7 @@ JSArray::JSArray(PassRefPtr<Structure> structure, unsigned initialLength)
Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue));
}
-JSArray::JSArray(PassRefPtr<Structure> structure, const ArgList& list)
+JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list)
: JSObject(structure)
{
unsigned initialCapacity = list.size();
@@ -172,6 +173,8 @@ JSArray::JSArray(PassRefPtr<Structure> structure, const ArgList& list)
m_vectorLength = initialCapacity;
m_storage->m_numValuesInVector = initialCapacity;
m_storage->m_sparseValueMap = 0;
+ m_storage->lazyCreationData = 0;
+ m_storage->reportedMapCapacity = 0;
size_t i = 0;
ArgList::const_iterator end = list.end();
@@ -185,6 +188,7 @@ JSArray::JSArray(PassRefPtr<Structure> structure, const ArgList& list)
JSArray::~JSArray()
{
+ ASSERT(vptr() == JSGlobalData::jsArrayVPtr);
checkConsistency(DestructorConsistencyCheck);
delete m_storage->m_sparseValueMap;
@@ -328,13 +332,24 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
}
// We miss some cases where we could compact the storage, such as a large array that is being filled from the end
- // (which will only be compacted as we reach indices that are less than cutoff) - but this makes the check much faster.
+ // (which will only be compacted as we reach indices that are less than MIN_SPARSE_ARRAY_INDEX) - but this makes the check much faster.
if ((i > MAX_STORAGE_VECTOR_INDEX) || !isDenseEnoughForVector(i + 1, storage->m_numValuesInVector + 1)) {
if (!map) {
map = new SparseArrayValueMap;
storage->m_sparseValueMap = map;
}
- map->set(i, value);
+
+ pair<SparseArrayValueMap::iterator, bool> result = map->add(i, value);
+ if (!result.second) { // pre-existing entry
+ result.first->second = value;
+ return;
+ }
+
+ size_t capacity = map->capacity();
+ if (capacity != storage->reportedMapCapacity) {
+ Heap::heap(this)->reportExtraMemoryCost((capacity - storage->reportedMapCapacity) * (sizeof(unsigned) + sizeof(JSValue)));
+ storage->reportedMapCapacity = capacity;
+ }
return;
}
}
@@ -380,8 +395,6 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
unsigned vectorLength = 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] = JSValue();
@@ -402,22 +415,24 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
m_storage = storage;
checkConsistency();
+
+ Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
}
-bool JSArray::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+bool JSArray::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
bool isArrayIndex;
unsigned i = propertyName.toArrayIndex(&isArrayIndex);
if (isArrayIndex)
- return deleteProperty(exec, i, checkDontDelete);
+ return deleteProperty(exec, i);
if (propertyName == exec->propertyNames().length)
return false;
- return JSObject::deleteProperty(exec, propertyName, checkDontDelete);
+ return JSObject::deleteProperty(exec, propertyName);
}
-bool JSArray::deleteProperty(ExecState* exec, unsigned i, bool checkDontDelete)
+bool JSArray::deleteProperty(ExecState* exec, unsigned i)
{
checkConsistency();
@@ -449,12 +464,12 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i, bool checkDontDelete)
checkConsistency();
if (i > MAX_ARRAY_INDEX)
- return deleteProperty(exec, Identifier::from(exec, i), checkDontDelete);
+ return deleteProperty(exec, Identifier::from(exec, i));
return false;
}
-void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable)
+void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
// FIXME: Filling PropertyNameArray with an identifier for every integer
// is incredibly inefficient for large arrays. We need a different approach,
@@ -474,7 +489,10 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa
propertyNames.add(Identifier::from(exec, it->first));
}
- JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
+ if (mode == IncludeDontEnumProperties)
+ propertyNames.add(exec->propertyNames().length);
+
+ JSObject::getOwnPropertyNames(exec, propertyNames, mode);
}
bool JSArray::increaseVectorLength(unsigned newLength)
@@ -492,13 +510,15 @@ bool JSArray::increaseVectorLength(unsigned newLength)
if (!tryFastRealloc(storage, storageSize(newVectorLength)).getValue(storage))
return false;
- Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
m_vectorLength = newVectorLength;
for (unsigned i = vectorLength; i < newVectorLength; ++i)
storage->m_vector[i] = JSValue();
m_storage = storage;
+
+ Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
+
return true;
}
@@ -785,7 +805,7 @@ struct AVLTreeAbstractorForArrayCompare {
m_cachedCall->setThis(m_globalThisValue);
m_cachedCall->setArgument(0, va);
m_cachedCall->setArgument(1, vb);
- compareResult = m_cachedCall->call().toNumber(m_cachedCall->newCallFrame());
+ compareResult = m_cachedCall->call().toNumber(m_cachedCall->newCallFrame(m_exec));
} else {
MarkedArgumentBuffer arguments;
arguments.append(va);
@@ -1051,26 +1071,4 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
#endif
-JSArray* constructEmptyArray(ExecState* exec)
-{
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure());
-}
-
-JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
-{
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
-}
-
-JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
-{
- MarkedArgumentBuffer values;
- values.append(singleItemValue);
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
-}
-
-JSArray* constructArray(ExecState* exec, const ArgList& values)
-{
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
-}
-
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h
index 2613991..64b2ff1 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSArray.h
@@ -32,6 +32,7 @@ namespace JSC {
unsigned m_numValuesInVector;
SparseArrayValueMap* m_sparseValueMap;
void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily.
+ size_t reportedMapCapacity;
JSValue m_vector[1];
};
@@ -40,9 +41,9 @@ namespace JSC {
friend class Walker;
public:
- explicit JSArray(PassRefPtr<Structure>);
- JSArray(PassRefPtr<Structure>, unsigned initialLength);
- JSArray(PassRefPtr<Structure>, const ArgList& initialValues);
+ explicit JSArray(NonNullPassRefPtr<Structure>);
+ JSArray(NonNullPassRefPtr<Structure>, unsigned initialLength);
+ JSArray(NonNullPassRefPtr<Structure>, const ArgList& initialValues);
virtual ~JSArray();
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
@@ -87,16 +88,17 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
inline void markChildrenDirect(MarkStack& markStack);
protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
- virtual bool deleteProperty(ExecState*, unsigned propertyName, bool checkDontDelete = true);
- virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false);
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+ virtual bool deleteProperty(ExecState*, unsigned propertyName);
+ virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual void markChildren(MarkStack&);
void* lazyCreationData();
@@ -121,11 +123,6 @@ namespace JSC {
JSArray* asArray(JSValue);
- JSArray* constructEmptyArray(ExecState*);
- JSArray* constructEmptyArray(ExecState*, unsigned initialLength);
- JSArray* constructArray(ExecState*, JSValue singleItemValue);
- JSArray* constructArray(ExecState*, const ArgList& values);
-
inline JSArray* asArray(JSCell* cell)
{
ASSERT(cell->inherits(&JSArray::info));
@@ -162,7 +159,7 @@ namespace JSC {
inline void MarkStack::markChildren(JSCell* cell)
{
ASSERT(Heap::isCellMarked(cell));
- if (cell->structure()->typeInfo().hasDefaultMark()) {
+ if (!cell->structure()->typeInfo().overridesMarkChildren()) {
#ifdef NDEBUG
asObject(cell)->markChildrenDirect(*this);
#else
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp
index 0907099..f8ab1e8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.cpp
@@ -35,17 +35,25 @@ namespace JSC {
const ClassInfo JSByteArray::s_defaultInfo = { "ByteArray", 0, 0, 0 };
-JSByteArray::JSByteArray(ExecState* exec, PassRefPtr<Structure> structure, ByteArray* storage, const JSC::ClassInfo* classInfo)
+JSByteArray::JSByteArray(ExecState* exec, NonNullPassRefPtr<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);
}
-
+
+#if !ASSERT_DISABLED
+JSByteArray::~JSByteArray()
+{
+ ASSERT(vptr() == JSGlobalData::jsByteArrayVPtr);
+}
+#endif
+
+
PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype)
{
- PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark));
+ PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
return result;
}
@@ -96,12 +104,12 @@ void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValue value)
setIndex(exec, propertyName, value);
}
-void JSByteArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable)
+void JSByteArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
unsigned length = m_storage->length();
for (unsigned i = 0; i < length; ++i)
propertyNames.add(Identifier::from(exec, i));
- JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
+ JSObject::getOwnPropertyNames(exec, propertyNames, mode);
}
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h
index 5ea0505..5b7adcf 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSByteArray.h
@@ -33,7 +33,7 @@
namespace JSC {
class JSByteArray : public JSObject {
- friend struct VPtrSet;
+ friend class JSGlobalData;
public:
bool canAccessIndex(unsigned i) { return i < m_storage->length(); }
JSValue getIndex(ExecState* exec, unsigned i)
@@ -73,7 +73,7 @@ namespace JSC {
setIndex(i, byteValue);
}
- JSByteArray(ExecState* exec, PassRefPtr<Structure>, WTF::ByteArray* storage, const JSC::ClassInfo* = &s_defaultInfo);
+ JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure>, WTF::ByteArray* storage, const JSC::ClassInfo* = &s_defaultInfo);
static PassRefPtr<Structure> createStructure(JSValue prototype);
virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
@@ -82,7 +82,7 @@ namespace JSC {
virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue);
- virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, bool includeNonEnumerable = false);
+ virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual const ClassInfo* classInfo() const { return m_classInfo; }
static const ClassInfo s_defaultInfo;
@@ -91,6 +91,13 @@ namespace JSC {
WTF::ByteArray* storage() const { return m_storage.get(); }
+#if !ASSERT_DISABLED
+ virtual ~JSByteArray();
+#endif
+
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags;
+
private:
enum VPtrStealingHackType { VPtrStealingHack };
JSByteArray(VPtrStealingHackType)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp
index 1cfe72d..869fbfc 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.cpp
@@ -59,10 +59,10 @@ static const union {
} doubles;
} NaNInf = { {
-#if PLATFORM(BIG_ENDIAN)
+#if CPU(BIG_ENDIAN)
{ 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 },
{ 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
-#elif PLATFORM(MIDDLE_ENDIAN)
+#elif CPU(MIDDLE_ENDIAN)
{ 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 },
{ 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }
#else
@@ -76,31 +76,22 @@ extern const double Inf = NaNInf.doubles.Inf_Double;
#endif // !(defined NAN && defined INFINITY)
-void* JSCell::operator new(size_t size, ExecState* exec)
-{
-#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
- return exec->heap()->inlineAllocate(size);
-#else
- return exec->heap()->allocate(size);
-#endif
-}
-
bool JSCell::getUInt32(uint32_t&) const
{
return false;
}
-bool JSCell::getString(UString&stringValue) const
+bool JSCell::getString(ExecState* exec, UString&stringValue) const
{
if (!isString())
return false;
- stringValue = static_cast<const JSString*>(this)->value();
+ stringValue = static_cast<const JSString*>(this)->value(exec);
return true;
}
-UString JSCell::getString() const
+UString JSCell::getString(ExecState* exec) const
{
- return isString() ? static_cast<const JSString*>(this)->value() : UString();
+ return isString() ? static_cast<const JSString*>(this)->value(exec) : UString();
}
JSObject* JSCell::getObject()
@@ -157,14 +148,14 @@ void JSCell::put(ExecState* exec, unsigned identifier, JSValue value)
toObject(exec)->put(exec, identifier, value);
}
-bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier, bool checkDontDelete)
+bool JSCell::deleteProperty(ExecState* exec, const Identifier& identifier)
{
- return toObject(exec)->deleteProperty(exec, identifier, checkDontDelete);
+ return toObject(exec)->deleteProperty(exec, identifier);
}
-bool JSCell::deleteProperty(ExecState* exec, unsigned identifier, bool checkDontDelete)
+bool JSCell::deleteProperty(ExecState* exec, unsigned identifier)
{
- return toObject(exec)->deleteProperty(exec, identifier, checkDontDelete);
+ return toObject(exec)->deleteProperty(exec, identifier);
}
JSObject* JSCell::toThisObject(ExecState* exec) const
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h
index d015b9c..36bfd66 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSCell.h
@@ -42,14 +42,19 @@ namespace JSC {
friend class JSString;
friend class JSValue;
friend class JSAPIValueWrapper;
- friend struct VPtrSet;
+ friend class JSZombie;
+ friend class JSGlobalData;
private:
explicit JSCell(Structure*);
- JSCell(); // Only used for initializing Collector blocks.
virtual ~JSCell();
public:
+ static PassRefPtr<Structure> createDummyStructure()
+ {
+ return Structure::create(jsNull(), TypeInfo(UnspecifiedType));
+ }
+
// Querying the type.
#if USE(JSVALUE32)
bool isNumber() const;
@@ -59,12 +64,13 @@ namespace JSC {
virtual bool isGetterSetter() const;
bool inherits(const ClassInfo*) const;
virtual bool isAPIValueWrapper() const { return false; }
+ virtual bool isPropertyNameIterator() const { return false; }
Structure* structure() const;
// Extracting the value.
- bool getString(UString&) const;
- UString getString() const; // null string if not a string
+ bool getString(ExecState* exec, UString&) const;
+ UString getString(ExecState* exec) const; // null string if not a string
JSObject* getObject(); // NULL if not an object
const JSObject* getObject() const; // NULL if not an object
@@ -89,19 +95,23 @@ namespace JSC {
void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; }
virtual void markChildren(MarkStack&);
+#if ENABLE(JSC_ZOMBIES)
+ virtual bool isZombie() const { return false; }
+#endif
// 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 bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
- virtual bool deleteProperty(ExecState*, unsigned propertyName, bool checkDontDelete = true);
+ 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();
void* vptr() { return *reinterpret_cast<void**>(this); }
+ void setVPtr(void* vptr) { *reinterpret_cast<void**>(this) = vptr; }
private:
// Base implementation; for non-object classes implements getPropertySlot.
@@ -112,24 +122,11 @@ namespace JSC {
Structure* m_structure;
};
- // FIXME: We should deprecate this and just use JSValue::asCell() instead.
- JSCell* asCell(JSValue);
-
- inline JSCell* asCell(JSValue value)
- {
- return value.asCell();
- }
-
inline JSCell::JSCell(Structure* structure)
: m_structure(structure)
{
}
- // Only used for initializing Collector blocks.
- inline JSCell::JSCell()
- {
- }
-
inline JSCell::~JSCell()
{
}
@@ -137,7 +134,7 @@ namespace JSC {
#if USE(JSVALUE32)
inline bool JSCell::isNumber() const
{
- return Heap::isNumber(const_cast<JSCell*>(this));
+ return m_structure->typeInfo().type() == NumberType;
}
#endif
@@ -162,11 +159,12 @@ namespace JSC {
inline void* JSCell::operator new(size_t size, JSGlobalData* globalData)
{
-#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
- return globalData->heap.inlineAllocate(size);
-#else
return globalData->heap.allocate(size);
-#endif
+ }
+
+ inline void* JSCell::operator new(size_t size, ExecState* exec)
+ {
+ return exec->heap()->allocate(size);
}
// --- JSValue inlines ----------------------------
@@ -186,14 +184,14 @@ namespace JSC {
return isCell() && asCell()->isObject();
}
- inline bool JSValue::getString(UString& s) const
+ inline bool JSValue::getString(ExecState* exec, UString& s) const
{
- return isCell() && asCell()->getString(s);
+ return isCell() && asCell()->getString(exec, s);
}
- inline UString JSValue::getString() const
+ inline UString JSValue::getString(ExecState* exec) const
{
- return isCell() ? asCell()->getString() : UString();
+ return isCell() ? asCell()->getString(exec) : UString();
}
inline JSObject* JSValue::getObject() const
@@ -342,11 +340,6 @@ namespace JSC {
append(value.asCell());
}
- inline void Structure::markAggregate(MarkStack& markStack)
- {
- markStack.append(m_prototype);
- }
-
inline Heap* Heap::heap(JSValue v)
{
if (!v.isCell())
@@ -358,7 +351,13 @@ namespace JSC {
{
return cellBlock(c)->heap;
}
-
+
+#if ENABLE(JSC_ZOMBIES)
+ inline bool JSValue::isZombie() const
+ {
+ return isCell() && asCell() && asCell()->isZombie();
+ }
+#endif
} // namespace JSC
#endif // JSCell_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp
index bf4e34d..d213b4a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.cpp
@@ -50,13 +50,13 @@ bool JSFunction::isHostFunctionNonInline() const
return isHostFunction();
}
-JSFunction::JSFunction(PassRefPtr<Structure> structure)
+JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure)
: Base(structure)
, m_executable(adoptRef(new VPtrHackExecutable()))
{
}
-JSFunction::JSFunction(ExecState* exec, PassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
+JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
: Base(&exec->globalData(), structure, name)
#if ENABLE(JIT)
, m_executable(adoptRef(new NativeExecutable(exec)))
@@ -72,7 +72,7 @@ JSFunction::JSFunction(ExecState* exec, PassRefPtr<Structure> structure, int len
#endif
}
-JSFunction::JSFunction(ExecState* exec, PassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode)
+JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode)
: Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), executable->name())
, m_executable(executable)
{
@@ -81,6 +81,8 @@ JSFunction::JSFunction(ExecState* exec, PassRefPtr<FunctionExecutable> executabl
JSFunction::~JSFunction()
{
+ ASSERT(vptr() == JSGlobalData::jsFunctionVPtr);
+
// 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).
@@ -206,6 +208,17 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
+void JSFunction::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+ if (!isHostFunction() && (mode == IncludeDontEnumProperties)) {
+ propertyNames.add(exec->propertyNames().arguments);
+ propertyNames.add(exec->propertyNames().callee);
+ propertyNames.add(exec->propertyNames().caller);
+ propertyNames.add(exec->propertyNames().length);
+ }
+ Base::getOwnPropertyNames(exec, propertyNames, mode);
+}
+
void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
if (isHostFunction()) {
@@ -217,13 +230,13 @@ void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue va
Base::put(exec, propertyName, value, slot);
}
-bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
if (isHostFunction())
- return Base::deleteProperty(exec, propertyName, checkDontDelete);
+ return Base::deleteProperty(exec, propertyName);
if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
return false;
- return Base::deleteProperty(exec, propertyName, checkDontDelete);
+ return Base::deleteProperty(exec, propertyName);
}
// ECMA 13.2.2 [[Construct]]
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h
index 416a58a..bdb79b8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSFunction.h
@@ -36,13 +36,13 @@ namespace JSC {
class JSFunction : public InternalFunction {
friend class JIT;
- friend struct VPtrSet;
+ friend class JSGlobalData;
typedef InternalFunction Base;
public:
- JSFunction(ExecState*, PassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
- JSFunction(ExecState*, PassRefPtr<FunctionExecutable>, ScopeChainNode*);
+ JSFunction(ExecState*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
+ JSFunction(ExecState*, NonNullPassRefPtr<FunctionExecutable>, ScopeChainNode*);
virtual ~JSFunction();
JSObject* construct(ExecState*, const ArgList&);
@@ -61,26 +61,30 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
NativeFunction nativeFunction()
{
- return *reinterpret_cast<NativeFunction*>(m_data);
+ return *WTF::bitwise_cast<NativeFunction*>(m_data);
}
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
+ protected:
+ const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | InternalFunction::StructureFlags;
+
private:
- JSFunction(PassRefPtr<Structure>);
+ JSFunction(NonNullPassRefPtr<Structure>);
bool isHostFunctionNonInline() const;
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
+ virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
- virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual void markChildren(MarkStack&);
@@ -94,7 +98,7 @@ namespace JSC {
ScopeChain& scopeChain()
{
ASSERT(!isHostFunctionNonInline());
- return *reinterpret_cast<ScopeChain*>(m_data);
+ return *WTF::bitwise_cast<ScopeChain*>(m_data);
}
void clearScopeChain()
{
@@ -109,11 +113,11 @@ namespace JSC {
void setScopeChain(const ScopeChain& sc)
{
ASSERT(!isHostFunctionNonInline());
- *reinterpret_cast<ScopeChain*>(m_data) = sc;
+ *WTF::bitwise_cast<ScopeChain*>(m_data) = sc;
}
void setNativeFunction(NativeFunction func)
{
- *reinterpret_cast<NativeFunction*>(m_data) = func;
+ *WTF::bitwise_cast<NativeFunction*>(m_data) = func;
}
unsigned char m_data[sizeof(void*)];
};
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp
index 4496d6c..34b5f82 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -45,10 +45,10 @@
#include "JSNotAnObject.h"
#include "JSPropertyNameIterator.h"
#include "JSStaticScopeObject.h"
-#include "Parser.h"
#include "Lexer.h"
#include "Lookup.h"
#include "Nodes.h"
+#include "Parser.h"
#if ENABLE(JSC_MULTIPLE_THREADS)
#include <wtf/Threading.h>
@@ -71,40 +71,38 @@ extern JSC_CONST_HASHTABLE HashTable regExpTable;
extern JSC_CONST_HASHTABLE HashTable regExpConstructorTable;
extern JSC_CONST_HASHTABLE HashTable stringTable;
-struct VPtrSet {
- VPtrSet();
-
- void* jsArrayVPtr;
- void* jsByteArrayVPtr;
- void* jsStringVPtr;
- void* jsFunctionVPtr;
-};
+void* JSGlobalData::jsArrayVPtr;
+void* JSGlobalData::jsByteArrayVPtr;
+void* JSGlobalData::jsStringVPtr;
+void* JSGlobalData::jsFunctionVPtr;
-VPtrSet::VPtrSet()
+void JSGlobalData::storeVPtrs()
{
- // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
- void* storage = fastMalloc(sizeof(CollectorBlock));
+ CollectorCell cell;
+ void* storage = &cell;
+ COMPILE_ASSERT(sizeof(JSArray) <= sizeof(CollectorCell), sizeof_JSArray_must_be_less_than_CollectorCell);
JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull()));
- jsArrayVPtr = jsArray->vptr();
+ JSGlobalData::jsArrayVPtr = jsArray->vptr();
jsArray->~JSCell();
+ COMPILE_ASSERT(sizeof(JSByteArray) <= sizeof(CollectorCell), sizeof_JSByteArray_must_be_less_than_CollectorCell);
JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
- jsByteArrayVPtr = jsByteArray->vptr();
+ JSGlobalData::jsByteArrayVPtr = jsByteArray->vptr();
jsByteArray->~JSCell();
+ COMPILE_ASSERT(sizeof(JSString) <= sizeof(CollectorCell), sizeof_JSString_must_be_less_than_CollectorCell);
JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
- jsStringVPtr = jsString->vptr();
+ JSGlobalData::jsStringVPtr = jsString->vptr();
jsString->~JSCell();
+ COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(CollectorCell), sizeof_JSFunction_must_be_less_than_CollectorCell);
JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
- jsFunctionVPtr = jsFunction->vptr();
+ JSGlobalData::jsFunctionVPtr = jsFunction->vptr();
jsFunction->~JSCell();
-
- fastFree(storage);
}
-JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet)
+JSGlobalData::JSGlobalData(bool isShared)
: isSharedInstance(isShared)
, clientData(0)
, arrayTable(fastNew<HashTable>(JSC::arrayTable))
@@ -124,13 +122,10 @@ JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet)
, propertyNameIteratorStructure(JSPropertyNameIterator::createStructure(jsNull()))
, getterSetterStructure(GetterSetter::createStructure(jsNull()))
, apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull()))
+ , dummyMarkableCellStructure(JSCell::createDummyStructure())
#if USE(JSVALUE32)
, numberStructure(JSNumberCell::createStructure(jsNull()))
#endif
- , jsArrayVPtr(vptrSet.jsArrayVPtr)
- , jsByteArrayVPtr(vptrSet.jsByteArrayVPtr)
- , jsStringVPtr(vptrSet.jsStringVPtr)
- , jsFunctionVPtr(vptrSet.jsFunctionVPtr)
, identifierTable(createIdentifierTable())
, propertyNames(new CommonIdentifiers(this))
, emptyList(new MarkedArgumentBuffer)
@@ -147,7 +142,9 @@ JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet)
, dynamicGlobalObject(0)
, functionCodeBlockBeingReparsed(0)
, firstStringifierToMark(0)
- , markStack(vptrSet.jsArrayVPtr)
+ , markStack(jsArrayVPtr)
+ , cachedUTCOffset(NaN)
+ , weakRandom(static_cast<int>(currentTime()))
#ifndef NDEBUG
, mainThreadOnly(false)
#endif
@@ -199,9 +196,17 @@ JSGlobalData::~JSGlobalData()
delete clientData;
}
-PassRefPtr<JSGlobalData> JSGlobalData::create(bool isShared)
+PassRefPtr<JSGlobalData> JSGlobalData::createNonDefault()
+{
+ return adoptRef(new JSGlobalData(false));
+}
+
+PassRefPtr<JSGlobalData> JSGlobalData::create()
{
- return adoptRef(new JSGlobalData(isShared, VPtrSet()));
+ JSGlobalData* globalData = new JSGlobalData(false);
+ setDefaultIdentifierTable(globalData->identifierTable);
+ setCurrentIdentifierTable(globalData->identifierTable);
+ return adoptRef(globalData);
}
PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
@@ -221,7 +226,7 @@ JSGlobalData& JSGlobalData::sharedInstance()
{
JSGlobalData*& instance = sharedInstanceInternal();
if (!instance) {
- instance = create(true).releaseRef();
+ instance = new JSGlobalData(true);
#if ENABLE(JSC_MULTIPLE_THREADS)
instance->makeUsableFromMultipleThreads();
#endif
@@ -253,4 +258,27 @@ JSGlobalData::ClientData::~ClientData()
{
}
+void JSGlobalData::resetDateCache()
+{
+ cachedUTCOffset = NaN;
+ dstOffsetCache.reset();
+ cachedDateString = UString();
+ dateInstanceCache.reset();
+}
+
+void JSGlobalData::startSampling()
+{
+ interpreter->startSampling();
+}
+
+void JSGlobalData::stopSampling()
+{
+ interpreter->stopSampling();
+}
+
+void JSGlobalData::dumpSampleData(ExecState* exec)
+{
+ interpreter->dumpSampleData(exec);
+}
+
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h
index c9887e8..49a6c4c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalData.h
@@ -30,6 +30,7 @@
#define JSGlobalData_h
#include "Collector.h"
+#include "DateInstanceCache.h"
#include "ExecutableAllocator.h"
#include "JITStubs.h"
#include "JSValue.h"
@@ -37,6 +38,7 @@
#include "NumericStrings.h"
#include "SmallStrings.h"
#include "TimeoutChecker.h"
+#include "WeakRandom.h"
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
@@ -60,7 +62,26 @@ namespace JSC {
struct HashTable;
struct Instruction;
- struct VPtrSet;
+
+ struct DSTOffsetCache {
+ DSTOffsetCache()
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ offset = 0.0;
+ start = 0.0;
+ end = -1.0;
+ increment = 0.0;
+ }
+
+ double offset;
+ double start;
+ double end;
+ double increment;
+ };
class JSGlobalData : public RefCounted<JSGlobalData> {
public:
@@ -74,8 +95,9 @@ namespace JSC {
static bool sharedInstanceExists();
static JSGlobalData& sharedInstance();
- static PassRefPtr<JSGlobalData> create(bool isShared = false);
+ static PassRefPtr<JSGlobalData> create();
static PassRefPtr<JSGlobalData> createLeaked();
+ static PassRefPtr<JSGlobalData> createNonDefault();
~JSGlobalData();
#if ENABLE(JSC_MULTIPLE_THREADS)
@@ -104,22 +126,25 @@ namespace JSC {
RefPtr<Structure> propertyNameIteratorStructure;
RefPtr<Structure> getterSetterStructure;
RefPtr<Structure> apiWrapperStructure;
+ RefPtr<Structure> dummyMarkableCellStructure;
#if USE(JSVALUE32)
RefPtr<Structure> numberStructure;
#endif
- void* jsArrayVPtr;
- void* jsByteArrayVPtr;
- void* jsStringVPtr;
- void* jsFunctionVPtr;
+ static void storeVPtrs();
+ static JS_EXPORTDATA void* jsArrayVPtr;
+ static JS_EXPORTDATA void* jsByteArrayVPtr;
+ static JS_EXPORTDATA void* jsStringVPtr;
+ static JS_EXPORTDATA void* jsFunctionVPtr;
IdentifierTable* identifierTable;
CommonIdentifiers* propertyNames;
const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
SmallStrings smallStrings;
NumericStrings numericStrings;
-
+ DateInstanceCache dateInstanceCache;
+
#if ENABLE(ASSEMBLER)
ExecutableAllocator executableAllocator;
#endif
@@ -154,16 +179,29 @@ namespace JSC {
MarkStack markStack;
+ double cachedUTCOffset;
+ DSTOffsetCache dstOffsetCache;
+
+ UString cachedDateString;
+ double cachedDateStringValue;
+
+ WeakRandom weakRandom;
+
#ifndef NDEBUG
bool mainThreadOnly;
#endif
+ void resetDateCache();
+
+ void startSampling();
+ void stopSampling();
+ void dumpSampleData(ExecState* exec);
private:
- JSGlobalData(bool isShared, const VPtrSet&);
+ JSGlobalData(bool isShared);
static JSGlobalData*& sharedInstanceInternal();
void createNativeThunk();
};
-
+
} // namespace JSC
#endif // JSGlobalData_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp
index 60eb1b4..a2e9928 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -89,7 +89,7 @@ static inline void markIfNeeded(MarkStack& markStack, JSValue v)
static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s)
{
if (s)
- s->markAggregate(markStack);
+ markIfNeeded(markStack, s->storedPrototype());
}
JSGlobalObject::~JSGlobalObject()
@@ -121,15 +121,17 @@ JSGlobalObject::~JSGlobalObject()
registerFile.setGlobalObject(0);
registerFile.setNumGlobals(0);
}
- delete d();
+ d()->destructor(d());
}
void JSGlobalObject::init(JSObject* thisValue)
{
ASSERT(JSLock::currentThreadIsHoldingLock());
+ structure()->disableSpecificFunctionTracking();
+
d()->globalData = Heap::heap(this)->globalData();
- d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), thisValue);
+ d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), this, thisValue);
JSGlobalObject::globalExec()->init(0, 0, d()->globalScopeChain.node(), CallFrame::noCaller(), 0, 0, 0);
@@ -396,6 +398,21 @@ void JSGlobalObject::markChildren(MarkStack& markStack)
markIfNeeded(markStack, d()->methodCallDummy);
markIfNeeded(markStack, d()->errorStructure);
+ markIfNeeded(markStack, d()->argumentsStructure);
+ markIfNeeded(markStack, d()->arrayStructure);
+ markIfNeeded(markStack, d()->booleanObjectStructure);
+ markIfNeeded(markStack, d()->callbackConstructorStructure);
+ markIfNeeded(markStack, d()->callbackFunctionStructure);
+ markIfNeeded(markStack, d()->callbackObjectStructure);
+ markIfNeeded(markStack, d()->dateStructure);
+ markIfNeeded(markStack, d()->emptyObjectStructure);
+ markIfNeeded(markStack, d()->errorStructure);
+ markIfNeeded(markStack, d()->functionStructure);
+ markIfNeeded(markStack, d()->numberObjectStructure);
+ markIfNeeded(markStack, d()->prototypeFunctionStructure);
+ markIfNeeded(markStack, d()->regExpMatchesArrayStructure);
+ markIfNeeded(markStack, d()->regExpStructure);
+ markIfNeeded(markStack, d()->stringObjectStructure);
// No need to mark the other structures, because their prototypes are all
// guaranteed to be referenced elsewhere.
@@ -450,11 +467,12 @@ void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile)
void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData)
{
-#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
- return globalData->heap.inlineAllocate(size);
-#else
return globalData->heap.allocate(size);
-#endif
+}
+
+void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData)
+{
+ delete static_cast<JSGlobalObjectData*>(jsGlobalObjectData);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h
index 7459c2e..340e04d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObject.h
@@ -22,6 +22,7 @@
#ifndef JSGlobalObject_h
#define JSGlobalObject_h
+#include "JSArray.h"
#include "JSGlobalData.h"
#include "JSVariableObject.h"
#include "NativeFunctionWrapper.h"
@@ -52,14 +53,22 @@ namespace JSC {
struct HashTable;
typedef Vector<ExecState*, 16> ExecStateStack;
-
+
class JSGlobalObject : public JSVariableObject {
protected:
using JSVariableObject::JSVariableObjectData;
struct JSGlobalObjectData : public JSVariableObjectData {
- JSGlobalObjectData()
+ // We use an explicit destructor function pointer instead of a
+ // virtual destructor because we want to avoid adding a vtable
+ // pointer to this struct. Adding a vtable pointer would force the
+ // compiler to emit costly pointer fixup code when casting from
+ // JSVariableObjectData* to JSGlobalObjectData*.
+ typedef void (*Destructor)(void*);
+
+ JSGlobalObjectData(Destructor destructor)
: JSVariableObjectData(&symbolTable, 0)
+ , destructor(destructor)
, registerArraySize(0)
, globalScopeChain(NoScopeChain())
, regExpConstructor(0)
@@ -85,10 +94,8 @@ namespace JSC {
{
}
- virtual ~JSGlobalObjectData()
- {
- }
-
+ Destructor destructor;
+
size_t registerArraySize;
JSGlobalObject* next;
@@ -153,13 +160,13 @@ namespace JSC {
void* operator new(size_t, JSGlobalData*);
explicit JSGlobalObject()
- : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData)
+ : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData(destroyJSGlobalObjectData))
{
init(this);
}
protected:
- JSGlobalObject(PassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue)
+ JSGlobalObject(NonNullPassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue)
: JSVariableObject(structure, data)
{
init(thisValue);
@@ -229,10 +236,7 @@ namespace JSC {
unsigned profileGroup() const { return d()->profileGroup; }
Debugger* debugger() const { return d()->debugger; }
- void setDebugger(Debugger* debugger)
- {
- d()->debugger = debugger;
- }
+ void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
virtual bool supportsProfiling() const { return false; }
@@ -264,10 +268,13 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
protected:
+
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
+
struct GlobalPropertyInfo {
GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
: identifier(i)
@@ -283,6 +290,8 @@ namespace JSC {
void addStaticGlobals(GlobalPropertyInfo*, int count);
private:
+ static void destroyJSGlobalObjectData(void*);
+
// FIXME: Fold reset into init.
void init(JSObject* thisValue);
void reset(JSValue prototype);
@@ -347,14 +356,6 @@ namespace JSC {
return symbolTableGet(propertyName, slot, slotIsWriteable);
}
- inline JSGlobalObject* ScopeChainNode::globalObject() const
- {
- const ScopeChainNode* n = this;
- while (n->next)
- n = n->next;
- return asGlobalObject(n->object);
- }
-
inline JSValue Structure::prototypeForLookup(ExecState* exec) const
{
if (typeInfo().type() == ObjectType)
@@ -409,13 +410,46 @@ namespace JSC {
return globalData().dynamicGlobalObject;
}
+ inline JSObject* constructEmptyObject(ExecState* exec)
+ {
+ return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
+ }
+
+ inline JSArray* constructEmptyArray(ExecState* exec)
+ {
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure());
+ }
+
+ inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
+ {
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
+ }
+
+ inline JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
+ {
+ MarkedArgumentBuffer values;
+ values.append(singleItemValue);
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+ }
+
+ inline JSArray* constructArray(ExecState* exec, const ArgList& values)
+ {
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+ }
+
class DynamicGlobalObjectScope : public Noncopyable {
public:
DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject)
: m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
, m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
{
- m_dynamicGlobalObjectSlot = dynamicGlobalObject;
+ if (!m_dynamicGlobalObjectSlot) {
+ m_dynamicGlobalObjectSlot = dynamicGlobalObject;
+
+ // Reset the date cache between JS invocations to force the VM
+ // to observe time zone changes.
+ callFrame->globalData().resetDateCache();
+ }
}
~DynamicGlobalObjectScope()
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index 5ded370..0bc1274 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -27,14 +27,16 @@
#include "CallFrame.h"
#include "GlobalEvalFunction.h"
+#include "Interpreter.h"
#include "JSGlobalObject.h"
-#include "LiteralParser.h"
#include "JSString.h"
-#include "Interpreter.h"
-#include "Parser.h"
-#include "dtoa.h"
#include "Lexer.h"
+#include "LiteralParser.h"
#include "Nodes.h"
+#include "Parser.h"
+#include "StringBuilder.h"
+#include "StringExtras.h"
+#include "dtoa.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -55,24 +57,24 @@ static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEsc
if (!cstr.c_str())
return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
- UString result = "";
+ StringBuilder builder;
const char* p = cstr.c_str();
for (size_t k = 0; k < cstr.size(); k++, p++) {
char c = *p;
if (c && strchr(doNotEscape, c))
- result.append(c);
+ builder.append(c);
else {
char tmp[4];
- sprintf(tmp, "%%%02X", static_cast<unsigned char>(c));
- result += tmp;
+ snprintf(tmp, 4, "%%%02X", static_cast<unsigned char>(c));
+ builder.append((const char*)tmp);
}
}
- return jsString(exec, result);
+ return jsString(exec, builder.release());
}
static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
{
- UString result = "";
+ StringBuilder builder;
UString str = args.at(0).toString(exec);
int k = 0;
int len = str.size();
@@ -106,7 +108,7 @@ static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUne
charLen = 0;
else if (character >= 0x10000) {
// Convert to surrogate pair.
- result.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
+ builder.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF));
} else
u = static_cast<UChar>(character);
@@ -131,9 +133,9 @@ static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUne
}
}
k++;
- result.append(c);
+ builder.append(c);
}
- return jsString(exec, result);
+ return jsString(exec, builder.release());
}
bool isStrWhiteSpace(UChar c)
@@ -286,12 +288,12 @@ JSValue JSC_HOST_CALL globalFuncEval(ExecState* exec, JSObject* function, JSValu
if (JSValue parsedObject = preparser.tryLiteralParse())
return parsedObject;
- EvalExecutable eval(exec, makeSource(s));
- JSObject* error = eval.compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node());
+ RefPtr<EvalExecutable> eval = EvalExecutable::create(exec, makeSource(s));
+ JSObject* error = eval->compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node());
if (error)
return throwError(exec, error);
- return exec->interpreter()->execute(&eval, exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot());
+ return exec->interpreter()->execute(eval.get(), exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot());
}
JSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
@@ -376,7 +378,7 @@ JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, cons
"0123456789"
"*+-./@_";
- UString result = "";
+ StringBuilder builder;
UString s;
UString str = args.at(0).toString(exec);
const UChar* c = str.data();
@@ -393,15 +395,15 @@ JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, cons
sprintf(tmp, "%%%02X", u);
s = UString(tmp);
}
- result += s;
+ builder.append(s);
}
- return jsString(exec, result);
+ return jsString(exec, builder.release());
}
JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- UString result = "";
+ StringBuilder builder;
UString str = args.at(0).toString(exec);
int k = 0;
int len = str.size();
@@ -420,10 +422,10 @@ JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, co
k += 2;
}
k++;
- result.append(*c);
+ builder.append(*c);
}
- return jsString(exec, result);
+ return jsString(exec, builder.release());
}
#ifndef NDEBUG
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp
index 321762a..f4764e2 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.cpp
@@ -121,7 +121,7 @@ bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned)
return false;
}
-void JSNotAnObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray&, bool)
+void JSNotAnObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray&, EnumerationMode)
{
ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h
index 57347af..d5f430c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNotAnObject.h
@@ -62,10 +62,13 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
private:
+
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
+
// JSValue methods
virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
@@ -88,7 +91,7 @@ namespace JSC {
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
- virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false);
+ virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
JSNotAnObjectErrorStub* m_exception;
};
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h
index 6a48081..e9e2470 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSNumberCell.h
@@ -68,23 +68,15 @@ namespace JSC {
void* operator new(size_t size, ExecState* exec)
{
- #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
- return exec->heap()->inlineAllocateNumber(size);
- #else
return exec->heap()->allocateNumber(size);
- #endif
}
void* operator new(size_t size, JSGlobalData* globalData)
{
- #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
- return globalData->heap.inlineAllocateNumber(size);
- #else
return globalData->heap.allocateNumber(size);
- #endif
}
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion | HasDefaultMark)); }
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, OverridesGetOwnPropertySlot | NeedsThisConversion)); }
private:
JSNumberCell(JSGlobalData* globalData, double value)
@@ -117,6 +109,11 @@ namespace JSC {
return static_cast<JSNumberCell*>(v.asCell());
}
+ ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState* exec, double d)
+ {
+ *this = jsNumberCell(exec, d);
+ }
+
inline JSValue::JSValue(ExecState* exec, double d)
{
JSValue v = JSImmediate::from(d);
@@ -201,6 +198,11 @@ namespace JSC {
#endif // USE(JSVALUE32)
#if USE(JSVALUE64)
+ ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState*, double d)
+ {
+ *this = JSImmediate::fromNumberOutsideIntegerRange(d);
+ }
+
inline JSValue::JSValue(ExecState*, double d)
{
JSValue v = JSImmediate::from(d);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp
index 377c9d1..b089584 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.cpp
@@ -32,6 +32,7 @@
#include "JSArray.h"
#include "LiteralParser.h"
#include "PropertyNameArray.h"
+#include "StringBuilder.h"
#include <wtf/MathExtras.h>
namespace JSC {
@@ -70,8 +71,6 @@ public:
void markAggregate(MarkStack&);
private:
- typedef UString StringBuilder;
-
class Holder {
public:
Holder(JSObject*);
@@ -156,7 +155,7 @@ static inline UString gap(ExecState* exec, JSValue space)
}
// If the space value is a string, use it as the gap string, otherwise use no gap string.
- UString spaces = space.getString();
+ UString spaces = space.getString(exec);
if (spaces.size() > maxGapLength) {
spaces = spaces.substr(0, maxGapLength);
}
@@ -213,7 +212,7 @@ Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space)
break;
UString propertyName;
- if (name.getString(propertyName)) {
+ if (name.getString(exec, propertyName)) {
m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName));
continue;
}
@@ -269,7 +268,7 @@ JSValue Stringifier::stringify(JSValue value)
if (m_exec->hadException())
return jsNull();
- return jsString(m_exec, result);
+ return jsString(m_exec, result.release());
}
void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value)
@@ -389,7 +388,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder&
}
UString stringValue;
- if (value.getString(stringValue)) {
+ if (value.getString(m_exec, stringValue)) {
appendQuotedString(builder, stringValue);
return StringifySucceeded;
}
@@ -461,7 +460,7 @@ inline void Stringifier::indent()
// Use a single shared string, m_repeatedGap, so we don't keep allocating new ones as we indent and unindent.
int newSize = m_indent.size() + m_gap.size();
if (newSize > m_repeatedGap.size())
- m_repeatedGap.append(m_gap);
+ m_repeatedGap = makeString(m_repeatedGap, m_gap);
ASSERT(newSize <= m_repeatedGap.size());
m_indent = m_repeatedGap.substr(0, newSize);
}
@@ -504,7 +503,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui
m_propertyNames = stringifier.m_arrayReplacerPropertyNames.data();
else {
PropertyNameArray objectPropertyNames(exec);
- m_object->getPropertyNames(exec, objectPropertyNames);
+ m_object->getOwnPropertyNames(exec, objectPropertyNames);
m_propertyNames = objectPropertyNames.releaseData();
}
m_size = m_propertyNames->propertyNameVector().size();
@@ -588,7 +587,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui
// This only occurs when get an undefined value for an object property.
// In this case we don't want the separator and property name that we
// already appended, so roll back.
- builder = builder.substr(0, rollBackPoint);
+ builder.resize(rollBackPoint);
break;
}
@@ -750,7 +749,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
objectStack.append(object);
indexStack.append(0);
propertyStack.append(PropertyNameArray(m_exec));
- object->getPropertyNames(m_exec, propertyStack.last());
+ object->getOwnPropertyNames(m_exec, propertyStack.last());
// fallthrough
}
objectStartVisitMember:
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h
index 0705a69..ec3fa40 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSONObject.h
@@ -34,18 +34,21 @@ namespace JSC {
class JSONObject : public JSObject {
public:
- JSONObject(PassRefPtr<Structure> structure)
+ JSONObject(NonNullPassRefPtr<Structure> structure)
: JSObject(structure)
{
}
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
static void markStringifiers(MarkStack&, Stringifier*);
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
+
private:
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp
index 01f74ac..0e3475f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.cpp
@@ -42,6 +42,25 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSObject);
+static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode)
+{
+ // Add properties from the static hashtables of properties
+ for (; classInfo; classInfo = classInfo->parentClass) {
+ const HashTable* table = classInfo->propHashTable(exec);
+ if (!table)
+ continue;
+ table->initializeIfNeeded(exec);
+ ASSERT(table->table);
+
+ int hashSizeMask = table->compactSize - 1;
+ const HashEntry* entry = table->table;
+ for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
+ if (entry->key() && (!(entry->attributes() & DontEnum) || (mode == IncludeDontEnumProperties)))
+ propertyNames.add(entry->key());
+ }
+ }
+}
+
void JSObject::markChildren(MarkStack& markStack)
{
#ifndef NDEBUG
@@ -187,12 +206,12 @@ bool JSObject::hasProperty(ExecState* exec, unsigned propertyName) const
}
// ECMA 8.6.2.5
-bool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+bool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
unsigned attributes;
JSCell* specificValue;
if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) {
- if ((attributes & DontDelete) && checkDontDelete)
+ if ((attributes & DontDelete))
return false;
removeDirect(propertyName);
return true;
@@ -200,7 +219,7 @@ bool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName, b
// Look in the static hashtable of properties
const HashEntry* entry = findPropertyHashEntry(exec, propertyName);
- if (entry && (entry->attributes() & DontDelete) && checkDontDelete)
+ if (entry && entry->attributes() & DontDelete)
return false; // this builtin property can't be deleted
// FIXME: Should the code here actually do some deletion?
@@ -213,9 +232,9 @@ bool JSObject::hasOwnProperty(ExecState* exec, const Identifier& propertyName) c
return const_cast<JSObject*>(this)->getOwnPropertySlot(exec, propertyName, slot);
}
-bool JSObject::deleteProperty(ExecState* exec, unsigned propertyName, bool checkDontDelete)
+bool JSObject::deleteProperty(ExecState* exec, unsigned propertyName)
{
- return deleteProperty(exec, Identifier::from(exec, propertyName), checkDontDelete);
+ return deleteProperty(exec, Identifier::from(exec, propertyName));
}
static ALWAYS_INLINE JSValue callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
@@ -395,26 +414,10 @@ bool JSObject::hasInstance(ExecState* exec, JSValue value, JSValue proto)
bool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyName) const
{
- unsigned attributes;
- if (!getPropertyAttributes(exec, propertyName, attributes))
+ PropertyDescriptor descriptor;
+ if (!const_cast<JSObject*>(this)->getOwnPropertyDescriptor(exec, propertyName, descriptor))
return false;
- return !(attributes & DontEnum);
-}
-
-bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
-{
- JSCell* specificValue;
- if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound)
- return true;
-
- // Look in the static hashtable of properties
- const HashEntry* entry = findPropertyHashEntry(exec, propertyName);
- if (entry) {
- attributes = entry->attributes();
- return true;
- }
-
- return false;
+ return descriptor.enumerable();
}
bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyName, JSCell*& specificValue) const
@@ -430,14 +433,31 @@ bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyNa
return false;
}
-void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
- m_structure->getEnumerablePropertyNames(exec, propertyNames, this);
+ getOwnPropertyNames(exec, propertyNames, mode);
+
+ if (prototype().isNull())
+ return;
+
+ JSObject* prototype = asObject(this->prototype());
+ while(1) {
+ if (prototype->structure()->typeInfo().overridesGetPropertyNames()) {
+ prototype->getPropertyNames(exec, propertyNames, mode);
+ break;
+ }
+ prototype->getOwnPropertyNames(exec, propertyNames, mode);
+ JSValue nextProto = prototype->prototype();
+ if (nextProto.isNull())
+ break;
+ prototype = asObject(nextProto);
+ }
}
-void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable)
+void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
- m_structure->getOwnPropertyNames(exec, propertyNames, this, includeNonEnumerable);
+ m_structure->getPropertyNames(propertyNames, mode);
+ getClassPropertyNames(exec, classInfo(), propertyNames, mode);
}
bool JSObject::toBoolean(ExecState*) const
@@ -494,12 +514,12 @@ void JSObject::removeDirect(const Identifier& propertyName)
void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr)
{
- putDirectFunction(Identifier(exec, function->name(&exec->globalData())), function, attr);
+ putDirectFunction(Identifier(exec, function->name(exec)), function, attr);
}
void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr)
{
- putDirectFunctionWithoutTransition(Identifier(exec, function->name(&exec->globalData())), function, attr);
+ putDirectFunctionWithoutTransition(Identifier(exec, function->name(exec)), function, attr);
}
NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue* location)
@@ -514,7 +534,7 @@ Structure* JSObject::createInheritorID()
{
#ifdef QT_BUILD_SCRIPT_LIB
// ### QtScript needs the hasOwnProperty() calls etc. for QScriptObject
- m_inheritorID = Structure::create(this, TypeInfo(ObjectType, ImplementsHasInstance));
+ m_inheritorID = Structure::create(this, TypeInfo(ObjectType, ImplementsHasInstance | JSC::OverridesHasInstance | JSC::OverridesGetOwnPropertySlot | JSC::OverridesMarkChildren | JSC::OverridesGetPropertyNames));
#else
m_inheritorID = JSObject::createStructure(this);
#endif
@@ -526,11 +546,6 @@ void JSObject::allocatePropertyStorage(size_t oldSize, size_t newSize)
allocatePropertyStorageInline(oldSize, newSize);
}
-JSObject* constructEmptyObject(ExecState* exec)
-{
- return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
-}
-
bool JSObject::getOwnPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
unsigned attributes = 0;
@@ -581,7 +596,7 @@ bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName
if (descriptor.isEmpty())
return true;
- if (current.equalTo(descriptor))
+ if (current.equalTo(exec, descriptor))
return true;
// Filter out invalid changes
@@ -627,7 +642,7 @@ bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName
return false;
}
if (!current.writable()) {
- if (descriptor.value() || !JSValue::strictEqual(current.value(), descriptor.value())) {
+ if (descriptor.value() || !JSValue::strictEqual(exec, current.value(), descriptor.value())) {
if (throwException)
throwError(exec, TypeError, "Attempting to change value of a readonly property.");
return false;
@@ -649,12 +664,12 @@ bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName
// Changing the accessor functions of an existing accessor property
ASSERT(descriptor.isAccessorDescriptor());
if (!current.configurable()) {
- if (descriptor.setterPresent() && !(current.setter() && JSValue::strictEqual(current.setter(), descriptor.setter()))) {
+ if (descriptor.setterPresent() && !(current.setter() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) {
if (throwException)
throwError(exec, TypeError, "Attempting to change the setter of an unconfigurable property.");
return false;
}
- if (descriptor.getterPresent() && !(current.getter() && JSValue::strictEqual(current.getter(), descriptor.getter()))) {
+ if (descriptor.getterPresent() && !(current.getter() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) {
if (throwException)
throwError(exec, TypeError, "Attempting to change the getter of an unconfigurable property.");
return false;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h
index 9eb4e3e..21dbfe9 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSObject.h
@@ -74,7 +74,7 @@ namespace JSC {
friend class JSCell;
public:
- explicit JSObject(PassRefPtr<Structure>);
+ explicit JSObject(NonNullPassRefPtr<Structure>);
virtual void markChildren(MarkStack&);
ALWAYS_INLINE void markChildrenDirect(MarkStack& markStack);
@@ -86,7 +86,7 @@ namespace JSC {
JSValue prototype() const;
void setPrototype(JSValue prototype);
- void setStructure(PassRefPtr<Structure>);
+ void setStructure(NonNullPassRefPtr<Structure>);
Structure* inheritorID();
virtual UString className() const;
@@ -115,15 +115,15 @@ namespace JSC {
bool hasProperty(ExecState*, unsigned propertyName) const;
bool hasOwnProperty(ExecState*, const Identifier& propertyName) const;
- virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
- virtual bool deleteProperty(ExecState*, unsigned propertyName, bool checkDontDelete = true);
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+ virtual bool deleteProperty(ExecState*, unsigned propertyName);
virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;
virtual bool hasInstance(ExecState*, JSValue, JSValue prototypeProperty);
- virtual void getPropertyNames(ExecState*, PropertyNameArray&);
- virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false);
+ virtual void getPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
+ virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
@@ -135,7 +135,6 @@ namespace JSC {
virtual JSObject* toThisObject(ExecState*) const;
virtual JSObject* unwrappedObject();
- virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const;
// This get function only looks at the property map.
@@ -197,7 +196,6 @@ namespace JSC {
virtual bool isActivationObject() const { return false; }
virtual bool isWatchdogException() const { return false; }
virtual bool isNotAnObjectErrorStub() const { return false; }
-
#ifdef QT_BUILD_SCRIPT_LIB
virtual bool compareToObject(ExecState*, JSObject *other) { return other == this; }
#endif
@@ -206,15 +204,22 @@ namespace JSC {
void allocatePropertyStorageInline(size_t oldSize, size_t newSize);
bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); }
- static const size_t inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3;
- static const size_t nonInlineBaseStorageCapacity = 16;
+ static const unsigned inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3;
+ static const unsigned nonInlineBaseStorageCapacity = 16;
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
+ }
+
+ void flattenDictionaryObject()
+ {
+ m_structure->flattenDictionaryStructure(this);
}
protected:
+ static const unsigned StructureFlags = 0;
+
void addAnonymousSlots(unsigned count);
void putAnonymousValue(unsigned index, JSValue value)
{
@@ -231,7 +236,7 @@ namespace JSC {
using JSCell::isGetterSetter;
using JSCell::toObject;
void getObject();
- void getString();
+ void getString(ExecState* exec);
void isObject();
void isString();
#if USE(JSVALUE32)
@@ -268,8 +273,6 @@ namespace JSC {
RefPtr<Structure> m_inheritorID;
};
-JSObject* constructEmptyObject(ExecState*);
-
inline JSObject* asObject(JSCell* cell)
{
ASSERT(cell->isObject());
@@ -281,10 +284,9 @@ inline JSObject* asObject(JSValue value)
return asObject(value.asCell());
}
-inline JSObject::JSObject(PassRefPtr<Structure> structure)
+inline JSObject::JSObject(NonNullPassRefPtr<Structure> structure)
: JSCell(structure.releaseRef()) // ~JSObject balances this ref()
{
- ASSERT(m_structure);
ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity);
ASSERT(m_structure->isEmpty());
ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
@@ -313,7 +315,7 @@ inline void JSObject::setPrototype(JSValue prototype)
setStructure(newStructure.release());
}
-inline void JSObject::setStructure(PassRefPtr<Structure> structure)
+inline void JSObject::setStructure(NonNullPassRefPtr<Structure> structure)
{
m_structure->deref();
m_structure = structure.releaseRef(); // ~JSObject balances this ref()
@@ -375,14 +377,14 @@ ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifie
ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
- if (structure()->typeInfo().hasStandardGetOwnPropertySlot())
+ if (!structure()->typeInfo().overridesGetOwnPropertySlot())
return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot);
return getOwnPropertySlot(exec, propertyName, slot);
}
// It may seem crazy to inline a function this large but it makes a big difference
// since this is function very hot in variable lookup
-inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
JSObject* object = this;
while (true) {
@@ -395,7 +397,7 @@ inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propert
}
}
-inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
JSObject* object = this;
while (true) {
@@ -689,7 +691,7 @@ ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack)
{
JSCell::markChildren(markStack);
- m_structure->markAggregate(markStack);
+ markStack.append(prototype());
PropertyStorage storage = propertyStorage();
size_t storageSize = m_structure->propertyStorageSize();
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index e08a3d9..d3dcb83 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -29,26 +29,62 @@
#include "config.h"
#include "JSPropertyNameIterator.h"
+#include "JSGlobalObject.h"
+
namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator);
-JSPropertyNameIterator::~JSPropertyNameIterator()
+JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o)
{
+ ASSERT(!o->structure()->enumerationCache() ||
+ o->structure()->enumerationCache()->cachedStructure() != o->structure() ||
+ o->structure()->enumerationCache()->cachedPrototypeChain() != o->structure()->prototypeChain(exec));
+
+ PropertyNameArray propertyNames(exec);
+ o->getPropertyNames(exec, propertyNames);
+ size_t numCacheableSlots = 0;
+ if (!o->structure()->hasNonEnumerableProperties() && !o->structure()->hasAnonymousSlots() &&
+ !o->structure()->hasGetterSetterProperties() && !o->structure()->isUncacheableDictionary() &&
+ !o->structure()->typeInfo().overridesGetPropertyNames())
+ numCacheableSlots = o->structure()->propertyStorageSize();
+
+ JSPropertyNameIterator* jsPropertyNameIterator = new (exec) JSPropertyNameIterator(exec, propertyNames.data(), numCacheableSlots);
+
+ if (o->structure()->isDictionary())
+ return jsPropertyNameIterator;
+
+ if (o->structure()->typeInfo().overridesGetPropertyNames())
+ return jsPropertyNameIterator;
+
+ size_t count = normalizePrototypeChain(exec, o);
+ StructureChain* structureChain = o->structure()->prototypeChain(exec);
+ RefPtr<Structure>* structure = structureChain->head();
+ for (size_t i = 0; i < count; ++i) {
+ if (structure[i]->typeInfo().overridesGetPropertyNames())
+ return jsPropertyNameIterator;
+ }
+
+ jsPropertyNameIterator->setCachedPrototypeChain(structureChain);
+ jsPropertyNameIterator->setCachedStructure(o->structure());
+ o->structure()->setEnumerationCache(jsPropertyNameIterator);
+ return jsPropertyNameIterator;
}
-void JSPropertyNameIterator::markChildren(MarkStack& markStack)
+JSValue JSPropertyNameIterator::get(ExecState* exec, JSObject* base, size_t i)
{
- JSCell::markChildren(markStack);
- if (m_object)
- markStack.append(m_object);
+ JSValue& identifier = m_jsStrings[i];
+ if (m_cachedStructure == base->structure() && m_cachedPrototypeChain == base->structure()->prototypeChain(exec))
+ return identifier;
+
+ if (!base->hasProperty(exec, Identifier(exec, asString(identifier)->value(exec))))
+ return JSValue();
+ return identifier;
}
-void JSPropertyNameIterator::invalidate()
+void JSPropertyNameIterator::markChildren(MarkStack& markStack)
{
- ASSERT(m_position == m_end);
- m_object = 0;
- m_data.clear();
+ markStack.appendValues(m_jsStrings.get(), m_jsStringsSize, MayContainNullValues);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h
index d2849a8..f5c64bb 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -31,7 +31,9 @@
#include "JSObject.h"
#include "JSString.h"
+#include "Operations.h"
#include "PropertyNameArray.h"
+#include "StructureChain.h"
namespace JSC {
@@ -39,73 +41,63 @@ namespace JSC {
class JSObject;
class JSPropertyNameIterator : public JSCell {
+ friend class JIT;
+
public:
- static JSPropertyNameIterator* create(ExecState*, JSValue);
+ static JSPropertyNameIterator* create(ExecState*, JSObject*);
+
+ static PassRefPtr<Structure> createStructure(JSValue prototype)
+ {
+ return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren));
+ }
- virtual ~JSPropertyNameIterator();
+ virtual bool isPropertyNameIterator() const { return true; }
virtual void markChildren(MarkStack&);
- JSValue next(ExecState*);
- void invalidate();
-
- static PassRefPtr<Structure> createStructure(JSValue prototype)
+ bool getOffset(size_t i, int& offset)
{
- return Structure::create(prototype, TypeInfo(CompoundType));
+ if (i >= m_numCacheableSlots)
+ return false;
+ offset = i;
+ return true;
}
+
+ JSValue get(ExecState*, JSObject*, size_t i);
+ size_t size() { return m_jsStringsSize; }
+
+ void setCachedStructure(Structure* structure) { m_cachedStructure = structure; }
+ Structure* cachedStructure() { return m_cachedStructure; }
+
+ void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
+ StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
+
private:
- JSPropertyNameIterator(ExecState*);
- JSPropertyNameIterator(ExecState*, JSObject*, PassRefPtr<PropertyNameArrayData> propertyNameArrayData);
+ JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot);
- JSObject* m_object;
- RefPtr<PropertyNameArrayData> m_data;
- PropertyNameArrayData::const_iterator m_position;
- PropertyNameArrayData::const_iterator m_end;
+ Structure* m_cachedStructure;
+ RefPtr<StructureChain> m_cachedPrototypeChain;
+ uint32_t m_numCacheableSlots;
+ uint32_t m_jsStringsSize;
+ OwnArrayPtr<JSValue> m_jsStrings;
};
-inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec)
+inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots)
: JSCell(exec->globalData().propertyNameIteratorStructure.get())
- , m_object(0)
- , m_position(0)
- , m_end(0)
+ , m_cachedStructure(0)
+ , m_numCacheableSlots(numCacheableSlots)
+ , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
+ , m_jsStrings(new JSValue[m_jsStringsSize])
{
+ PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
+ for (size_t i = 0; i < m_jsStringsSize; ++i)
+ m_jsStrings[i] = jsOwnedString(exec, propertyNameVector[i].ustring());
}
-inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, JSObject* object, PassRefPtr<PropertyNameArrayData> propertyNameArrayData)
- : JSCell(exec->globalData().propertyNameIteratorStructure.get())
- , m_object(object)
- , m_data(propertyNameArrayData)
- , m_position(m_data->begin())
- , m_end(m_data->end())
-{
-}
-
-inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue v)
+inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache)
{
- if (v.isUndefinedOrNull())
- return new (exec) JSPropertyNameIterator(exec);
-
- JSObject* o = v.toObject(exec);
- PropertyNameArray propertyNames(exec);
- o->getPropertyNames(exec, propertyNames);
- return new (exec) JSPropertyNameIterator(exec, o, propertyNames.releaseData());
-}
-
-inline JSValue JSPropertyNameIterator::next(ExecState* exec)
-{
- if (m_position == m_end)
- return JSValue();
-
- if (m_data->cachedStructure() == m_object->structure() && m_data->cachedPrototypeChain() == m_object->structure()->prototypeChain(exec))
- return jsOwnedString(exec, (*m_position++).ustring());
-
- do {
- if (m_object->hasProperty(exec, *m_position))
- return jsOwnedString(exec, (*m_position++).ustring());
- m_position++;
- } while (m_position != m_end);
-
- return JSValue();
+ ASSERT(!isDictionary());
+ m_enumerationCache = enumerationCache;
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h
index 5eb0e4b..2542878 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -57,7 +57,10 @@ namespace JSC{
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); }
+
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
private:
JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); }
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp
index a30f729..1e23a15 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.cpp
@@ -25,41 +25,150 @@
#include "JSGlobalObject.h"
#include "JSObject.h"
+#include "Operations.h"
#include "StringObject.h"
#include "StringPrototype.h"
namespace JSC {
+void JSString::Rope::destructNonRecursive()
+{
+ Vector<Rope*, 32> workQueue;
+ Rope* rope = this;
+
+ while (true) {
+ unsigned length = rope->ropeLength();
+ for (unsigned i = 0; i < length; ++i) {
+ Fiber& fiber = rope->fibers(i);
+ if (fiber.isString())
+ fiber.string()->deref();
+ else {
+ Rope* nextRope = fiber.rope();
+ if (nextRope->hasOneRef())
+ workQueue.append(nextRope);
+ else
+ nextRope->deref();
+ }
+ }
+ if (rope != this)
+ fastFree(rope);
+
+ if (workQueue.isEmpty())
+ return;
+
+ rope = workQueue.last();
+ workQueue.removeLast();
+ }
+}
+
+JSString::Rope::~Rope()
+{
+ destructNonRecursive();
+}
+
+// Overview: this methods converts a JSString from holding a string in rope form
+// down to a simple UString representation. It does so by building up the string
+// backwards, since we want to avoid recursion, we expect that the tree structure
+// representing the rope is likely imbalanced with more nodes down the left side
+// (since appending to the string is likely more common) - and as such resolving
+// in this fashion should minimize work queue size. (If we built the queue forwards
+// we would likely have to place all of the constituent UString::Reps into the
+// Vector before performing any concatenation, but by working backwards we likely
+// only fill the queue with the number of substrings at any given level in a
+// rope-of-ropes.)
+void JSString::resolveRope(ExecState* exec) const
+{
+ ASSERT(isRope());
+
+ // Allocate the buffer to hold the final string, position initially points to the end.
+ UChar* buffer;
+ if (PassRefPtr<UStringImpl> newImpl = UStringImpl::tryCreateUninitialized(m_stringLength, buffer))
+ m_value = newImpl;
+ else {
+ for (unsigned i = 0; i < m_ropeLength; ++i) {
+ m_fibers[i].deref();
+ m_fibers[i] = static_cast<void*>(0);
+ }
+ m_ropeLength = 0;
+ ASSERT(!isRope());
+ ASSERT(m_value == UString());
+ throwOutOfMemoryError(exec);
+ return;
+ }
+ UChar* position = buffer + m_stringLength;
+
+ // Start with the current Rope.
+ Vector<Rope::Fiber, 32> workQueue;
+ Rope::Fiber currentFiber;
+ for (unsigned i = 0; i < (m_ropeLength - 1); ++i)
+ workQueue.append(m_fibers[i]);
+ currentFiber = m_fibers[m_ropeLength - 1];
+ while (true) {
+ if (currentFiber.isRope()) {
+ Rope* rope = currentFiber.rope();
+ // Copy the contents of the current rope into the workQueue, with the last item in 'currentFiber'
+ // (we will be working backwards over the rope).
+ unsigned ropeLengthMinusOne = rope->ropeLength() - 1;
+ for (unsigned i = 0; i < ropeLengthMinusOne; ++i)
+ workQueue.append(rope->fibers(i));
+ currentFiber = rope->fibers(ropeLengthMinusOne);
+ } else {
+ UString::Rep* string = currentFiber.string();
+ unsigned length = string->size();
+ position -= length;
+ UStringImpl::copyChars(position, string->data(), length);
+
+ // Was this the last item in the work queue?
+ if (workQueue.isEmpty()) {
+ // Create a string from the UChar buffer, clear the rope RefPtr.
+ ASSERT(buffer == position);
+ for (unsigned i = 0; i < m_ropeLength; ++i) {
+ m_fibers[i].deref();
+ m_fibers[i] = static_cast<void*>(0);
+ }
+ m_ropeLength = 0;
+
+ ASSERT(!isRope());
+ return;
+ }
+
+ // No! - set the next item up to process.
+ currentFiber = workQueue.last();
+ workQueue.removeLast();
+ }
+ }
+}
+
JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
{
return const_cast<JSString*>(this);
}
-bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
+bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result)
{
- value = this;
- number = m_value.toDouble();
+ result = this;
+ number = value(exec).toDouble();
return false;
}
bool JSString::toBoolean(ExecState*) const
{
- return !m_value.isEmpty();
+ return m_stringLength;
}
-double JSString::toNumber(ExecState*) const
+double JSString::toNumber(ExecState* exec) const
{
- return m_value.toDouble();
+ return value(exec).toDouble();
}
-UString JSString::toString(ExecState*) const
+UString JSString::toString(ExecState* exec) const
{
- return m_value;
+ return value(exec);
}
-UString JSString::toThisString(ExecState*) const
+UString JSString::toThisString(ExecState* exec) const
{
- return m_value;
+ return value(exec);
}
JSString* JSString::toThisJSString(ExecState*)
@@ -106,14 +215,14 @@ bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNam
bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
if (propertyName == exec->propertyNames().length) {
- descriptor.setDescriptor(jsNumber(exec, m_value.size()), DontEnum | DontDelete | ReadOnly);
+ descriptor.setDescriptor(jsNumber(exec, m_stringLength), DontEnum | DontDelete | ReadOnly);
return true;
}
bool isStrictUInt32;
unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
- if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {
- descriptor.setDescriptor(jsSingleCharacterSubstring(exec, m_value, i), DontDelete | ReadOnly);
+ if (isStrictUInt32 && i < m_stringLength) {
+ descriptor.setDescriptor(jsSingleCharacterSubstring(exec, value(exec), i), DontDelete | ReadOnly);
return true;
}
@@ -139,60 +248,4 @@ bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Proper
return JSString::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
}
-bool JSString::getStringPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
-{
- if (propertyName == exec->propertyNames().length) {
- attributes = DontEnum | DontDelete | ReadOnly;
- return true;
- }
- bool isStrictUInt32;
- unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
- if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {
- attributes = DontDelete | ReadOnly;
- return true;
- }
- return false;
-}
-
-JSString* jsString(JSGlobalData* globalData, const UString& s)
-{
- int size = s.size();
- if (!size)
- return globalData->smallStrings.emptyString(globalData);
- if (size == 1) {
- UChar c = s.data()[0];
- if (c <= 0xFF)
- return globalData->smallStrings.singleCharacterString(globalData, c);
- }
- return new (globalData) JSString(globalData, s);
-}
-
-JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length)
-{
- ASSERT(offset <= static_cast<unsigned>(s.size()));
- ASSERT(length <= static_cast<unsigned>(s.size()));
- ASSERT(offset + length <= static_cast<unsigned>(s.size()));
- if (!length)
- return globalData->smallStrings.emptyString(globalData);
- if (length == 1) {
- UChar c = s.data()[offset];
- if (c <= 0xFF)
- return globalData->smallStrings.singleCharacterString(globalData, c);
- }
- return new (globalData) JSString(globalData, UString::Rep::create(s.rep(), offset, length));
-}
-
-JSString* jsOwnedString(JSGlobalData* globalData, const UString& s)
-{
- int size = s.size();
- if (!size)
- return globalData->smallStrings.emptyString(globalData);
- if (size == 1) {
- UChar c = s.data()[0];
- if (c <= 0xFF)
- return globalData->smallStrings.singleCharacterString(globalData, c);
- }
- return new (globalData) JSString(globalData, s, JSString::HasOtherOwner);
-}
-
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h
index eeada2e..e1c6aba 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSString.h
@@ -59,14 +59,117 @@ namespace JSC {
JSString* jsOwnedString(JSGlobalData*, const UString&);
JSString* jsOwnedString(ExecState*, const UString&);
- class JSString : public JSCell {
- friend class JIT;
- friend struct VPtrSet;
+ typedef void (*JSStringFinalizerCallback)(JSString*, void* context);
+ JSString* jsStringWithFinalizer(ExecState*, const UString&, JSStringFinalizerCallback callback, void* context);
+ class JS_EXPORTCLASS JSString : public JSCell {
public:
- JSString(JSGlobalData* globalData, const UString& value)
+ friend class JIT;
+ friend class JSGlobalData;
+
+ // A Rope is a string composed of a set of substrings.
+ class Rope : public RefCounted<Rope> {
+ public:
+ // A Rope is composed from a set of smaller strings called Fibers.
+ // Each Fiber in a rope is either UString::Rep or another Rope.
+ class Fiber {
+ public:
+ Fiber() : m_value(0) {}
+ Fiber(UString::Rep* string) : m_value(reinterpret_cast<intptr_t>(string)) {}
+ Fiber(Rope* rope) : m_value(reinterpret_cast<intptr_t>(rope) | 1) {}
+
+ Fiber(void* nonFiber) : m_value(reinterpret_cast<intptr_t>(nonFiber)) {}
+
+ void deref()
+ {
+ if (isRope())
+ rope()->deref();
+ else
+ string()->deref();
+ }
+
+ Fiber& ref()
+ {
+ if (isString())
+ string()->ref();
+ else
+ rope()->ref();
+ return *this;
+ }
+
+ unsigned refAndGetLength()
+ {
+ if (isString()) {
+ UString::Rep* rep = string();
+ return rep->ref()->size();
+ } else {
+ Rope* r = rope();
+ r->ref();
+ return r->stringLength();
+ }
+ }
+
+ bool isRope() { return m_value & 1; }
+ Rope* rope() { return reinterpret_cast<Rope*>(m_value & ~1); }
+ bool isString() { return !isRope(); }
+ UString::Rep* string() { return reinterpret_cast<UString::Rep*>(m_value); }
+
+ void* nonFiber() { return reinterpret_cast<void*>(m_value); }
+ private:
+ intptr_t m_value;
+ };
+
+ // Creates a Rope comprising of 'ropeLength' Fibers.
+ // The Rope is constructed in an uninitialized state - initialize must be called for each Fiber in the Rope.
+ static PassRefPtr<Rope> createOrNull(unsigned ropeLength)
+ {
+ void* allocation;
+ if (tryFastMalloc(sizeof(Rope) + (ropeLength - 1) * sizeof(Fiber)).getValue(allocation))
+ return adoptRef(new (allocation) Rope(ropeLength));
+ return 0;
+ }
+
+ ~Rope();
+ void destructNonRecursive();
+
+ void append(unsigned &index, Fiber& fiber)
+ {
+ m_fibers[index++] = fiber;
+ m_stringLength += fiber.refAndGetLength();
+ }
+ void append(unsigned &index, const UString& string)
+ {
+ UString::Rep* rep = string.rep();
+ m_fibers[index++] = Fiber(rep);
+ m_stringLength += rep->ref()->size();
+ }
+ void append(unsigned& index, JSString* jsString)
+ {
+ if (jsString->isRope()) {
+ for (unsigned i = 0; i < jsString->m_ropeLength; ++i)
+ append(index, jsString->m_fibers[i]);
+ } else
+ append(index, jsString->string());
+ }
+
+ unsigned ropeLength() { return m_ropeLength; }
+ unsigned stringLength() { return m_stringLength; }
+ Fiber& fibers(unsigned index) { return m_fibers[index]; }
+
+ private:
+ Rope(unsigned ropeLength) : m_ropeLength(ropeLength), m_stringLength(0) {}
+ void* operator new(size_t, void* inPlace) { return inPlace; }
+
+ unsigned m_ropeLength;
+ unsigned m_stringLength;
+ Fiber m_fibers[1];
+ };
+
+ ALWAYS_INLINE JSString(JSGlobalData* globalData, const UString& value)
: JSCell(globalData->stringStructure.get())
+ , m_stringLength(value.size())
, m_value(value)
+ , m_ropeLength(0)
{
Heap::heap(this)->reportExtraMemoryCost(value.cost());
}
@@ -74,33 +177,164 @@ namespace JSC {
enum HasOtherOwnerType { HasOtherOwner };
JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType)
: JSCell(globalData->stringStructure.get())
+ , m_stringLength(value.size())
, m_value(value)
+ , m_ropeLength(0)
{
}
JSString(JSGlobalData* globalData, PassRefPtr<UString::Rep> value, HasOtherOwnerType)
: JSCell(globalData->stringStructure.get())
+ , m_stringLength(value->size())
, m_value(value)
+ , m_ropeLength(0)
{
}
-
- const UString& value() const { return m_value; }
+ JSString(JSGlobalData* globalData, PassRefPtr<JSString::Rope> rope)
+ : JSCell(globalData->stringStructure.get())
+ , m_stringLength(rope->stringLength())
+ , m_ropeLength(1)
+ {
+ m_fibers[0] = rope.releaseRef();
+ }
+ // This constructor constructs a new string by concatenating s1 & s2.
+ // This should only be called with ropeLength <= 3.
+ JSString(JSGlobalData* globalData, unsigned ropeLength, JSString* s1, JSString* s2)
+ : JSCell(globalData->stringStructure.get())
+ , m_stringLength(s1->length() + s2->length())
+ , m_ropeLength(ropeLength)
+ {
+ ASSERT(ropeLength <= s_maxInternalRopeLength);
+ unsigned index = 0;
+ appendStringInConstruct(index, s1);
+ appendStringInConstruct(index, s2);
+ ASSERT(ropeLength == index);
+ }
+ // This constructor constructs a new string by concatenating s1 & s2.
+ // This should only be called with ropeLength <= 3.
+ JSString(JSGlobalData* globalData, unsigned ropeLength, JSString* s1, const UString& u2)
+ : JSCell(globalData->stringStructure.get())
+ , m_stringLength(s1->length() + u2.size())
+ , m_ropeLength(ropeLength)
+ {
+ ASSERT(ropeLength <= s_maxInternalRopeLength);
+ unsigned index = 0;
+ appendStringInConstruct(index, s1);
+ appendStringInConstruct(index, u2);
+ ASSERT(ropeLength == index);
+ }
+ // This constructor constructs a new string by concatenating s1 & s2.
+ // This should only be called with ropeLength <= 3.
+ JSString(JSGlobalData* globalData, unsigned ropeLength, const UString& u1, JSString* s2)
+ : JSCell(globalData->stringStructure.get())
+ , m_stringLength(u1.size() + s2->length())
+ , m_ropeLength(ropeLength)
+ {
+ ASSERT(ropeLength <= s_maxInternalRopeLength);
+ unsigned index = 0;
+ appendStringInConstruct(index, u1);
+ appendStringInConstruct(index, s2);
+ ASSERT(ropeLength == index);
+ }
+ // This constructor constructs a new string by concatenating v1, v2 & v3.
+ // This should only be called with ropeLength <= 3 ... which since every
+ // value must require a ropeLength of at least one implies that the length
+ // for each value must be exactly 1!
+ JSString(ExecState* exec, JSValue v1, JSValue v2, JSValue v3)
+ : JSCell(exec->globalData().stringStructure.get())
+ , m_stringLength(0)
+ , m_ropeLength(s_maxInternalRopeLength)
+ {
+ unsigned index = 0;
+ appendValueInConstructAndIncrementLength(exec, index, v1);
+ appendValueInConstructAndIncrementLength(exec, index, v2);
+ appendValueInConstructAndIncrementLength(exec, index, v3);
+ ASSERT(index == s_maxInternalRopeLength);
+ }
+
+ JSString(JSGlobalData* globalData, const UString& value, JSStringFinalizerCallback finalizer, void* context)
+ : JSCell(globalData->stringStructure.get())
+ , m_stringLength(value.size())
+ , m_value(value)
+ , m_ropeLength(0)
+ {
+ // nasty hack because we can't union non-POD types
+ m_fibers[0] = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(finalizer));
+ m_fibers[1] = context;
+ Heap::heap(this)->reportExtraMemoryCost(value.cost());
+ }
+
+ ~JSString()
+ {
+ ASSERT(vptr() == JSGlobalData::jsStringVPtr);
+ for (unsigned i = 0; i < m_ropeLength; ++i)
+ m_fibers[i].deref();
+
+ if (!m_ropeLength && m_fibers[0].nonFiber()) {
+ JSStringFinalizerCallback finalizer = (JSStringFinalizerCallback)(m_fibers[0].nonFiber());
+ finalizer(this, m_fibers[1].nonFiber());
+ }
+ }
+
+ const UString& value(ExecState* exec) const
+ {
+ if (isRope())
+ resolveRope(exec);
+ return m_value;
+ }
+ const UString tryGetValue() const
+ {
+ if (isRope())
+ UString();
+ return m_value;
+ }
+ unsigned length() { return m_stringLength; }
bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
bool getStringPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&);
- bool getStringPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned&) const;
-
- bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
- JSString* getIndex(JSGlobalData*, unsigned);
+ bool canGetIndex(unsigned i) { return i < m_stringLength; }
+ JSString* getIndex(ExecState*, unsigned);
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion | HasDefaultMark)); }
+ static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion)); }
private:
enum VPtrStealingHackType { VPtrStealingHack };
JSString(VPtrStealingHackType)
: JSCell(0)
+ , m_ropeLength(0)
+ {
+ }
+
+ void resolveRope(ExecState*) const;
+
+ void appendStringInConstruct(unsigned& index, const UString& string)
+ {
+ m_fibers[index++] = Rope::Fiber(string.rep()->ref());
+ }
+
+ void appendStringInConstruct(unsigned& index, JSString* jsString)
{
+ if (jsString->isRope()) {
+ for (unsigned i = 0; i < jsString->m_ropeLength; ++i)
+ m_fibers[index++] = jsString->m_fibers[i].ref();
+ } else
+ appendStringInConstruct(index, jsString->string());
+ }
+
+ void appendValueInConstructAndIncrementLength(ExecState* exec, unsigned& index, JSValue v)
+ {
+ if (v.isString()) {
+ ASSERT(asCell(v)->isString());
+ JSString* s = static_cast<JSString*>(asCell(v));
+ ASSERT(s->ropeLength() == 1);
+ appendStringInConstruct(index, s);
+ m_stringLength += s->length();
+ } else {
+ UString u(v.toString(exec));
+ m_fibers[index++] = Rope::Fiber(u.rep()->ref());
+ m_stringLength += u.size();
+ }
}
virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
@@ -119,11 +353,38 @@ namespace JSC {
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
- UString m_value;
+ static const unsigned s_maxInternalRopeLength = 3;
+
+ // A string is represented either by a UString or a Rope.
+ unsigned m_stringLength;
+ mutable UString m_value;
+ mutable unsigned m_ropeLength;
+ mutable Rope::Fiber m_fibers[s_maxInternalRopeLength];
+
+ bool isRope() const { return m_ropeLength; }
+ UString& string() { ASSERT(!isRope()); return m_value; }
+ unsigned ropeLength() { return m_ropeLength ? m_ropeLength : 1; }
+
+ friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2);
+ friend JSValue jsString(ExecState* exec, const UString& u1, JSString* s2);
+ friend JSValue jsString(ExecState* exec, JSString* s1, const UString& u2);
+ friend JSValue jsString(ExecState* exec, Register* strings, unsigned count);
+ friend JSValue jsString(ExecState* exec, JSValue thisValue, const ArgList& args);
+ friend JSString* jsStringWithFinalizer(ExecState*, const UString&, JSStringFinalizerCallback callback, void* context);
};
JSString* asString(JSValue);
+ // When an object is created from a different DLL, MSVC changes vptr to a "local" one right after invoking a constructor,
+ // see <http://groups.google.com/group/microsoft.public.vc.language/msg/55cdcefeaf770212>.
+ // This breaks isJSString(), and we don't need that hack anyway, so we change vptr back to primary one.
+ // The below function must be called by any inline function that invokes a JSString constructor.
+#if COMPILER(MSVC) && !defined(BUILDING_JavaScriptCore)
+ inline JSString* fixupVPtr(JSGlobalData* globalData, JSString* string) { string->setVPtr(globalData->jsStringVPtr); return string; }
+#else
+ inline JSString* fixupVPtr(JSGlobalData*, JSString* string) { return string; }
+#endif
+
inline JSString* asString(JSValue value)
{
ASSERT(asCell(value)->isString());
@@ -139,7 +400,7 @@ namespace JSC {
{
if (c <= 0xFF)
return globalData->smallStrings.singleCharacterString(globalData, c);
- return new (globalData) JSString(globalData, UString(&c, 1));
+ return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(&c, 1)));
}
inline JSString* jsSingleCharacterSubstring(JSGlobalData* globalData, const UString& s, unsigned offset)
@@ -148,7 +409,7 @@ namespace JSC {
UChar c = s.data()[offset];
if (c <= 0xFF)
return globalData->smallStrings.singleCharacterString(globalData, c);
- return new (globalData) JSString(globalData, UString::Rep::create(s.rep(), offset, 1));
+ return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UString::Rep::create(s.rep(), offset, 1))));
}
inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s)
@@ -156,19 +417,67 @@ namespace JSC {
ASSERT(s);
ASSERT(s[0]);
ASSERT(s[1]);
- return new (globalData) JSString(globalData, s);
+ return fixupVPtr(globalData, new (globalData) JSString(globalData, s));
}
inline JSString* jsNontrivialString(JSGlobalData* globalData, const UString& s)
{
ASSERT(s.size() > 1);
- return new (globalData) JSString(globalData, s);
+ return fixupVPtr(globalData, new (globalData) JSString(globalData, s));
}
- inline JSString* JSString::getIndex(JSGlobalData* globalData, unsigned i)
+ inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
{
ASSERT(canGetIndex(i));
- return jsSingleCharacterSubstring(globalData, m_value, i);
+ return jsSingleCharacterSubstring(&exec->globalData(), value(exec), i);
+ }
+
+ inline JSString* jsString(JSGlobalData* globalData, const UString& s)
+ {
+ int size = s.size();
+ if (!size)
+ return globalData->smallStrings.emptyString(globalData);
+ if (size == 1) {
+ UChar c = s.data()[0];
+ if (c <= 0xFF)
+ return globalData->smallStrings.singleCharacterString(globalData, c);
+ }
+ return fixupVPtr(globalData, new (globalData) JSString(globalData, s));
+ }
+
+ inline JSString* jsStringWithFinalizer(ExecState* exec, const UString& s, JSStringFinalizerCallback callback, void* context)
+ {
+ ASSERT(s.size() && (s.size() > 1 || s.data()[0] > 0xFF));
+ JSGlobalData* globalData = &exec->globalData();
+ return fixupVPtr(globalData, new (globalData) JSString(globalData, s, callback, context));
+ }
+
+ inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length)
+ {
+ ASSERT(offset <= static_cast<unsigned>(s.size()));
+ ASSERT(length <= static_cast<unsigned>(s.size()));
+ ASSERT(offset + length <= static_cast<unsigned>(s.size()));
+ if (!length)
+ return globalData->smallStrings.emptyString(globalData);
+ if (length == 1) {
+ UChar c = s.data()[offset];
+ if (c <= 0xFF)
+ return globalData->smallStrings.singleCharacterString(globalData, c);
+ }
+ return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UString::Rep::create(s.rep(), offset, length)), JSString::HasOtherOwner));
+ }
+
+ inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s)
+ {
+ int size = s.size();
+ if (!size)
+ return globalData->smallStrings.emptyString(globalData);
+ if (size == 1) {
+ UChar c = s.data()[0];
+ if (c <= 0xFF)
+ return globalData->smallStrings.singleCharacterString(globalData, c);
+ }
+ return fixupVPtr(globalData, new (globalData) JSString(globalData, s, JSString::HasOtherOwner));
}
inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); }
@@ -183,14 +492,14 @@ namespace JSC {
ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
if (propertyName == exec->propertyNames().length) {
- slot.setValue(jsNumber(exec, m_value.size()));
+ slot.setValue(jsNumber(exec, m_stringLength));
return true;
}
bool isStrictUInt32;
unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
- if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {
- slot.setValue(jsSingleCharacterSubstring(exec, m_value, i));
+ if (isStrictUInt32 && i < m_stringLength) {
+ slot.setValue(jsSingleCharacterSubstring(exec, value(exec), i));
return true;
}
@@ -199,8 +508,8 @@ namespace JSC {
ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
- if (propertyName < static_cast<unsigned>(m_value.size())) {
- slot.setValue(jsSingleCharacterSubstring(exec, m_value, propertyName));
+ if (propertyName < m_stringLength) {
+ slot.setValue(jsSingleCharacterSubstring(exec, value(exec), propertyName));
return true;
}
@@ -219,7 +528,7 @@ namespace JSC {
inline UString JSValue::toString(ExecState* exec) const
{
if (isString())
- return static_cast<JSString*>(asCell())->value();
+ return static_cast<JSString*>(asCell())->value(exec);
if (isInt32())
return exec->globalData().numericStrings.add(asInt32());
if (isDouble())
@@ -236,6 +545,26 @@ namespace JSC {
return asCell()->toString(exec);
}
+ inline UString JSValue::toPrimitiveString(ExecState* exec) const
+ {
+ if (isString())
+ return static_cast<JSString*>(asCell())->value(exec);
+ if (isInt32())
+ return exec->globalData().numericStrings.add(asInt32());
+ if (isDouble())
+ return exec->globalData().numericStrings.add(asDouble());
+ if (isTrue())
+ return "true";
+ if (isFalse())
+ return "false";
+ if (isNull())
+ return "null";
+ if (isUndefined())
+ return "undefined";
+ ASSERT(isCell());
+ return asCell()->toPrimitive(exec, NoPreference).toString(exec);
+ }
+
} // namespace JSC
#endif // JSString_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h
index 279510b..7c89600 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSTypeInfo.h
@@ -40,9 +40,9 @@ namespace JSC {
static const unsigned OverridesHasInstance = 1 << 2;
static const unsigned ImplementsDefaultHasInstance = 1 << 3;
static const unsigned NeedsThisConversion = 1 << 4;
- static const unsigned HasStandardGetOwnPropertySlot = 1 << 5;
- static const unsigned HasDefaultMark = 1 << 6;
- static const unsigned HasDefaultGetPropertyNames = 1 << 7;
+ static const unsigned OverridesGetOwnPropertySlot = 1 << 5;
+ static const unsigned OverridesMarkChildren = 1 << 6;
+ static const unsigned OverridesGetPropertyNames = 1 << 7;
class TypeInfo {
friend class JIT;
@@ -63,9 +63,9 @@ namespace JSC {
bool implementsHasInstance() const { return m_flags & ImplementsHasInstance; }
bool overridesHasInstance() const { return m_flags & OverridesHasInstance; }
bool needsThisConversion() const { return m_flags & NeedsThisConversion; }
- bool hasStandardGetOwnPropertySlot() const { return m_flags & HasStandardGetOwnPropertySlot; }
- bool hasDefaultMark() const { return m_flags & HasDefaultMark; }
- bool hasDefaultGetPropertyNames() const { return m_flags & HasDefaultGetPropertyNames; }
+ bool overridesGetOwnPropertySlot() const { return m_flags & OverridesGetOwnPropertySlot; }
+ bool overridesMarkChildren() const { return m_flags & OverridesMarkChildren; }
+ bool overridesGetPropertyNames() const { return m_flags & OverridesGetPropertyNames; }
unsigned flags() const { return m_flags; }
private:
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h
index 3c511d8..6da921f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSValue.h
@@ -80,6 +80,7 @@ namespace JSC {
enum JSUndefinedTag { JSUndefined };
enum JSTrueTag { JSTrue };
enum JSFalseTag { JSFalse };
+ enum EncodeAsDoubleTag { EncodeAsDouble };
JSValue();
JSValue(JSNullTag);
@@ -90,6 +91,7 @@ namespace JSC {
JSValue(const JSCell* ptr);
// Numbers
+ JSValue(EncodeAsDoubleTag, ExecState*, double);
JSValue(ExecState*, double);
JSValue(ExecState*, char);
JSValue(ExecState*, unsigned char);
@@ -135,8 +137,8 @@ namespace JSC {
bool getBoolean() const; // false if not a boolean
bool getNumber(double&) const;
double uncheckedGetNumber() const;
- bool getString(UString&) const;
- UString getString() const; // null string if not a string
+ bool getString(ExecState* exec, UString&) const;
+ UString getString(ExecState* exec) const; // null string if not a string
JSObject* getObject() const; // 0 if not an object
CallType getCallData(CallData&);
@@ -156,6 +158,7 @@ namespace JSC {
double toNumber(ExecState*) const;
JSValue toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
UString toString(ExecState*) const;
+ UString toPrimitiveString(ExecState*) const;
JSObject* toObject(ExecState*) const;
// Integer conversions.
@@ -166,6 +169,10 @@ namespace JSC {
uint32_t toUInt32(ExecState*) const;
uint32_t toUInt32(ExecState*, bool& ok) const;
+#if ENABLE(JSC_ZOMBIES)
+ bool isZombie() const;
+#endif
+
// 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)); }
@@ -186,9 +193,9 @@ namespace JSC {
static bool equal(ExecState* exec, JSValue v1, JSValue v2);
static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
static bool equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
- static bool strictEqual(JSValue v1, JSValue v2);
- static bool strictEqualSlowCase(JSValue v1, JSValue v2);
- static bool strictEqualSlowCaseInline(JSValue v1, JSValue v2);
+ static bool strictEqual(ExecState* exec, JSValue v1, JSValue v2);
+ static bool strictEqualSlowCase(ExecState* exec, JSValue v1, JSValue v2);
+ static bool strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object
@@ -228,7 +235,7 @@ namespace JSC {
union {
EncodedJSValue asEncodedJSValue;
double asDouble;
-#if PLATFORM(BIG_ENDIAN)
+#if CPU(BIG_ENDIAN)
struct {
int32_t tag;
int32_t payload;
@@ -279,6 +286,11 @@ namespace JSC {
return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
}
+ ALWAYS_INLINE JSValue jsDoubleNumber(ExecState* exec, double d)
+ {
+ return JSValue(JSValue::EncodeAsDouble, exec, d);
+ }
+
ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d)
{
return JSValue(exec, d);
@@ -373,6 +385,14 @@ namespace JSC {
return static_cast<uint32_t>(val);
}
+ // FIXME: We should deprecate this and just use JSValue::asCell() instead.
+ JSCell* asCell(JSValue);
+
+ inline JSCell* asCell(JSValue value)
+ {
+ return value.asCell();
+ }
+
ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
{
if (isInt32())
@@ -423,6 +443,9 @@ namespace JSC {
{
JSValue v;
v.u.asEncodedJSValue = encodedJSValue;
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!v.isZombie());
+#endif
return v;
}
@@ -469,6 +492,9 @@ namespace JSC {
else
u.asBits.tag = EmptyValueTag;
u.asBits.payload = reinterpret_cast<int32_t>(ptr);
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
}
inline JSValue::JSValue(const JSCell* ptr)
@@ -478,6 +504,9 @@ namespace JSC {
else
u.asBits.tag = EmptyValueTag;
u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
}
inline JSValue::operator bool() const
@@ -575,6 +604,11 @@ namespace JSC {
return reinterpret_cast<JSCell*>(u.asBits.payload);
}
+ ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState*, double d)
+ {
+ u.asDouble = d;
+ }
+
inline JSValue::JSValue(ExecState* exec, double d)
{
const int32_t asInt32 = static_cast<int32_t>(d);
@@ -773,11 +807,17 @@ namespace JSC {
inline JSValue::JSValue(JSCell* ptr)
: m_ptr(ptr)
{
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
}
inline JSValue::JSValue(const JSCell* ptr)
: m_ptr(const_cast<JSCell*>(ptr))
{
+#if ENABLE(JSC_ZOMBIES)
+ ASSERT(!isZombie());
+#endif
}
inline JSValue::operator bool() const
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp
index ac193ca..7365001 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.cpp
@@ -34,33 +34,23 @@
namespace JSC {
-bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
if (symbolTable().contains(propertyName.ustring().rep()))
return false;
- return JSObject::deleteProperty(exec, propertyName, checkDontDelete);
+ return JSObject::deleteProperty(exec, propertyName);
}
-void JSVariableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable)
+void JSVariableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
SymbolTable::const_iterator end = symbolTable().end();
for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) {
- if (!(it->second.getAttributes() & DontEnum) || includeNonEnumerable)
+ if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))
propertyNames.add(Identifier(exec, it->first.get()));
}
- JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
-}
-
-bool JSVariableObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
-{
- SymbolTableEntry entry = symbolTable().get(propertyName.ustring().rep());
- if (!entry.isNull()) {
- attributes = entry.getAttributes() | DontDelete;
- return true;
- }
- return JSObject::getPropertyAttributes(exec, propertyName, attributes);
+ JSObject::getOwnPropertyNames(exec, propertyNames, mode);
}
bool JSVariableObject::isVariableObject() const
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h
index fe92729..737816d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSVariableObject.h
@@ -48,22 +48,21 @@ namespace JSC {
virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0;
- virtual bool deleteProperty(ExecState*, const Identifier&, bool checkDontDelete = true);
- virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false);
+ virtual bool deleteProperty(ExecState*, const Identifier&);
+ virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual bool isVariableObject() const;
virtual bool isDynamicScope() const = 0;
- virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
-
Register& registerAt(int index) const { return d->registers[index]; }
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
protected:
+ static const unsigned StructureFlags = OverridesGetPropertyNames | JSObject::StructureFlags;
// Subclasses of JSVariableObject can subclass this struct to add data
// without increasing their own size (since there's a hard limit on the
// size of a JSCell).
@@ -84,7 +83,7 @@ namespace JSC {
JSVariableObjectData& operator=(const JSVariableObjectData&);
};
- JSVariableObject(PassRefPtr<Structure> structure, JSVariableObjectData* data)
+ JSVariableObject(NonNullPassRefPtr<Structure> structure, JSVariableObjectData* data)
: JSObject(structure)
, d(data) // Subclass owns this pointer.
{
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h
index b56a58d..191ff3b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSWrapperObject.h
@@ -30,7 +30,7 @@ namespace JSC {
// Number, Boolean and Date which are wrappers for primitive types.
class JSWrapperObject : public JSObject {
protected:
- explicit JSWrapperObject(PassRefPtr<Structure>);
+ explicit JSWrapperObject(NonNullPassRefPtr<Structure>);
public:
JSValue internalValue() const { return m_internalValue; }
@@ -38,7 +38,7 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames | HasDefaultMark));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
private:
@@ -47,7 +47,7 @@ namespace JSC {
JSValue m_internalValue;
};
- inline JSWrapperObject::JSWrapperObject(PassRefPtr<Structure> structure)
+ inline JSWrapperObject::JSWrapperObject(NonNullPassRefPtr<Structure> structure)
: JSObject(structure)
{
addAnonymousSlots(1);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSZombie.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSZombie.cpp
new file mode 100644
index 0000000..072d29b
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSZombie.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "JSZombie.h"
+#include "ClassInfo.h"
+
+#if ENABLE(JSC_ZOMBIES)
+
+namespace JSC {
+
+const ClassInfo JSZombie::s_info = { "Zombie", 0, 0, 0 };
+
+Structure* JSZombie::leakedZombieStructure() {
+ static Structure* structure = 0;
+ if (!structure) {
+ Structure::startIgnoringLeaks();
+ structure = Structure::create(jsNull(), TypeInfo(UnspecifiedType)).releaseRef();
+ Structure::stopIgnoringLeaks();
+ }
+ return structure;
+}
+
+}
+
+#endif // ENABLE(JSC_ZOMBIES)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSZombie.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSZombie.h
new file mode 100644
index 0000000..8b33ea6
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/JSZombie.h
@@ -0,0 +1,78 @@
+/*
+ * 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 JSZombie_h
+#define JSZombie_h
+
+#include "JSCell.h"
+
+#if ENABLE(JSC_ZOMBIES)
+namespace JSC {
+
+class JSZombie : public JSCell {
+public:
+ JSZombie(const ClassInfo* oldInfo, Structure* structure)
+ : JSCell(structure)
+ , m_oldInfo(oldInfo)
+ {
+ }
+ virtual bool isZombie() const { return true; }
+ virtual const ClassInfo* classInfo() const { return &s_info; }
+ static Structure* leakedZombieStructure();
+
+ virtual bool isGetterSetter() const { ASSERT_NOT_REACHED(); return false; }
+ virtual bool isAPIValueWrapper() const { ASSERT_NOT_REACHED(); return false; }
+ virtual bool isPropertyNameIterator() const { ASSERT_NOT_REACHED(); return false; }
+ virtual CallType getCallData(CallData&) { ASSERT_NOT_REACHED(); return CallTypeNone; }
+ virtual ConstructType getConstructData(ConstructData&) { ASSERT_NOT_REACHED(); return ConstructTypeNone; }
+ virtual bool getUInt32(uint32_t&) const { ASSERT_NOT_REACHED(); return false; }
+ virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const { ASSERT_NOT_REACHED(); return jsNull(); }
+ virtual bool getPrimitiveNumber(ExecState*, double&, JSValue&) { ASSERT_NOT_REACHED(); return false; }
+ virtual bool toBoolean(ExecState*) const { ASSERT_NOT_REACHED(); return false; }
+ virtual double toNumber(ExecState*) const { ASSERT_NOT_REACHED(); return 0.0; }
+ virtual UString toString(ExecState*) const { ASSERT_NOT_REACHED(); return ""; }
+ virtual JSObject* toObject(ExecState*) const { ASSERT_NOT_REACHED(); return 0; }
+ virtual void markChildren(MarkStack&) { ASSERT_NOT_REACHED(); }
+ virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&) { ASSERT_NOT_REACHED(); }
+ virtual void put(ExecState*, unsigned, JSValue) { ASSERT_NOT_REACHED(); }
+ virtual bool deleteProperty(ExecState*, const Identifier&) { ASSERT_NOT_REACHED(); return false; }
+ virtual bool deleteProperty(ExecState*, unsigned) { ASSERT_NOT_REACHED(); return false; }
+ virtual JSObject* toThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return 0; }
+ virtual UString toThisString(ExecState*) const { ASSERT_NOT_REACHED(); return ""; }
+ virtual JSString* toThisJSString(ExecState*) { ASSERT_NOT_REACHED(); return 0; }
+ virtual JSValue getJSNumber() { ASSERT_NOT_REACHED(); return jsNull(); }
+ virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
+ virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
+
+ static const ClassInfo s_info;
+private:
+ const ClassInfo* m_oldInfo;
+};
+
+}
+
+#endif // ENABLE(JSC_ZOMBIES)
+
+#endif // JSZombie_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp
index d242282..aa1e5ed 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/LiteralParser.cpp
@@ -29,6 +29,7 @@
#include "JSArray.h"
#include "JSString.h"
#include "Lexer.h"
+#include "StringBuilder.h"
#include <wtf/ASCIICType.h>
#include <wtf/dtoa.h>
@@ -134,48 +135,48 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
{
++m_ptr;
const UChar* runStart;
- token.stringToken = UString();
+ StringBuilder builder;
do {
runStart = m_ptr;
while (m_ptr < m_end && isSafeStringCharacter<mode>(*m_ptr))
++m_ptr;
if (runStart < m_ptr)
- token.stringToken.append(runStart, m_ptr - runStart);
+ builder.append(runStart, m_ptr - runStart);
if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') {
++m_ptr;
if (m_ptr >= m_end)
return TokError;
switch (*m_ptr) {
case '"':
- token.stringToken.append('"');
+ builder.append('"');
m_ptr++;
break;
case '\\':
- token.stringToken.append('\\');
+ builder.append('\\');
m_ptr++;
break;
case '/':
- token.stringToken.append('/');
+ builder.append('/');
m_ptr++;
break;
case 'b':
- token.stringToken.append('\b');
+ builder.append('\b');
m_ptr++;
break;
case 'f':
- token.stringToken.append('\f');
+ builder.append('\f');
m_ptr++;
break;
case 'n':
- token.stringToken.append('\n');
+ builder.append('\n');
m_ptr++;
break;
case 'r':
- token.stringToken.append('\r');
+ builder.append('\r');
m_ptr++;
break;
case 't':
- token.stringToken.append('\t');
+ builder.append('\t');
m_ptr++;
break;
@@ -186,7 +187,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
if (!isASCIIHexDigit(m_ptr[i]))
return TokError;
}
- token.stringToken.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4]));
+ builder.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4]));
m_ptr += 5;
break;
@@ -199,6 +200,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
if (m_ptr >= m_end || *m_ptr != '"')
return TokError;
+ token.stringToken = builder.release();
token.type = TokString;
token.end = ++m_ptr;
return TokString;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.cpp
index 8359ff7..4e9e086 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.cpp
@@ -34,7 +34,7 @@ void HashTable::createTable(JSGlobalData* globalData) const
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;
+ int hashIndex = identifier->existingHash() & compactHashSizeMask;
HashEntry* entry = &entries[hashIndex];
if (entry->key()) {
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h
index 4d70689..e673c09 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Lookup.h
@@ -144,7 +144,7 @@ namespace JSC {
{
ASSERT(table);
- const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & compactHashSizeMask];
+ const HashEntry* entry = &table[identifier.ustring().rep()->existingHash() & compactHashSizeMask];
if (!entry->key())
return 0;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.h
index 5bc85fa..c551bac 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStack.h
@@ -47,7 +47,7 @@ namespace JSC {
}
ALWAYS_INLINE void append(JSValue);
- ALWAYS_INLINE void append(JSCell*);
+ void append(JSCell*);
ALWAYS_INLINE void appendValues(Register* values, size_t count, MarkSetProperties properties = NoNullValues)
{
@@ -153,7 +153,7 @@ namespace JSC {
ASSERT(0 == (size % MarkStack::pageSize()));
if (size == m_allocated)
return;
-#if PLATFORM(WIN)
+#if OS(WINDOWS) || OS(SYMBIAN) || PLATFORM(BREWMP)
// We cannot release a part of a region with VirtualFree. To get around this,
// we'll release the entire region and reallocate the size that we want.
releaseStack(m_data, m_allocated);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackNone.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackNone.cpp
new file mode 100644
index 0000000..b1ff48b
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackNone.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009 Company 100, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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 "MarkStack.h"
+
+#include "FastMalloc.h"
+
+namespace JSC {
+
+void MarkStack::initializePagesize()
+{
+ MarkStack::s_pageSize = 4096;
+}
+
+void* MarkStack::allocateStack(size_t size)
+{
+ return fastMalloc(size);
+}
+
+void MarkStack::releaseStack(void* addr, size_t)
+{
+ return fastFree(addr);
+}
+
+}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackPosix.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackPosix.cpp
index aec968e..de5e8ba 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackPosix.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackPosix.cpp
@@ -24,49 +24,29 @@
*/
#include "config.h"
-
-
#include "MarkStack.h"
+#if OS(UNIX) && !OS(SYMBIAN)
+
#include <unistd.h>
-#if defined (__SYMBIAN32__)
-#include "wtf/FastMalloc.h"
-#include <e32base.h>
-#include <e32std.h>
-#include <e32hal.h>
-#include <hal.h>
-#else
#include <sys/mman.h>
-#endif
namespace JSC {
void MarkStack::initializePagesize()
{
-#if defined (__SYMBIAN32__)
- TInt page_size;
- UserHal::PageSizeInBytes(page_size);
- MarkStack::s_pageSize = page_size;
-#else
MarkStack::s_pageSize = getpagesize();
-#endif
}
void* MarkStack::allocateStack(size_t size)
{
-#if defined (__SYMBIAN32__)
- return fastMalloc(size);
-#else
return mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
-#endif
}
void MarkStack::releaseStack(void* addr, size_t size)
{
-#if defined (__SYMBIAN32__)
- fastFree(addr);
-#else
munmap(reinterpret_cast<char*>(addr), size);
-#endif
}
}
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackSymbian.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackSymbian.cpp
new file mode 100644
index 0000000..bda14ac
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackSymbian.cpp
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "MarkStack.h"
+
+#if OS(SYMBIAN)
+
+#include <e32hal.h>
+
+namespace JSC {
+
+void MarkStack::initializePagesize()
+{
+ TInt page_size;
+ UserHal::PageSizeInBytes(page_size);
+ MarkStack::s_pageSize = page_size;
+}
+
+void* MarkStack::allocateStack(size_t size)
+{
+ return fastMalloc(size);
+}
+
+void MarkStack::releaseStack(void* addr, size_t size)
+{
+ return fastFree(addr);
+}
+
+}
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackWin.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackWin.cpp
index 1fdd06a..a171c78 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackWin.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MarkStackWin.cpp
@@ -24,10 +24,10 @@
*/
#include "config.h"
-
-
#include "MarkStack.h"
+#if OS(WINDOWS)
+
#include "windows.h"
namespace JSC {
@@ -51,3 +51,5 @@ void MarkStack::releaseStack(void* addr, size_t)
}
}
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp
index 36771ab..98ff3ba 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.cpp
@@ -85,7 +85,7 @@ const ClassInfo MathObject::info = { "Math", 0, 0, ExecState::mathTable };
@end
*/
-MathObject::MathObject(ExecState* exec, PassRefPtr<Structure> structure)
+MathObject::MathObject(ExecState* exec, NonNullPassRefPtr<Structure> structure)
: JSObject(structure)
{
putDirectWithoutTransition(Identifier(exec, "E"), jsNumber(exec, exp(1.0)), DontDelete | DontEnum | ReadOnly);
@@ -96,7 +96,6 @@ MathObject::MathObject(ExecState* exec, PassRefPtr<Structure> 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
@@ -120,22 +119,22 @@ JSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState* exec, JSObject*, JSValue, cons
JSValue JSC_HOST_CALL mathProtoFuncACos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, acos(args.at(0).toNumber(exec)));
+ return jsDoubleNumber(exec, acos(args.at(0).toNumber(exec)));
}
JSValue JSC_HOST_CALL mathProtoFuncASin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, asin(args.at(0).toNumber(exec)));
+ return jsDoubleNumber(exec, asin(args.at(0).toNumber(exec)));
}
JSValue JSC_HOST_CALL mathProtoFuncATan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, atan(args.at(0).toNumber(exec)));
+ return jsDoubleNumber(exec, atan(args.at(0).toNumber(exec)));
}
JSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, atan2(args.at(0).toNumber(exec), args.at(1).toNumber(exec)));
+ return jsDoubleNumber(exec, atan2(args.at(0).toNumber(exec), args.at(1).toNumber(exec)));
}
JSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState* exec, JSObject*, JSValue, const ArgList& args)
@@ -145,12 +144,12 @@ JSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState* exec, JSObject*, JSValue, con
JSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, cos(args.at(0).toNumber(exec)));
+ return jsDoubleNumber(exec, cos(args.at(0).toNumber(exec)));
}
JSValue JSC_HOST_CALL mathProtoFuncExp(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, exp(args.at(0).toNumber(exec)));
+ return jsDoubleNumber(exec, exp(args.at(0).toNumber(exec)));
}
JSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
@@ -160,7 +159,7 @@ JSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState* exec, JSObject*, JSValue, co
JSValue JSC_HOST_CALL mathProtoFuncLog(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, log(args.at(0).toNumber(exec)));
+ return jsDoubleNumber(exec, log(args.at(0).toNumber(exec)));
}
JSValue JSC_HOST_CALL mathProtoFuncMax(ExecState* exec, JSObject*, JSValue, const ArgList& args)
@@ -211,7 +210,7 @@ JSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec, JSObject*, JSValue, cons
JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue, const ArgList&)
{
- return jsNumber(exec, WTF::weakRandomNumber());
+ return jsDoubleNumber(exec, exec->globalData().weakRandom.get());
}
JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, const ArgList& args)
@@ -224,17 +223,17 @@ JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, co
JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, sin(args.at(0).toNumber(exec)));
+ return jsDoubleNumber(exec, sin(args.at(0).toNumber(exec)));
}
JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, sqrt(args.at(0).toNumber(exec)));
+ return jsDoubleNumber(exec, sqrt(args.at(0).toNumber(exec)));
}
JSValue JSC_HOST_CALL mathProtoFuncTan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, tan(args.at(0).toNumber(exec)));
+ return jsDoubleNumber(exec, tan(args.at(0).toNumber(exec)));
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h
index a2e065f..7f474b8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/MathObject.h
@@ -27,7 +27,7 @@ namespace JSC {
class MathObject : public JSObject {
public:
- MathObject(ExecState*, PassRefPtr<Structure>);
+ MathObject(ExecState*, NonNullPassRefPtr<Structure>);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
@@ -37,8 +37,11 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
+
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
};
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.cpp
index 0205fc5..403fc7e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.cpp
@@ -32,8 +32,8 @@ ASSERT_CLASS_FITS_IN_CELL(NativeErrorConstructor);
const ClassInfo NativeErrorConstructor::info = { "Function", &InternalFunction::info, 0, 0 };
-NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, PassRefPtr<Structure> structure, NativeErrorPrototype* nativeErrorPrototype)
- : InternalFunction(&exec->globalData(), structure, Identifier(exec, nativeErrorPrototype->getDirect(exec->propertyNames().name).getString()))
+NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, NativeErrorPrototype* nativeErrorPrototype)
+ : InternalFunction(&exec->globalData(), structure, Identifier(exec, nativeErrorPrototype->getDirect(exec->propertyNames().name).getString(exec)))
, m_errorStructure(ErrorInstance::createStructure(nativeErrorPrototype))
{
putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.h
index 118d1f4..152dbac 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorConstructor.h
@@ -31,7 +31,7 @@ namespace JSC {
class NativeErrorConstructor : public InternalFunction {
public:
- NativeErrorConstructor(ExecState*, PassRefPtr<Structure>, NativeErrorPrototype*);
+ NativeErrorConstructor(ExecState*, NonNullPassRefPtr<Structure>, NativeErrorPrototype*);
static const ClassInfo info;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.cpp
index 650a0fd..ca12798 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.cpp
@@ -29,7 +29,7 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype);
-NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure, const UString& name, const UString& message)
+NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& name, const UString& message)
#ifdef QT_BUILD_SCRIPT_LIB
: ErrorInstance(structure)
#else
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.h
index 48a9d7e..39a02c8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NativeErrorPrototype.h
@@ -36,7 +36,7 @@ namespace JSC {
#endif
{
public:
- NativeErrorPrototype(ExecState*, PassRefPtr<Structure>, const UString& name, const UString& message);
+ NativeErrorPrototype(ExecState*, NonNullPassRefPtr<Structure>, const UString& name, const UString& message);
};
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp
index a95106d..cc6c51d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -53,7 +53,7 @@ const ClassInfo NumberConstructor::info = { "Function", &InternalFunction::info,
@end
*/
-NumberConstructor::NumberConstructor(ExecState* exec, PassRefPtr<Structure> structure, NumberPrototype* numberPrototype)
+NumberConstructor::NumberConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, NumberPrototype* numberPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, numberPrototype->info.className))
{
// Number.Prototype
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h
index 710ac86..cf19b6f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class NumberConstructor : public InternalFunction {
public:
- NumberConstructor(ExecState*, PassRefPtr<Structure>, NumberPrototype*);
+ NumberConstructor(ExecState*, NonNullPassRefPtr<Structure>, NumberPrototype*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
@@ -39,11 +39,14 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames));
+ return Structure::create(proto, TypeInfo(ObjectType, StructureFlags));
}
enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags;
+
private:
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.cpp
index 0e8df17..1a7e44c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.cpp
@@ -31,7 +31,7 @@ ASSERT_CLASS_FITS_IN_CELL(NumberObject);
const ClassInfo NumberObject::info = { "Number", 0, 0, 0 };
-NumberObject::NumberObject(PassRefPtr<Structure> structure)
+NumberObject::NumberObject(NonNullPassRefPtr<Structure> structure)
: JSWrapperObject(structure)
{
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h
index f502bee..8223a90 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberObject.h
@@ -27,20 +27,22 @@ namespace JSC {
class NumberObject : public JSWrapperObject {
public:
- explicit NumberObject(PassRefPtr<Structure>);
+ explicit NumberObject(NonNullPassRefPtr<Structure>);
static const ClassInfo info;
-#if USE(JSVALUE32)
+
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultGetPropertyNames));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
+
+ protected:
+#if USE(JSVALUE32)
+ static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags;
#else
- static PassRefPtr<Structure> createStructure(JSValue prototype)
- {
- return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot | HasDefaultMark | HasDefaultGetPropertyNames));
- }
+ static const unsigned StructureFlags = JSWrapperObject::StructureFlags;
#endif
+
private:
virtual const ClassInfo* classInfo() const { return &info; }
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.cpp
index 947324c..67210fa 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -25,9 +25,10 @@
#include "Error.h"
#include "JSFunction.h"
#include "JSString.h"
+#include "Operations.h"
#include "PrototypeFunction.h"
+#include "StringBuilder.h"
#include "dtoa.h"
-#include "Operations.h"
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
#include <wtf/Vector.h>
@@ -45,7 +46,7 @@ static JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState*, JSObject*, J
// ECMA 15.7.4
-NumberPrototype::NumberPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
+NumberPrototype::NumberPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
: NumberObject(structure)
{
setInternalValue(jsNumber(exec, 0));
@@ -73,11 +74,12 @@ static UString integerPartNoExp(double d)
bool resultIsInfOrNan = (decimalPoint == 9999);
size_t length = strlen(result);
- UString str = sign ? "-" : "";
+ StringBuilder builder;
+ builder.append(sign ? "-" : "");
if (resultIsInfOrNan)
- str += result;
+ builder.append((const char*)result);
else if (decimalPoint <= 0)
- str += "0";
+ builder.append("0");
else {
Vector<char, 1024> buf(decimalPoint + 1);
@@ -89,10 +91,10 @@ static UString integerPartNoExp(double d)
strncpy(buf.data(), result, decimalPoint);
buf[decimalPoint] = '\0';
- str.append(buf.data());
+ builder.append((const char*)(buf.data()));
}
- return str;
+ return builder.release();
}
static UString charSequence(char c, int count)
@@ -236,13 +238,16 @@ JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue
UString s;
if (x < 0) {
- s.append('-');
+ s = "-";
x = -x;
- } else if (x == -0.0)
- x = 0;
+ } else {
+ s = "";
+ if (x == -0.0)
+ x = 0;
+ }
if (x >= pow(10.0, 21.0))
- return jsString(exec, s + UString::from(x));
+ return jsString(exec, makeString(s, UString::from(x)));
const double tenToTheF = pow(10.0, f);
double n = floor(x * tenToTheF);
@@ -253,17 +258,19 @@ JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue
int k = m.size();
if (k <= f) {
- UString z;
+ StringBuilder z;
for (int i = 0; i < f + 1 - k; i++)
z.append('0');
- m = z + m;
+ z.append(m);
+ m = z.release();
k = f + 1;
ASSERT(k == m.size());
}
int kMinusf = k - f;
+
if (kMinusf < m.size())
- return jsString(exec, s + m.substr(0, kMinusf) + "." + m.substr(kMinusf));
- return jsString(exec, s + m.substr(0, kMinusf));
+ return jsString(exec, makeString(s, m.substr(0, kMinusf), ".", m.substr(kMinusf)));
+ return jsString(exec, makeString(s, m.substr(0, kMinusf)));
}
static void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits)
@@ -391,7 +398,8 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV
if (x < 0) {
s = "-";
x = -x;
- }
+ } else
+ s = "";
if (!(doublePrecision >= 1 && doublePrecision <= 21)) // true for NaN
return throwError(exec, RangeError, "toPrecision() argument must be between 1 and 21");
@@ -422,10 +430,10 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV
m = integerPartNoExp(n);
if (e < -6 || e >= precision) {
if (m.size() > 1)
- m = m.substr(0, 1) + "." + m.substr(1);
+ m = makeString(m.substr(0, 1), ".", m.substr(1));
if (e >= 0)
- return jsNontrivialString(exec, s + m + "e+" + UString::from(e));
- return jsNontrivialString(exec, s + m + "e-" + UString::from(-e));
+ return jsNontrivialString(exec, makeString(s, m, "e+", UString::from(e)));
+ return jsNontrivialString(exec, makeString(s, m, "e-", UString::from(-e)));
}
} else {
m = charSequence('0', precision);
@@ -433,13 +441,13 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV
}
if (e == precision - 1)
- return jsString(exec, s + m);
+ return jsString(exec, makeString(s, m));
if (e >= 0) {
if (e + 1 < m.size())
- return jsString(exec, s + m.substr(0, e + 1) + "." + m.substr(e + 1));
- return jsString(exec, s + m);
+ return jsString(exec, makeString(s, m.substr(0, e + 1), ".", m.substr(e + 1)));
+ return jsString(exec, makeString(s, m));
}
- return jsNontrivialString(exec, s + "0." + charSequence('0', -(e + 1)) + m);
+ return jsNontrivialString(exec, makeString(s, "0.", charSequence('0', -(e + 1)), m));
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.h
index 0a3a544..1fb2077 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/NumberPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class NumberPrototype : public NumberObject {
public:
- NumberPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
+ NumberPrototype(ExecState*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure);
};
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp
index 2992f1b..0838eb4 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.cpp
@@ -36,12 +36,13 @@ ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor);
static JSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*, JSObject*, JSValue, const ArgList&);
static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*, JSObject*, JSValue, const ArgList&);
static JSValue JSC_HOST_CALL objectConstructorKeys(ExecState*, JSObject*, JSValue, const ArgList&);
static JSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*, JSObject*, JSValue, const ArgList&);
static JSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*, JSObject*, JSValue, const ArgList&);
static JSValue JSC_HOST_CALL objectConstructorCreate(ExecState*, JSObject*, JSValue, const ArgList&);
-ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> structure, ObjectPrototype* objectPrototype, Structure* prototypeFunctionStructure)
+ObjectConstructor::ObjectConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, ObjectPrototype* objectPrototype, Structure* prototypeFunctionStructure)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, "Object"))
{
// ECMA 15.2.3.1
@@ -52,6 +53,7 @@ ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> stru
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().getPrototypeOf, objectConstructorGetPrototypeOf), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().getOwnPropertyDescriptor, objectConstructorGetOwnPropertyDescriptor), DontEnum);
+ putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().getOwnPropertyNames, objectConstructorGetOwnPropertyNames), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().keys, objectConstructorKeys), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 3, exec->propertyNames().defineProperty, objectConstructorDefineProperty), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().defineProperties, objectConstructorDefineProperties), DontEnum);
@@ -125,6 +127,21 @@ JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec,
return description;
}
+// FIXME: Use the enumeration cache.
+JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+ if (!args.at(0).isObject())
+ return throwError(exec, TypeError, "Requested property names of a value that is not an object.");
+ PropertyNameArray properties(exec);
+ asObject(args.at(0))->getOwnPropertyNames(exec, properties, IncludeDontEnumProperties);
+ JSArray* names = constructEmptyArray(exec);
+ size_t numProperties = properties.size();
+ for (size_t i = 0; i < numProperties; i++)
+ names->push(exec, jsOwnedString(exec, properties[i].ustring()));
+ return names;
+}
+
+// FIXME: Use the enumeration cache.
JSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
if (!args.at(0).isObject())
@@ -147,14 +164,14 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor
}
JSObject* description = asObject(in);
- PropertySlot enumerableSlot;
+ PropertySlot enumerableSlot(description);
if (description->getPropertySlot(exec, exec->propertyNames().enumerable, enumerableSlot)) {
desc.setEnumerable(enumerableSlot.getValue(exec, exec->propertyNames().enumerable).toBoolean(exec));
if (exec->hadException())
return false;
}
- PropertySlot configurableSlot;
+ PropertySlot configurableSlot(description);
if (description->getPropertySlot(exec, exec->propertyNames().configurable, configurableSlot)) {
desc.setConfigurable(configurableSlot.getValue(exec, exec->propertyNames().configurable).toBoolean(exec));
if (exec->hadException())
@@ -162,21 +179,21 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor
}
JSValue value;
- PropertySlot valueSlot;
+ PropertySlot valueSlot(description);
if (description->getPropertySlot(exec, exec->propertyNames().value, valueSlot)) {
desc.setValue(valueSlot.getValue(exec, exec->propertyNames().value));
if (exec->hadException())
return false;
}
- PropertySlot writableSlot;
+ PropertySlot writableSlot(description);
if (description->getPropertySlot(exec, exec->propertyNames().writable, writableSlot)) {
desc.setWritable(writableSlot.getValue(exec, exec->propertyNames().writable).toBoolean(exec));
if (exec->hadException())
return false;
}
- PropertySlot getSlot;
+ PropertySlot getSlot(description);
if (description->getPropertySlot(exec, exec->propertyNames().get, getSlot)) {
JSValue get = getSlot.getValue(exec, exec->propertyNames().get);
if (exec->hadException())
@@ -192,7 +209,7 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor
desc.setGetter(get);
}
- PropertySlot setSlot;
+ PropertySlot setSlot(description);
if (description->getPropertySlot(exec, exec->propertyNames().set, setSlot)) {
JSValue set = setSlot.getValue(exec, exec->propertyNames().set);
if (exec->hadException())
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h
index 9373781..1d2cdde 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class ObjectConstructor : public InternalFunction {
public:
- ObjectConstructor(ExecState*, PassRefPtr<Structure>, ObjectPrototype*, Structure* prototypeFunctionStructure);
+ ObjectConstructor(ExecState*, NonNullPassRefPtr<Structure>, ObjectPrototype*, Structure* prototypeFunctionStructure);
private:
virtual ConstructType getConstructData(ConstructData&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp
index fccc44a..3065c6d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -40,7 +40,7 @@ static JSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState*, JSObject*,
static JSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValue, const ArgList&);
static JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValue, const ArgList&);
-ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<Structure> stucture, Structure* prototypeFunctionStructure)
+ObjectPrototype::ObjectPrototype(ExecState* exec, NonNullPassRefPtr<Structure> stucture, Structure* prototypeFunctionStructure)
: JSObject(stucture)
, m_hasNoPropertiesWithUInt32Names(true)
{
@@ -148,7 +148,7 @@ JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec, JSObject*,
JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- return jsNontrivialString(exec, "[object " + thisValue.toThisObject(exec)->className() + "]");
+ return jsNontrivialString(exec, makeString("[object ", thisValue.toThisObject(exec)->className(), "]"));
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h
index 6dd3c28..489d962 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ObjectPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class ObjectPrototype : public JSObject {
public:
- ObjectPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
+ ObjectPrototype(ExecState*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure);
private:
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.cpp
index 093bbec..0e1887c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.cpp
@@ -29,10 +29,6 @@
#include <stdio.h>
#include <wtf/MathExtras.h>
-#if HAVE(FLOAT_H)
-#include <float.h>
-#endif
-
namespace JSC {
bool JSValue::equalSlowCase(ExecState* exec, JSValue v1, JSValue v2)
@@ -40,9 +36,9 @@ bool JSValue::equalSlowCase(ExecState* exec, JSValue v1, JSValue v2)
return equalSlowCaseInline(exec, v1, v2);
}
-bool JSValue::strictEqualSlowCase(JSValue v1, JSValue v2)
+bool JSValue::strictEqualSlowCase(ExecState* exec, JSValue v1, JSValue v2)
{
- return strictEqualSlowCaseInline(v1, v2);
+ return strictEqualSlowCaseInline(exec, v1, v2);
}
NEVER_INLINE JSValue throwOutOfMemoryError(ExecState* exec)
@@ -58,12 +54,13 @@ NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
JSValue p1 = v1.toPrimitive(callFrame);
JSValue p2 = v2.toPrimitive(callFrame);
- if (p1.isString() || p2.isString()) {
- RefPtr<UString::Rep> value = concatenate(p1.toString(callFrame).rep(), p2.toString(callFrame).rep());
- if (!value)
- return throwOutOfMemoryError(callFrame);
- return jsString(callFrame, value.release());
+ if (p1.isString()) {
+ return p2.isString()
+ ? jsString(callFrame, asString(p1), asString(p2))
+ : jsString(callFrame, asString(p1), p2.toString(callFrame));
}
+ if (p2.isString())
+ return jsString(callFrame, p1.toString(callFrame), asString(p2));
return jsNumber(callFrame, p1.toNumber(callFrame) + p2.toNumber(callFrame));
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h
index 21120f5..d1d6eaa 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Operations.h
@@ -35,6 +35,136 @@ namespace JSC {
bool jsIsObjectType(JSValue);
bool jsIsFunctionType(JSValue);
+ ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
+ {
+ if (!s1->length())
+ return s2;
+ if (!s2->length())
+ return s1;
+
+ unsigned ropeLength = s1->ropeLength() + s2->ropeLength();
+ JSGlobalData* globalData = &exec->globalData();
+
+ if (ropeLength <= JSString::s_maxInternalRopeLength)
+ return new (globalData) JSString(globalData, ropeLength, s1, s2);
+
+ unsigned index = 0;
+ RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
+ if (UNLIKELY(!rope))
+ return throwOutOfMemoryError(exec);
+ rope->append(index, s1);
+ rope->append(index, s2);
+ ASSERT(index == ropeLength);
+ return new (globalData) JSString(globalData, rope.release());
+ }
+
+ ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2)
+ {
+ unsigned ropeLength = 1 + s2->ropeLength();
+ JSGlobalData* globalData = &exec->globalData();
+
+ if (ropeLength <= JSString::s_maxInternalRopeLength)
+ return new (globalData) JSString(globalData, ropeLength, u1, s2);
+
+ unsigned index = 0;
+ RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
+ if (UNLIKELY(!rope))
+ return throwOutOfMemoryError(exec);
+ rope->append(index, u1);
+ rope->append(index, s2);
+ ASSERT(index == ropeLength);
+ return new (globalData) JSString(globalData, rope.release());
+ }
+
+ ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, const UString& u2)
+ {
+ unsigned ropeLength = s1->ropeLength() + 1;
+ JSGlobalData* globalData = &exec->globalData();
+
+ if (ropeLength <= JSString::s_maxInternalRopeLength)
+ return new (globalData) JSString(globalData, ropeLength, s1, u2);
+
+ unsigned index = 0;
+ RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
+ if (UNLIKELY(!rope))
+ return throwOutOfMemoryError(exec);
+ rope->append(index, s1);
+ rope->append(index, u2);
+ ASSERT(index == ropeLength);
+ return new (globalData) JSString(globalData, rope.release());
+ }
+
+ ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
+ {
+ ASSERT(count >= 3);
+
+ unsigned ropeLength = 0;
+ for (unsigned i = 0; i < count; ++i) {
+ JSValue v = strings[i].jsValue();
+ if (LIKELY(v.isString()))
+ ropeLength += asString(v)->ropeLength();
+ else
+ ++ropeLength;
+ }
+
+ JSGlobalData* globalData = &exec->globalData();
+ if (ropeLength == 3)
+ return new (globalData) JSString(exec, strings[0].jsValue(), strings[1].jsValue(), strings[2].jsValue());
+
+ RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
+ if (UNLIKELY(!rope))
+ return throwOutOfMemoryError(exec);
+
+ unsigned index = 0;
+ for (unsigned i = 0; i < count; ++i) {
+ JSValue v = strings[i].jsValue();
+ if (LIKELY(v.isString()))
+ rope->append(index, asString(v));
+ else
+ rope->append(index, v.toString(exec));
+ }
+
+ ASSERT(index == ropeLength);
+ return new (globalData) JSString(globalData, rope.release());
+ }
+
+ ALWAYS_INLINE JSValue jsString(ExecState* exec, JSValue thisValue, const ArgList& args)
+ {
+ unsigned ropeLength = 0;
+ if (LIKELY(thisValue.isString()))
+ ropeLength += asString(thisValue)->ropeLength();
+ else
+ ++ropeLength;
+ for (unsigned i = 0; i < args.size(); ++i) {
+ JSValue v = args.at(i);
+ if (LIKELY(v.isString()))
+ ropeLength += asString(v)->ropeLength();
+ else
+ ++ropeLength;
+ }
+
+ RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
+ if (UNLIKELY(!rope))
+ return throwOutOfMemoryError(exec);
+
+ unsigned index = 0;
+ if (LIKELY(thisValue.isString()))
+ rope->append(index, asString(thisValue));
+ else
+ rope->append(index, thisValue.toString(exec));
+ for (unsigned i = 0; i < args.size(); ++i) {
+ JSValue v = args.at(i);
+ if (LIKELY(v.isString()))
+ rope->append(index, asString(v));
+ else
+ rope->append(index, v.toString(exec));
+ }
+ ASSERT(index == ropeLength);
+
+ JSGlobalData* globalData = &exec->globalData();
+ return new (globalData) JSString(globalData, rope.release());
+ }
+
// ECMA 11.9.3
inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
{
@@ -53,7 +183,7 @@ namespace JSC {
bool s1 = v1.isString();
bool s2 = v2.isString();
if (s1 && s2)
- return asString(v1)->value() == asString(v2)->value();
+ return asString(v1)->value(exec) == asString(v2)->value(exec);
if (v1.isUndefinedOrNull()) {
if (v2.isUndefinedOrNull())
@@ -70,13 +200,12 @@ namespace JSC {
}
if (v1.isObject()) {
- if (v2.isObject()) {
+ if (v2.isObject())
return v1 == v2
#ifdef QT_BUILD_SCRIPT_LIB
|| asObject(v1)->compareToObject(exec, asObject(v2))
#endif
;
- }
JSValue p1 = v1.toPrimitive(exec);
if (exec->hadException())
return false;
@@ -115,17 +244,17 @@ namespace JSC {
}
// ECMA 11.9.3
- ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(JSValue v1, JSValue v2)
+ ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
{
ASSERT(v1.isCell() && v2.isCell());
if (v1.asCell()->isString() && v2.asCell()->isString())
- return asString(v1)->value() == asString(v2)->value();
+ return asString(v1)->value(exec) == asString(v2)->value(exec);
return v1 == v2;
}
- inline bool JSValue::strictEqual(JSValue v1, JSValue v2)
+ inline bool JSValue::strictEqual(ExecState* exec, JSValue v1, JSValue v2)
{
if (v1.isInt32() && v2.isInt32())
return v1 == v2;
@@ -136,10 +265,10 @@ namespace JSC {
if (!v1.isCell() || !v2.isCell())
return v1 == v2;
- return strictEqualSlowCaseInline(v1, v2);
+ return strictEqualSlowCaseInline(exec, v1, v2);
}
- inline bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2)
+ ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2)
{
if (v1.isInt32() && v2.isInt32())
return v1.asInt32() < v2.asInt32();
@@ -151,7 +280,7 @@ namespace JSC {
JSGlobalData* globalData = &callFrame->globalData();
if (isJSString(globalData, v1) && isJSString(globalData, v2))
- return asString(v1)->value() < asString(v2)->value();
+ return asString(v1)->value(callFrame) < asString(v2)->value(callFrame);
JSValue p1;
JSValue p2;
@@ -161,7 +290,7 @@ namespace JSC {
if (wasNotString1 | wasNotString2)
return n1 < n2;
- return asString(p1)->value() < asString(p2)->value();
+ return asString(p1)->value(callFrame) < asString(p2)->value(callFrame);
}
inline bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2)
@@ -176,7 +305,7 @@ namespace JSC {
JSGlobalData* globalData = &callFrame->globalData();
if (isJSString(globalData, v1) && isJSString(globalData, v2))
- return !(asString(v2)->value() < asString(v1)->value());
+ return !(asString(v2)->value(callFrame) < asString(v1)->value(callFrame));
JSValue p1;
JSValue p2;
@@ -186,7 +315,7 @@ namespace JSC {
if (wasNotString1 | wasNotString2)
return n1 <= n2;
- return !(asString(p2)->value() < asString(p1)->value());
+ return !(asString(p2)->value(callFrame) < asString(p1)->value(callFrame));
}
// Fast-path choices here are based on frequency data from SunSpider:
@@ -200,44 +329,29 @@ namespace JSC {
ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
{
- double left;
- double right = 0.0;
-
- bool rightIsNumber = v2.getNumber(right);
- if (rightIsNumber && v1.getNumber(left))
+ double left = 0.0, right;
+ if (v1.getNumber(left) && v2.getNumber(right))
return jsNumber(callFrame, left + right);
- bool leftIsString = v1.isString();
- if (leftIsString && v2.isString()) {
- RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
- if (!value)
- return throwOutOfMemoryError(callFrame);
- return jsString(callFrame, value.release());
- }
-
- if (rightIsNumber & leftIsString) {
- RefPtr<UString::Rep> value = v2.isInt32() ?
- concatenate(asString(v1)->value().rep(), v2.asInt32()) :
- concatenate(asString(v1)->value().rep(), right);
-
- if (!value)
- return throwOutOfMemoryError(callFrame);
- return jsString(callFrame, value.release());
+ if (v1.isString()) {
+ return v2.isString()
+ ? jsString(callFrame, asString(v1), asString(v2))
+ : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame));
}
// All other cases are pretty uncommon
return jsAddSlowCase(callFrame, v1, v2);
}
- inline size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValue baseValue, const PropertySlot& slot)
+ inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, size_t& slotOffset)
{
- JSCell* cell = asCell(baseValue);
+ JSCell* cell = asCell(base);
size_t count = 0;
- while (slot.slotBase() != cell) {
+ while (slotBase != cell) {
JSValue v = cell->structure()->prototypeForLookup(callFrame);
- // If we didn't find slotBase in baseValue's prototype chain, then baseValue
+ // If we didn't find slotBase in base's prototype chain, then base
// must be a proxy for another object.
if (v.isNull())
@@ -247,8 +361,11 @@ namespace JSC {
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
- if (cell->structure()->isDictionary())
- asObject(cell)->setStructure(Structure::fromDictionaryTransition(cell->structure()));
+ if (cell->structure()->isDictionary()) {
+ asObject(cell)->flattenDictionaryObject();
+ if (slotBase == cell)
+ slotOffset = cell->structure()->get(propertyName);
+ }
++count;
}
@@ -257,6 +374,25 @@ namespace JSC {
return count;
}
+ inline size_t normalizePrototypeChain(CallFrame* callFrame, JSCell* base)
+ {
+ size_t count = 0;
+ while (1) {
+ JSValue v = base->structure()->prototypeForLookup(callFrame);
+ if (v.isNull())
+ return count;
+
+ base = 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 (base->structure()->isDictionary())
+ asObject(base)->flattenDictionaryObject();
+
+ ++count;
+ }
+ }
+
ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
{
ScopeChainIterator iter = scopeChain->begin();
@@ -279,52 +415,6 @@ namespace JSC {
ASSERT_NOT_REACHED();
return JSValue();
}
-
- ALWAYS_INLINE JSValue concatenateStrings(CallFrame* callFrame, Register* strings, unsigned count)
- {
- ASSERT(count >= 3);
-
- // Estimate the amount of space required to hold the entire string. If all
- // arguments are strings, we can easily calculate the exact amount of space
- // required. For any other arguments, for now let's assume they may require
- // 11 UChars of storage. This is enouch to hold any int, and likely is also
- // reasonable for the other immediates. We may want to come back and tune
- // this value at some point.
- unsigned bufferSize = 0;
- for (unsigned i = 0; i < count; ++i) {
- JSValue v = strings[i].jsValue();
- if (LIKELY(v.isString()))
- bufferSize += asString(v)->value().size();
- else
- bufferSize += 11;
- }
-
- // Allocate an output string to store the result.
- // If the first argument is a String, and if it has the capacity (or can grow
- // its capacity) to hold the entire result then use this as a base to concatenate
- // onto. Otherwise, allocate a new empty output buffer.
- JSValue firstValue = strings[0].jsValue();
- RefPtr<UString::Rep> resultRep;
- if (firstValue.isString() && (resultRep = asString(firstValue)->value().rep())->reserveCapacity(bufferSize)) {
- // We're going to concatenate onto the first string - remove it from the list of items to be appended.
- ++strings;
- --count;
- } else
- resultRep = UString::Rep::createEmptyBuffer(bufferSize);
- UString result(resultRep);
-
- // Loop over the operands, writing them into the output buffer.
- for (unsigned i = 0; i < count; ++i) {
- JSValue v = strings[i].jsValue();
- if (LIKELY(v.isString()))
- result.append(asString(v)->value());
- else
- result.append(v.toString(callFrame));
- }
-
- return jsString(callFrame, result);
- }
-
} // namespace JSC
#endif // Operations_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.cpp
index 4db814f..558ae28 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.cpp
@@ -153,15 +153,15 @@ void PropertyDescriptor::setGetter(JSValue getter)
m_attributes &= ~ReadOnly;
}
-bool PropertyDescriptor::equalTo(const PropertyDescriptor& other) const
+bool PropertyDescriptor::equalTo(ExecState* exec, const PropertyDescriptor& other) const
{
if (!other.m_value == m_value ||
!other.m_getter == m_getter ||
!other.m_setter == m_setter)
return false;
- return (!m_value || JSValue::strictEqual(other.m_value, m_value)) &&
- (!m_getter || JSValue::strictEqual(other.m_getter, m_getter)) &&
- (!m_setter || JSValue::strictEqual(other.m_setter, m_setter)) &&
+ return (!m_value || JSValue::strictEqual(exec, other.m_value, m_value)) &&
+ (!m_getter || JSValue::strictEqual(exec, other.m_getter, m_getter)) &&
+ (!m_setter || JSValue::strictEqual(exec, other.m_setter, m_setter)) &&
attributesEqual(other);
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.h
index 40bec86..ff9f160 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyDescriptor.h
@@ -61,7 +61,7 @@ namespace JSC {
bool configurablePresent() const { return m_seenAttributes & ConfigurablePresent; }
bool setterPresent() const { return m_setter; }
bool getterPresent() const { return m_getter; }
- bool equalTo(const PropertyDescriptor& other) const;
+ bool equalTo(ExecState* exec, const PropertyDescriptor& other) const;
bool attributesEqual(const PropertyDescriptor& other) const;
unsigned attributesWithOverride(const PropertyDescriptor& other) const;
private:
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.cpp
index 0878e73..5108272 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.cpp
@@ -21,13 +21,16 @@
#include "config.h"
#include "PropertyNameArray.h"
+#include "Structure.h"
+#include "StructureChain.h"
+
namespace JSC {
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->isIdentifier());
size_t size = m_data->propertyNameVector().size();
if (size < setThreshold) {
@@ -44,7 +47,7 @@ void PropertyNameArray::add(UString::Rep* identifier)
return;
}
- m_data->propertyNameVector().append(Identifier(m_globalData, identifier));
+ addKnownUnique(identifier);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.h
index 67ee9c8..3dbcc9d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PropertyNameArray.h
@@ -23,46 +23,35 @@
#include "CallFrame.h"
#include "Identifier.h"
-#include "Structure.h"
-#include "StructureChain.h"
#include <wtf/HashSet.h>
+#include <wtf/OwnArrayPtr.h>
#include <wtf/Vector.h>
namespace JSC {
+
+ class Structure;
+ class StructureChain;
+ // FIXME: Rename to PropertyNameArray.
class PropertyNameArrayData : public RefCounted<PropertyNameArrayData> {
public:
typedef Vector<Identifier, 20> PropertyNameVector;
- typedef PropertyNameVector::const_iterator const_iterator;
static PassRefPtr<PropertyNameArrayData> create() { return adoptRef(new PropertyNameArrayData); }
- const_iterator begin() const { return m_propertyNameVector.begin(); }
- const_iterator end() const { return m_propertyNameVector.end(); }
-
PropertyNameVector& propertyNameVector() { return m_propertyNameVector; }
- void setCachedStructure(Structure* structure) { m_cachedStructure = structure; }
- Structure* cachedStructure() const { return m_cachedStructure; }
-
- void setCachedPrototypeChain(PassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
- StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
-
private:
PropertyNameArrayData()
- : m_cachedStructure(0)
{
}
PropertyNameVector m_propertyNameVector;
- Structure* m_cachedStructure;
- RefPtr<StructureChain> m_cachedPrototypeChain;
};
+ // FIXME: Rename to PropertyNameArrayBuilder.
class PropertyNameArray {
public:
- typedef PropertyNameArrayData::const_iterator const_iterator;
-
PropertyNameArray(JSGlobalData* globalData)
: m_data(PropertyNameArrayData::create())
, m_globalData(globalData)
@@ -83,21 +72,18 @@ namespace JSC {
void add(UString::Rep*);
void addKnownUnique(UString::Rep* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); }
- size_t size() const { return m_data->propertyNameVector().size(); }
-
Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; }
const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; }
- const_iterator begin() const { return m_data->begin(); }
- const_iterator end() const { return m_data->end(); }
-
void setData(PassRefPtr<PropertyNameArrayData> data) { m_data = data; }
PropertyNameArrayData* data() { return m_data.get(); }
-
PassRefPtr<PropertyNameArrayData> releaseData() { return m_data.release(); }
- void setShouldCache(bool shouldCache) { m_shouldCache = shouldCache; }
- bool shouldCache() const { return m_shouldCache; }
+ // FIXME: Remove these functions.
+ typedef PropertyNameArrayData::PropertyNameVector::const_iterator const_iterator;
+ size_t size() const { return m_data->propertyNameVector().size(); }
+ const_iterator begin() const { return m_data->propertyNameVector().begin(); }
+ const_iterator end() const { return m_data->propertyNameVector().end(); }
private:
typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Protect.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Protect.h
index 6e7984c..c2d7f0c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Protect.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Protect.h
@@ -22,8 +22,8 @@
#ifndef Protect_h
#define Protect_h
-#include "JSCell.h"
#include "Collector.h"
+#include "JSValue.h"
namespace JSC {
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.cpp
index 8e3d107..38f8adb 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.cpp
+++ b/src/3rdparty/javascriptcore/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<Structure> prototypeFunctionStructure, int length, const Identifier& name, NativeFunction function)
+PrototypeFunction::PrototypeFunction(ExecState* exec, NonNullPassRefPtr<Structure> prototypeFunctionStructure, int length, const Identifier& name, NativeFunction function)
: InternalFunction(&exec->globalData(), prototypeFunctionStructure, name)
, m_function(function)
{
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.h
index 99ab327..70ee034 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/PrototypeFunction.h
+++ b/src/3rdparty/javascriptcore/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<Structure>, int length, const Identifier&, NativeFunction);
+ PrototypeFunction(ExecState*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
private:
virtual CallType getCallData(CallData&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.cpp
index b366b58..430a5c0 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.cpp
@@ -65,7 +65,6 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags)
: m_pattern(pattern)
- , m_flags(flags)
, m_flagBits(0)
, m_constructionError(0)
, m_numSubpatterns(0)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.h
index 24d4199..61ab0bc 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExp.h
@@ -49,7 +49,6 @@ namespace JSC {
bool multiline() const { return m_flagBits & Multiline; }
const UString& pattern() const { return m_pattern; }
- const UString& flags() const { return m_flags; }
bool isValid() const { return !m_constructionError; }
const char* errorMessage() const { return m_constructionError; }
@@ -66,7 +65,6 @@ namespace JSC {
enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 };
UString m_pattern; // FIXME: Just decompile m_regExp instead of storing this.
- UString m_flags; // FIXME: Just decompile m_regExp instead of storing this.
int m_flagBits;
const char* m_constructionError;
unsigned m_numSubpatterns;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp
index 1c95175..6f00142 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -90,29 +90,7 @@ const ClassInfo RegExpConstructor::info = { "Function", &InternalFunction::info,
@end
*/
-struct RegExpConstructorPrivate : FastAllocBase {
- // Global search cache / settings
- RegExpConstructorPrivate()
- : lastNumSubPatterns(0)
- , multiline(false)
- , lastOvectorIndex(0)
- {
- }
-
- const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; }
- Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; }
- Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; }
- void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; }
-
- UString input;
- UString lastInput;
- Vector<int, 32> ovector[2];
- unsigned lastNumSubPatterns : 30;
- bool multiline : 1;
- unsigned lastOvectorIndex : 1;
-};
-
-RegExpConstructor::RegExpConstructor(ExecState* exec, PassRefPtr<Structure> structure, RegExpPrototype* regExpPrototype)
+RegExpConstructor::RegExpConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, RegExpPrototype* regExpPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, "RegExp"))
, d(new RegExpConstructorPrivate)
{
@@ -123,30 +101,6 @@ RegExpConstructor::RegExpConstructor(ExecState* exec, PassRefPtr<Structure> stru
putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly | DontDelete | DontEnum);
}
-/*
- To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
- expression matching through the performMatch function. We use cached results to calculate,
- e.g., RegExp.lastMatch and RegExp.leftParen.
-*/
-void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector)
-{
- position = r->match(s, startOffset, &d->tempOvector());
-
- if (ovector)
- *ovector = d->tempOvector().data();
-
- if (position != -1) {
- ASSERT(!d->tempOvector().isEmpty());
-
- length = d->tempOvector()[1] - d->tempOvector()[0];
-
- d->input = s;
- d->lastInput = s;
- d->changeLastOvector();
- d->lastNumSubPatterns = r->numSubpatterns();
- }
-}
-
RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data)
: JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1)
{
@@ -178,6 +132,8 @@ void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
int start = d->lastOvector()[2 * i];
if (start >= 0)
JSArray::put(exec, i, jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start));
+ else
+ JSArray::put(exec, i, jsUndefined());
}
PutPropertySlot slot;
@@ -346,7 +302,7 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args)
RefPtr<RegExp> regExp = RegExp::create(&exec->globalData(), pattern, flags);
if (!regExp->isValid())
- return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
+ return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage()));
return new (exec) RegExpObject(exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h
index 4b06b51..f9ca9cf 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpConstructor.h
@@ -22,6 +22,7 @@
#define RegExpConstructor_h
#include "InternalFunction.h"
+#include "RegExp.h"
#include <wtf/OwnPtr.h>
namespace JSC {
@@ -30,13 +31,35 @@ namespace JSC {
class RegExpPrototype;
struct RegExpConstructorPrivate;
+ struct RegExpConstructorPrivate : FastAllocBase {
+ // Global search cache / settings
+ RegExpConstructorPrivate()
+ : lastNumSubPatterns(0)
+ , multiline(false)
+ , lastOvectorIndex(0)
+ {
+ }
+
+ const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; }
+ Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; }
+ Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; }
+ void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; }
+
+ UString input;
+ UString lastInput;
+ Vector<int, 32> ovector[2];
+ unsigned lastNumSubPatterns : 30;
+ bool multiline : 1;
+ unsigned lastOvectorIndex : 1;
+ };
+
class RegExpConstructor : public InternalFunction {
public:
- RegExpConstructor(ExecState*, PassRefPtr<Structure>, RegExpPrototype*);
+ RegExpConstructor(ExecState*, NonNullPassRefPtr<Structure>, RegExpPrototype*);
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance | HasDefaultMark | HasDefaultGetPropertyNames));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
@@ -59,6 +82,9 @@ namespace JSC {
JSValue getLeftContext(ExecState*) const;
JSValue getRightContext(ExecState*) const;
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags;
+
private:
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
@@ -78,6 +104,30 @@ namespace JSC {
return static_cast<RegExpConstructor*>(asObject(value));
}
+ /*
+ To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
+ expression matching through the performMatch function. We use cached results to calculate,
+ e.g., RegExp.lastMatch and RegExp.leftParen.
+ */
+ inline void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector)
+ {
+ position = r->match(s, startOffset, &d->tempOvector());
+
+ if (ovector)
+ *ovector = d->tempOvector().data();
+
+ if (position != -1) {
+ ASSERT(!d->tempOvector().isEmpty());
+
+ length = d->tempOvector()[1] - d->tempOvector()[0];
+
+ d->input = s;
+ d->lastInput = s;
+ d->changeLastOvector();
+ d->lastNumSubPatterns = r->numSubpatterns();
+ }
+ }
+
} // namespace JSC
#endif // RegExpConstructor_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h
index c1a5a25..38d3cb4 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpMatchesArray.h
@@ -65,25 +65,25 @@ namespace JSC {
JSArray::put(exec, propertyName, v);
}
- virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete = true)
+ virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName)
{
if (lazyCreationData())
fillArrayInstance(exec);
- return JSArray::deleteProperty(exec, propertyName, checkDontDelete);
+ return JSArray::deleteProperty(exec, propertyName);
}
- virtual bool deleteProperty(ExecState* exec, unsigned propertyName, bool checkDontDelete = true)
+ virtual bool deleteProperty(ExecState* exec, unsigned propertyName)
{
if (lazyCreationData())
fillArrayInstance(exec);
- return JSArray::deleteProperty(exec, propertyName, checkDontDelete);
+ return JSArray::deleteProperty(exec, propertyName);
}
- virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr, bool includeNonEnumerable = false)
+ virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
{
if (lazyCreationData())
fillArrayInstance(exec);
- JSArray::getOwnPropertyNames(exec, arr, includeNonEnumerable);
+ JSArray::getOwnPropertyNames(exec, arr, mode);
}
void fillArrayInstance(ExecState*);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp
index 9d9dd7d..42bfcef 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.cpp
@@ -57,7 +57,7 @@ const ClassInfo RegExpObject::info = { "RegExp", 0, 0, ExecState::regExpTable };
@end
*/
-RegExpObject::RegExpObject(PassRefPtr<Structure> structure, PassRefPtr<RegExp> regExp)
+RegExpObject::RegExpObject(NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<RegExp> regExp)
: JSObject(structure)
, d(new RegExpObjectData(regExp, 0))
{
@@ -142,7 +142,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args)
UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec);
if (input.isNull()) {
- throwError(exec, GeneralError, "No input to " + toString(exec) + ".");
+ throwError(exec, GeneralError, makeString("No input to ", toString(exec), "."));
return false;
}
@@ -159,7 +159,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args)
}
int position;
- int length;
+ int length = 0;
regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length);
if (position < 0) {
d->lastIndex = 0;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h
index 67113b6..3117c86 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpObject.h
@@ -28,7 +28,7 @@ namespace JSC {
class RegExpObject : public JSObject {
public:
- RegExpObject(PassRefPtr<Structure>, PassRefPtr<RegExp>);
+ RegExpObject(NonNullPassRefPtr<Structure>, NonNullPassRefPtr<RegExp>);
virtual ~RegExpObject();
void setRegExp(PassRefPtr<RegExp> r) { d->regExp = r; }
@@ -49,16 +49,19 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType, HasDefaultMark | HasDefaultGetPropertyNames));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
+ protected:
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
+
private:
bool match(ExecState*, const ArgList&);
virtual CallType getCallData(CallData&);
struct RegExpObjectData : FastAllocBase {
- RegExpObjectData(PassRefPtr<RegExp> regExp, double lastIndex)
+ RegExpObjectData(NonNullPassRefPtr<RegExp> regExp, double lastIndex)
: regExp(regExp)
, lastIndex(lastIndex)
{
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp
index 4714171..5f9d357 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -46,7 +46,7 @@ static JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*, JSObject*, JSVa
const ClassInfo RegExpPrototype::info = { "RegExpPrototype", 0, 0, 0 };
-RegExpPrototype::RegExpPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
+RegExpPrototype::RegExpPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
: JSObject(structure)
{
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
@@ -91,7 +91,7 @@ JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue
}
if (!regExp->isValid())
- return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
+ return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage()));
asRegExpObject(thisValue)->setRegExp(regExp.release());
asRegExpObject(thisValue)->setLastIndex(0);
@@ -106,19 +106,17 @@ JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValu
return throwError(exec, TypeError);
}
- UString result = "/" + asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
-#ifdef QT_BUILD_SCRIPT_LIB
- if (result.size() == 1)
- result.append("(?:)");
-#endif
- result.append('/');
+ char postfix[5] = { '/', 0, 0, 0, 0 };
+ int index = 1;
if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec))
- result.append('g');
+ postfix[index++] = 'g';
if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
- result.append('i');
+ postfix[index++] = 'i';
if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec))
- result.append('m');
- return jsNontrivialString(exec, result);
+ postfix[index] = 'm';
+ UString source = asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
+ // If source is empty, use "/(?:)/" to avoid colliding with comment syntax
+ return jsNontrivialString(exec, makeString("/", source.size() ? source : UString("(?:)"), postfix));
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.h
index f5db720..d3979bd 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/RegExpPrototype.h
@@ -27,7 +27,7 @@ namespace JSC {
class RegExpPrototype : public JSObject {
public:
- RegExpPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
+ RegExpPrototype(ExecState*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure);
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp
index 960c525..981794b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.cpp
@@ -36,8 +36,8 @@ void ScopeChainNode::print() const
ScopeChainIterator scopeEnd = end();
for (ScopeChainIterator scopeIter = begin(); scopeIter != scopeEnd; ++scopeIter) {
JSObject* o = *scopeIter;
- PropertyNameArray propertyNames(globalObject()->globalExec());
- o->getPropertyNames(globalObject()->globalExec(), propertyNames);
+ PropertyNameArray propertyNames(globalObject->globalExec());
+ o->getPropertyNames(globalObject->globalExec(), propertyNames);
PropertyNameArray::const_iterator propEnd = propertyNames.end();
fprintf(stderr, "----- [scope %p] -----\n", o);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h
index c5e16c9..0b15b67 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/ScopeChain.h
@@ -33,14 +33,16 @@ namespace JSC {
class ScopeChainNode : public FastAllocBase {
public:
- ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSObject* globalThis)
+ ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
: next(next)
, object(object)
, globalData(globalData)
+ , globalObject(globalObject)
, globalThis(globalThis)
, refCount(1)
{
ASSERT(globalData);
+ ASSERT(globalObject);
}
#ifndef NDEBUG
// Due to the number of subtle and timing dependent bugs that have occurred due
@@ -51,6 +53,7 @@ namespace JSC {
next = 0;
object = 0;
globalData = 0;
+ globalObject = 0;
globalThis = 0;
}
#endif
@@ -58,6 +61,7 @@ namespace JSC {
ScopeChainNode* next;
JSObject* object;
JSGlobalData* globalData;
+ JSGlobalObject* globalObject;
JSObject* globalThis;
int refCount;
@@ -82,9 +86,6 @@ namespace JSC {
ScopeChainIterator begin() const;
ScopeChainIterator end() const;
- JSGlobalObject* globalObject() const; // defined in JSGlobalObject.h
- JSObject* globalThisObject() const { return globalThis; }
-
#ifndef NDEBUG
void print() const;
#endif
@@ -93,7 +94,7 @@ namespace JSC {
inline ScopeChainNode* ScopeChainNode::push(JSObject* o)
{
ASSERT(o);
- return new ScopeChainNode(this, o, globalData, globalThis);
+ return new ScopeChainNode(this, o, globalData, globalObject, globalThis);
}
inline ScopeChainNode* ScopeChainNode::pop()
@@ -163,8 +164,8 @@ namespace JSC {
{
}
- ScopeChain(JSObject* o, JSGlobalData* globalData, JSObject* globalThis)
- : m_node(new ScopeChainNode(0, o, globalData, globalThis))
+ ScopeChain(JSObject* o, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis)
+ : m_node(new ScopeChainNode(0, o, globalData, globalObject, globalThis))
{
}
@@ -203,7 +204,7 @@ namespace JSC {
void pop() { m_node = m_node->pop(); }
void clear() { m_node->deref(); m_node = 0; }
- JSGlobalObject* globalObject() const { return m_node->globalObject(); }
+ JSGlobalObject* globalObject() const { return m_node->globalObject; }
void markAggregate(MarkStack&) const;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp
index 04701cb..ac71735 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/SmallStrings.cpp
@@ -41,30 +41,16 @@ public:
UString::Rep* rep(unsigned char character) { return &m_reps[character]; }
private:
- UChar m_characters[numCharactersToStore];
- UString::BaseString m_base;
UString::Rep m_reps[numCharactersToStore];
};
SmallStringsStorage::SmallStringsStorage()
- : m_base(m_characters, numCharactersToStore)
{
- m_base.rc = numCharactersToStore + 1;
- // make sure UString doesn't try to reuse the buffer by pretending we have one more character in it
- m_base.usedCapacity = numCharactersToStore + 1;
- m_base.capacity = numCharactersToStore + 1;
- m_base.checkConsistency();
-
- for (unsigned i = 0; i < numCharactersToStore; ++i)
- m_characters[i] = i;
-
- memset(&m_reps, 0, sizeof(m_reps));
+ UChar* characterBuffer = 0;
+ RefPtr<UStringImpl> baseString = UStringImpl::createUninitialized(numCharactersToStore, characterBuffer);
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();
+ characterBuffer[i] = i;
+ new (&m_reps[i]) UString::Rep(&characterBuffer[i], 1, PassRefPtr<UStringImpl>(baseString));
}
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringBuilder.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringBuilder.h
new file mode 100644
index 0000000..8e18d37
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringBuilder.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 StringBuilder_h
+#define StringBuilder_h
+
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class StringBuilder {
+public:
+ void append(const UChar u)
+ {
+ buffer.append(u);
+ }
+
+ void append(const char* str)
+ {
+ buffer.append(str, strlen(str));
+ }
+
+ void append(const char* str, size_t len)
+ {
+ buffer.reserveCapacity(buffer.size() + len);
+ for (size_t i = 0; i < len; i++)
+ buffer.append(static_cast<unsigned char>(str[i]));
+ }
+
+ void append(const UChar* str, size_t len)
+ {
+ buffer.append(str, len);
+ }
+
+ void append(const UString& str)
+ {
+ buffer.append(str.data(), str.size());
+ }
+
+ bool isEmpty() { return buffer.isEmpty(); }
+ void reserveCapacity(size_t newCapacity) { buffer.reserveCapacity(newCapacity); }
+ void resize(size_t size) { buffer.resize(size); }
+ size_t size() const { return buffer.size(); }
+
+ UChar operator[](size_t i) const { return buffer.at(i); }
+
+ UString release()
+ {
+ buffer.shrinkToFit();
+ return UString::adopt(buffer);
+ }
+
+private:
+ Vector<UChar, 64> buffer;
+};
+
+}
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.cpp
index 6380445..c7b62bf 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.cpp
@@ -30,12 +30,12 @@ namespace JSC {
static NEVER_INLINE JSValue stringFromCharCodeSlowCase(ExecState* exec, const ArgList& args)
{
- UChar* buf = static_cast<UChar*>(fastMalloc(args.size() * sizeof(UChar)));
- UChar* p = buf;
- ArgList::const_iterator end = args.end();
- for (ArgList::const_iterator it = args.begin(); it != end; ++it)
- *p++ = static_cast<UChar>((*it).toUInt32(exec));
- return jsString(exec, UString(buf, p - buf, false));
+ unsigned length = args.size();
+ UChar* buf;
+ PassRefPtr<UStringImpl> impl = UStringImpl::createUninitialized(length, buf);
+ for (unsigned i = 0; i < length; ++i)
+ buf[i] = static_cast<UChar>(args.at(i).toUInt32(exec));
+ return jsString(exec, impl);
}
static JSValue JSC_HOST_CALL stringFromCharCode(ExecState* exec, JSObject*, JSValue, const ArgList& args)
@@ -47,7 +47,7 @@ static JSValue JSC_HOST_CALL stringFromCharCode(ExecState* exec, JSObject*, JSVa
ASSERT_CLASS_FITS_IN_CELL(StringConstructor);
-StringConstructor::StringConstructor(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, StringPrototype* stringPrototype)
+StringConstructor::StringConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, StringPrototype* stringPrototype)
: InternalFunction(&exec->globalData(), structure, Identifier(exec, stringPrototype->classInfo()->className))
{
// ECMA 15.5.3.1 String.prototype
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.h
index 7d52c69..e511f7b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringConstructor.h
@@ -29,7 +29,7 @@ namespace JSC {
class StringConstructor : public InternalFunction {
public:
- StringConstructor(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure, StringPrototype*);
+ StringConstructor(ExecState*, NonNullPassRefPtr<Structure>, Structure* prototypeFunctionStructure, StringPrototype*);
virtual ConstructType getConstructData(ConstructData&);
virtual CallType getCallData(CallData&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp
index dd1ac5d..f8e0e87 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.cpp
+++ b/src/3rdparty/javascriptcore/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<Structure> structure)
+StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure)
: JSWrapperObject(structure)
{
setInternalValue(jsEmptyString(exec));
}
-StringObject::StringObject(PassRefPtr<Structure> structure, JSString* string)
+StringObject::StringObject(NonNullPassRefPtr<Structure> structure, JSString* string)
: JSWrapperObject(structure)
{
setInternalValue(string);
}
-StringObject::StringObject(ExecState* exec, PassRefPtr<Structure> structure, const UString& string)
+StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& string)
: JSWrapperObject(structure)
{
setInternalValue(jsString(exec, string));
@@ -75,7 +75,7 @@ void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue
JSObject::put(exec, propertyName, value, slot);
}
-bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyName, bool checkDontDelete)
+bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
if (propertyName == exec->propertyNames().length)
return false;
@@ -83,15 +83,17 @@ bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyNam
unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
if (isStrictUInt32 && internalValue()->canGetIndex(i))
return false;
- return JSObject::deleteProperty(exec, propertyName, checkDontDelete);
+ return JSObject::deleteProperty(exec, propertyName);
}
-void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, bool includeNonEnumerable)
+void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
- int size = internalValue()->value().size();
+ int size = internalValue()->length();
for (int i = 0; i < size; ++i)
propertyNames.add(Identifier(exec, UString::from(i)));
- return JSObject::getOwnPropertyNames(exec, propertyNames);
+ if (mode == IncludeDontEnumProperties)
+ propertyNames.add(exec->propertyNames().length);
+ return JSObject::getOwnPropertyNames(exec, propertyNames, mode);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h
index 2f5927a..b720b90 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObject.h
@@ -28,8 +28,8 @@ namespace JSC {
class StringObject : public JSWrapperObject {
public:
- StringObject(ExecState*, PassRefPtr<Structure>);
- StringObject(ExecState*, PassRefPtr<Structure>, const UString&);
+ StringObject(ExecState*, NonNullPassRefPtr<Structure>);
+ StringObject(ExecState*, NonNullPassRefPtr<Structure>, const UString&);
static StringObject* create(ExecState*, JSString*);
@@ -38,8 +38,8 @@ namespace JSC {
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
virtual void put(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&);
- virtual bool deleteProperty(ExecState*, const Identifier& propertyName, bool checkDontDelete = true);
- virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, bool includeNonEnumerable = false);
+ virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+ virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual const ClassInfo* classInfo() const { return &info; }
static const JS_EXPORTDATA ClassInfo info;
@@ -48,11 +48,12 @@ namespace JSC {
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
- return Structure::create(prototype, TypeInfo(ObjectType));
+ return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags));
}
protected:
- StringObject(PassRefPtr<Structure>, JSString*);
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
+ StringObject(NonNullPassRefPtr<Structure>, JSString*);
};
StringObject* asStringObject(JSValue);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
index 1d2e03f..69e1939 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h
@@ -37,16 +37,18 @@ namespace JSC {
}
private:
- StringObjectThatMasqueradesAsUndefined(ExecState* exec, PassRefPtr<Structure> structure, const UString& string)
+ StringObjectThatMasqueradesAsUndefined(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& string)
: StringObject(exec, structure, string)
{
}
static PassRefPtr<Structure> createStructure(JSValue proto)
{
- return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined | HasDefaultMark));
+ return Structure::create(proto, TypeInfo(ObjectType, StructureFlags));
}
+ static const unsigned StructureFlags = OverridesGetOwnPropertySlot | MasqueradesAsUndefined | OverridesGetPropertyNames | StringObject::StructureFlags;
+
virtual bool toBoolean(ExecState*) const { return false; }
};
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp
index c9a32b6..d002e07 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.cpp
@@ -25,9 +25,11 @@
#include "CachedCall.h"
#include "Error.h"
#include "Executable.h"
+#include "JSGlobalObjectFunctions.h"
#include "JSArray.h"
#include "JSFunction.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#include "PropertyNameArray.h"
#include "RegExpConstructor.h"
#include "RegExpObject.h"
@@ -72,6 +74,10 @@ static JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState*, JSObject*, JSVa
static JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState*, JSObject*, JSValue, const ArgList&);
static JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState*, JSObject*, JSValue, const ArgList&);
+
}
#include "StringPrototype.lut.h"
@@ -117,11 +123,14 @@ const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, Exec
fontsize stringProtoFuncFontsize DontEnum|Function 1
anchor stringProtoFuncAnchor DontEnum|Function 1
link stringProtoFuncLink DontEnum|Function 1
+ trim stringProtoFuncTrim DontEnum|Function 0
+ trimLeft stringProtoFuncTrimLeft DontEnum|Function 0
+ trimRight stringProtoFuncTrimRight DontEnum|Function 0
@end
*/
// ECMA 15.5.4
-StringPrototype::StringPrototype(ExecState* exec, PassRefPtr<Structure> structure)
+StringPrototype::StringPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure)
: StringObject(exec, structure)
{
// The constructor will be added later, after StringConstructor has been built
@@ -140,12 +149,11 @@ bool StringPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier
// ------------------------------ Functions --------------------------
-static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
+static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, int i)
{
- UString substitutedReplacement;
+ Vector<UChar> substitutedReplacement;
int offset = 0;
- int i = -1;
- while ((i = replacement.find('$', i + 1)) != -1) {
+ do {
if (i + 1 == replacement.size())
break;
@@ -197,15 +205,21 @@ static inline UString substituteBackreferences(const UString& replacement, const
i += 1 + advance;
offset = i + 1;
substitutedReplacement.append(source.data() + backrefStart, backrefLength);
- }
-
- if (!offset)
- return replacement;
+ } while ((i = replacement.find('$', i + 1)) != -1);
if (replacement.size() - offset)
substitutedReplacement.append(replacement.data() + offset, replacement.size() - offset);
- return substitutedReplacement;
+ substitutedReplacement.shrinkToFit();
+ return UString::adopt(substitutedReplacement);
+}
+
+static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
+{
+ int i = replacement.find('$', 0);
+ if (UNLIKELY(i != -1))
+ return substituteBackreferencesSlow(replacement, source, ovector, reg, i);
+ return replacement;
}
static inline int localeCompare(const UString& a, const UString& b)
@@ -216,7 +230,7 @@ static inline int localeCompare(const UString& a, const UString& b)
JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
JSString* sourceVal = thisValue.toThisJSString(exec);
- const UString& source = sourceVal->value();
+ const UString& source = sourceVal->value(exec);
JSValue pattern = args.at(0);
@@ -249,7 +263,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
return jsNull();
while (true) {
int matchIndex;
- int matchLen;
+ int matchLen = 0;
int* ovector;
regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
if (matchIndex < 0)
@@ -273,7 +287,8 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
cachedCall.setArgument(i++, sourceVal);
cachedCall.setThis(exec->globalThisValue());
- replacements.append(cachedCall.call().toString(cachedCall.newCallFrame()));
+ JSValue result = cachedCall.call();
+ replacements.append(result.toString(cachedCall.newCallFrame(exec)));
if (exec->hadException())
break;
@@ -290,7 +305,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
} else {
do {
int matchIndex;
- int matchLen;
+ int matchLen = 0;
int* ovector;
regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
if (matchIndex < 0)
@@ -414,12 +429,14 @@ JSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSVa
JSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue.toThisString(exec);
+ if (thisValue.isString() && (args.size() == 1)) {
+ JSValue v = args.at(0);
+ return v.isString()
+ ? jsString(exec, asString(thisValue), asString(v))
+ : jsString(exec, asString(thisValue), v.toString(exec));
+ }
- ArgList::const_iterator end = args.end();
- for (ArgList::const_iterator it = args.begin(); it != end; ++it)
- s += (*it).toString(exec);
- return jsString(exec, s);
+ return jsString(exec, thisValue, args);
}
JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -461,6 +478,11 @@ JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSV
dpos = 0;
else if (!(dpos <= len)) // true for NaN
dpos = len;
+#if OS(SYMBIAN)
+ // Work around for broken NaN compare operator
+ else if (isnan(dpos))
+ dpos = len;
+#endif
return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
}
@@ -485,7 +507,7 @@ JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue t
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
- int matchLength;
+ int matchLength = 0;
regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
if (!(reg->global())) {
// case without 'g' flag is handled like RegExp.prototype.exec
@@ -535,7 +557,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
- int matchLength;
+ int matchLength = 0;
regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
return jsNumber(exec, pos);
}
@@ -683,7 +705,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec, JSObject*, JSVal
JSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
JSString* sVal = thisValue.toThisJSString(exec);
- const UString& s = sVal->value();
+ const UString& s = sVal->value(exec);
int sSize = s.size();
if (!sSize)
@@ -699,7 +721,7 @@ JSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSV
buffer[i] = toASCIILower(c);
}
if (!(ored & ~0x7f))
- return jsString(exec, UString(buffer.releaseBuffer(), sSize, false));
+ return jsString(exec, UString::adopt(buffer));
bool error;
int length = Unicode::toLower(buffer.data(), sSize, sData, sSize, &error);
@@ -709,15 +731,18 @@ JSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSV
if (error)
return sVal;
}
- if (length == sSize && memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0)
- return sVal;
- return jsString(exec, UString(buffer.releaseBuffer(), length, false));
+ if (length == sSize) {
+ if (memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0)
+ return sVal;
+ } else
+ buffer.resize(length);
+ return jsString(exec, UString::adopt(buffer));
}
JSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
JSString* sVal = thisValue.toThisJSString(exec);
- const UString& s = sVal->value();
+ const UString& s = sVal->value(exec);
int sSize = s.size();
if (!sSize)
@@ -733,7 +758,7 @@ JSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSV
buffer[i] = toASCIIUpper(c);
}
if (!(ored & ~0x7f))
- return jsString(exec, UString(buffer.releaseBuffer(), sSize, false));
+ return jsString(exec, UString::adopt(buffer));
bool error;
int length = Unicode::toUpper(buffer.data(), sSize, sData, sSize, &error);
@@ -743,9 +768,12 @@ JSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSV
if (error)
return sVal;
}
- if (length == sSize && memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0)
- return sVal;
- return jsString(exec, UString(buffer.releaseBuffer(), length, false));
+ if (length == sSize) {
+ if (memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0)
+ return sVal;
+ } else
+ buffer.resize(length);
+ return jsString(exec, UString::adopt(buffer));
}
JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -761,62 +789,62 @@ JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, J
JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, "<big>" + s + "</big>");
+ return jsNontrivialString(exec, makeString("<big>", s, "</big>"));
}
JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, "<small>" + s + "</small>");
+ return jsNontrivialString(exec, makeString("<small>", s, "</small>"));
}
JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, "<blink>" + s + "</blink>");
+ return jsNontrivialString(exec, makeString("<blink>", s, "</blink>"));
}
JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, "<b>" + s + "</b>");
+ return jsNontrivialString(exec, makeString("<b>", s, "</b>"));
}
JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsString(exec, "<tt>" + s + "</tt>");
+ return jsString(exec, makeString("<tt>", s, "</tt>"));
}
JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, "<i>" + s + "</i>");
+ return jsNontrivialString(exec, makeString("<i>", s, "</i>"));
}
JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, "<strike>" + s + "</strike>");
+ return jsNontrivialString(exec, makeString("<strike>", s, "</strike>"));
}
JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, "<sub>" + s + "</sub>");
+ return jsNontrivialString(exec, makeString("<sub>", s, "</sub>"));
}
JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, "<sup>" + s + "</sup>");
+ return jsNontrivialString(exec, makeString("<sup>", s, "</sup>"));
}
JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
UString s = thisValue.toThisString(exec);
JSValue a0 = args.at(0);
- return jsNontrivialString(exec, "<font color=\"" + a0.toString(exec) + "\">" + s + "</font>");
+ return jsNontrivialString(exec, makeString("<font color=\"", a0.toString(exec), "\">", s, "</font>"));
}
JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -829,7 +857,8 @@ JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValu
unsigned stringSize = s.size();
unsigned bufferSize = 22 + stringSize;
UChar* buffer;
- if (!tryFastMalloc(bufferSize * sizeof(UChar)).getValue(buffer))
+ PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(bufferSize, buffer);
+ if (!impl)
return jsUndefined();
buffer[0] = '<';
buffer[1] = 'f';
@@ -854,17 +883,17 @@ JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValu
buffer[19 + stringSize] = 'n';
buffer[20 + stringSize] = 't';
buffer[21 + stringSize] = '>';
- return jsNontrivialString(exec, UString(buffer, bufferSize, false));
+ return jsNontrivialString(exec, impl);
}
- return jsNontrivialString(exec, "<font size=\"" + a0.toString(exec) + "\">" + s + "</font>");
+ return jsNontrivialString(exec, makeString("<font size=\"", a0.toString(exec), "\">", s, "</font>"));
}
JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
UString s = thisValue.toThisString(exec);
JSValue a0 = args.at(0);
- return jsNontrivialString(exec, "<a name=\"" + a0.toString(exec) + "\">" + s + "</a>");
+ return jsNontrivialString(exec, makeString("<a name=\"", a0.toString(exec), "\">", s, "</a>"));
}
JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -877,7 +906,8 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th
unsigned stringSize = s.size();
unsigned bufferSize = 15 + linkTextSize + stringSize;
UChar* buffer;
- if (!tryFastMalloc(bufferSize * sizeof(UChar)).getValue(buffer))
+ PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(bufferSize, buffer);
+ if (!impl)
return jsUndefined();
buffer[0] = '<';
buffer[1] = 'a';
@@ -896,7 +926,54 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th
buffer[12 + linkTextSize + stringSize] = '/';
buffer[13 + linkTextSize + stringSize] = 'a';
buffer[14 + linkTextSize + stringSize] = '>';
- return jsNontrivialString(exec, UString(buffer, bufferSize, false));
+ return jsNontrivialString(exec, impl);
}
+enum {
+ TrimLeft = 1,
+ TrimRight = 2
+};
+
+static inline bool isTrimWhitespace(UChar c)
+{
+ return isStrWhiteSpace(c) || c == 0x200b;
+}
+
+static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKind)
+{
+ UString str = thisValue.toThisString(exec);
+ int left = 0;
+ if (trimKind & TrimLeft) {
+ while (left < str.size() && isTrimWhitespace(str[left]))
+ left++;
+ }
+ int right = str.size();
+ if (trimKind & TrimRight) {
+ while (right > left && isTrimWhitespace(str[right - 1]))
+ right--;
+ }
+
+ // Don't gc allocate a new string if we don't have to.
+ if (left == 0 && right == str.size() && thisValue.isString())
+ return thisValue;
+
+ return jsString(exec, str.substr(left, right - left));
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ return trimString(exec, thisValue, TrimLeft | TrimRight);
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ return trimString(exec, thisValue, TrimLeft);
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ return trimString(exec, thisValue, TrimRight);
+}
+
+
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h
index 580e13d..3a6a2a3 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StringPrototype.h
@@ -29,7 +29,7 @@ namespace JSC {
class StringPrototype : public StringObject {
public:
- StringPrototype(ExecState*, PassRefPtr<Structure>);
+ StringPrototype(ExecState*, NonNullPassRefPtr<Structure>);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp
index be817c3..8e50dd1 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.cpp
@@ -28,9 +28,10 @@
#include "Identifier.h"
#include "JSObject.h"
+#include "JSPropertyNameIterator.h"
+#include "Lookup.h"
#include "PropertyNameArray.h"
#include "StructureChain.h"
-#include "Lookup.h"
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/RefPtr.h>
@@ -75,6 +76,8 @@ static HashSet<Structure*>& ignoreSet = *(new HashSet<Structure*>);
static HashSet<Structure*>& liveStructureSet = *(new HashSet<Structure*>);
#endif
+static int comparePropertyMapEntryIndices(const void* a, const void* b);
+
void Structure::dumpStatistics()
{
#if DUMP_STRUCTURE_ID_STATISTICS
@@ -130,6 +133,7 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo)
, m_isPinnedPropertyTable(false)
, m_hasGetterSetterProperties(false)
, m_attributesInPrevious(0)
+ , m_specificFunctionThrashCount(0)
{
ASSERT(m_prototype);
ASSERT(m_prototype.isObject() || m_prototype.isNull());
@@ -158,9 +162,9 @@ Structure::~Structure()
m_previous->table.removeAnonymousSlotTransition(m_anonymousSlotsInPrevious);
}
-
- if (m_cachedPropertyNameArrayData)
- m_cachedPropertyNameArrayData->setCachedStructure(0);
+
+ if (m_enumerationCache)
+ m_enumerationCache->setCachedStructure(0);
if (m_propertyTable) {
unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
@@ -281,59 +285,6 @@ void Structure::materializePropertyMap()
}
}
-void Structure::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject, bool includeNonEnumerable)
-{
- getNamesFromPropertyTable(propertyNames, includeNonEnumerable);
- getNamesFromClassInfoTable(exec, baseObject->classInfo(), propertyNames, includeNonEnumerable);
-}
-
-void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
-{
- bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary());
-
- if (shouldCache && m_cachedPropertyNameArrayData) {
- if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) {
- propertyNames.setData(m_cachedPropertyNameArrayData);
- return;
- }
- clearEnumerationCache();
- }
-
- baseObject->getOwnPropertyNames(exec, propertyNames);
-
- if (m_prototype.isObject()) {
- propertyNames.setShouldCache(false); // No need for our prototypes to waste memory on caching, since they're not being enumerated directly.
- JSObject* prototype = asObject(m_prototype);
- while(1) {
- if (!prototype->structure()->typeInfo().hasDefaultGetPropertyNames()) {
- prototype->getPropertyNames(exec, propertyNames);
- break;
- }
- prototype->getOwnPropertyNames(exec, propertyNames);
- JSValue nextProto = prototype->prototype();
- if (!nextProto.isObject())
- break;
- prototype = asObject(nextProto);
- }
- }
-
- if (shouldCache) {
- StructureChain* protoChain = prototypeChain(exec);
- m_cachedPropertyNameArrayData = propertyNames.data();
- if (!protoChain->isCacheable())
- return;
- m_cachedPropertyNameArrayData->setCachedPrototypeChain(protoChain);
- m_cachedPropertyNameArrayData->setCachedStructure(this);
- }
-}
-
-void Structure::clearEnumerationCache()
-{
- if (m_cachedPropertyNameArrayData)
- m_cachedPropertyNameArrayData->setCachedStructure(0);
- m_cachedPropertyNameArrayData.clear();
-}
-
void Structure::growPropertyStorageCapacity()
{
if (m_propertyStorageCapacity == JSObject::inlineStorageCapacity)
@@ -351,7 +302,7 @@ void Structure::despecifyDictionaryFunction(const Identifier& propertyName)
ASSERT(isDictionary());
ASSERT(m_propertyTable);
- unsigned i = rep->computedHash();
+ unsigned i = rep->existingHash();
#if DUMP_PROPERTYMAP_STATS
++numProbes;
@@ -369,7 +320,7 @@ void Structure::despecifyDictionaryFunction(const Identifier& propertyName)
++numCollisions;
#endif
- unsigned k = 1 | doubleHash(rep->computedHash());
+ unsigned k = 1 | doubleHash(rep->existingHash());
while (1) {
i += k;
@@ -407,6 +358,9 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
ASSERT(!structure->isDictionary());
ASSERT(structure->typeInfo().type() == ObjectType);
ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset));
+
+ if (structure->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
+ specificValue = 0;
if (structure->transitionCount() > s_maxTransitionLength) {
RefPtr<Structure> transition = toCacheableDictionaryTransition(structure);
@@ -426,6 +380,8 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
transition->m_specificValueInPrevious = specificValue;
transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+ transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+ transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
if (structure->m_propertyTable) {
if (structure->m_isPinnedPropertyTable)
@@ -468,6 +424,8 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure,
transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+ transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+ transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
// Don't set m_offset, as one can not transition to this.
@@ -480,10 +438,13 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure,
PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structure, const Identifier& replaceFunction)
{
+ ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount);
RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+ transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+ transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount + 1;
// Don't set m_offset, as one can not transition to this.
@@ -491,8 +452,12 @@ PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structur
transition->m_propertyTable = structure->copyPropertyTable();
transition->m_isPinnedPropertyTable = true;
- bool removed = transition->despecifyFunction(replaceFunction);
- ASSERT_UNUSED(removed, removed);
+ if (transition->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
+ transition->despecifyAllFunctions();
+ else {
+ bool removed = transition->despecifyFunction(replaceFunction);
+ ASSERT_UNUSED(removed, removed);
+ }
return transition.release();
}
@@ -515,6 +480,8 @@ PassRefPtr<Structure> Structure::addAnonymousSlotsTransition(Structure* structur
transition->m_specificValueInPrevious = 0;
transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+ transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+ transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
if (structure->m_propertyTable) {
if (structure->m_isPinnedPropertyTable)
@@ -543,6 +510,8 @@ PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties;
+ transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+ transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
// Don't set m_offset, as one can not transition to this.
@@ -561,6 +530,8 @@ PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, Di
transition->m_dictionaryKind = kind;
transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+ transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+ transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
structure->materializePropertyMapIfNecessary();
transition->m_propertyTable = structure->copyPropertyTable();
@@ -579,43 +550,75 @@ PassRefPtr<Structure> Structure::toUncacheableDictionaryTransition(Structure* st
return toDictionaryTransition(structure, UncachedDictionaryKind);
}
-PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure)
+PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSObject* object)
{
- ASSERT(structure->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_dictionaryKind = NoneDictionaryKind;
+ ASSERT(isDictionary());
+ if (isUncacheableDictionary()) {
+ ASSERT(m_propertyTable);
+ Vector<PropertyMapEntry*> sortedPropertyEntries(m_propertyTable->keyCount);
+ PropertyMapEntry** p = sortedPropertyEntries.data();
+ unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
+ for (unsigned i = 1; i <= entryCount; i++) {
+ if (m_propertyTable->entries()[i].key)
+ *p++ = &m_propertyTable->entries()[i];
+ }
+ size_t propertyCount = p - sortedPropertyEntries.data();
+ qsort(sortedPropertyEntries.data(), propertyCount, sizeof(PropertyMapEntry*), comparePropertyMapEntryIndices);
+ sortedPropertyEntries.resize(propertyCount);
+
+ // We now have the properties currently defined on this object
+ // in the order that they are expected to be in, but we need to
+ // reorder the storage, so we have to copy the current values out
+ Vector<JSValue> values(propertyCount);
+ unsigned anonymousSlotCount = m_propertyTable->anonymousSlotCount;
+ for (unsigned i = 0; i < propertyCount; i++) {
+ PropertyMapEntry* entry = sortedPropertyEntries[i];
+ values[i] = object->getDirectOffset(entry->offset);
+ // Update property table to have the new property offsets
+ entry->offset = anonymousSlotCount + i;
+ entry->index = i;
+ }
+
+ // Copy the original property values into their final locations
+ for (unsigned i = 0; i < propertyCount; i++)
+ object->putDirectOffset(anonymousSlotCount + i, values[i]);
+
+ if (m_propertyTable->deletedOffsets) {
+ delete m_propertyTable->deletedOffsets;
+ m_propertyTable->deletedOffsets = 0;
+ }
+ }
- return structure;
+ m_dictionaryKind = NoneDictionaryKind;
+ return this;
}
size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
{
+ ASSERT(!m_enumerationCache);
+
+ if (m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
+ specificValue = 0;
+
materializePropertyMapIfNecessary();
m_isPinnedPropertyTable = true;
+
size_t offset = put(propertyName, attributes, specificValue);
if (propertyStorageSize() > propertyStorageCapacity())
growPropertyStorageCapacity();
- clearEnumerationCache();
return offset;
}
size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName)
{
ASSERT(isUncacheableDictionary());
+ ASSERT(!m_enumerationCache);
materializePropertyMapIfNecessary();
m_isPinnedPropertyTable = true;
size_t offset = remove(propertyName);
- clearEnumerationCache();
return offset;
}
@@ -682,7 +685,7 @@ size_t Structure::get(const UString::Rep* rep, unsigned& attributes, JSCell*& sp
if (!m_propertyTable)
return notFound;
- unsigned i = rep->computedHash();
+ unsigned i = rep->existingHash();
#if DUMP_PROPERTYMAP_STATS
++numProbes;
@@ -702,7 +705,7 @@ size_t Structure::get(const UString::Rep* rep, unsigned& attributes, JSCell*& sp
++numCollisions;
#endif
- unsigned k = 1 | doubleHash(rep->computedHash());
+ unsigned k = 1 | doubleHash(rep->existingHash());
while (1) {
i += k;
@@ -733,7 +736,7 @@ bool Structure::despecifyFunction(const Identifier& propertyName)
UString::Rep* rep = propertyName._ustring.rep();
- unsigned i = rep->computedHash();
+ unsigned i = rep->existingHash();
#if DUMP_PROPERTYMAP_STATS
++numProbes;
@@ -753,7 +756,7 @@ bool Structure::despecifyFunction(const Identifier& propertyName)
++numCollisions;
#endif
- unsigned k = 1 | doubleHash(rep->computedHash());
+ unsigned k = 1 | doubleHash(rep->existingHash());
while (1) {
i += k;
@@ -774,6 +777,17 @@ bool Structure::despecifyFunction(const Identifier& propertyName)
}
}
+void Structure::despecifyAllFunctions()
+{
+ materializePropertyMapIfNecessary();
+ if (!m_propertyTable)
+ return;
+
+ unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
+ for (unsigned i = 1; i <= entryCount; ++i)
+ m_propertyTable->entries()[i].specificValue = 0;
+}
+
size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
{
ASSERT(!propertyName.isNull());
@@ -781,6 +795,9 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel
checkConsistency();
+ if (attributes & DontEnum)
+ m_hasNonEnumerableProperties = true;
+
UString::Rep* rep = propertyName._ustring.rep();
if (!m_propertyTable)
@@ -788,7 +805,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel
// FIXME: Consider a fast case for tables with no deleted sentinels.
- unsigned i = rep->computedHash();
+ unsigned i = rep->existingHash();
unsigned k = 0;
bool foundDeletedElement = false;
unsigned deletedElementIndex = 0; // initialize to make the compiler happy
@@ -811,7 +828,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel
}
if (k == 0) {
- k = 1 | doubleHash(rep->computedHash());
+ k = 1 | doubleHash(rep->existingHash());
#if DUMP_PROPERTYMAP_STATS
++numCollisions;
#endif
@@ -891,7 +908,7 @@ size_t Structure::remove(const Identifier& propertyName)
#endif
// Find the thing to remove.
- unsigned i = rep->computedHash();
+ unsigned i = rep->existingHash();
unsigned k = 0;
unsigned entryIndex;
UString::Rep* key = 0;
@@ -905,7 +922,7 @@ size_t Structure::remove(const Identifier& propertyName)
break;
if (k == 0) {
- k = 1 | doubleHash(rep->computedHash());
+ k = 1 | doubleHash(rep->existingHash());
#if DUMP_PROPERTYMAP_STATS
++numCollisions;
#endif
@@ -949,7 +966,7 @@ void Structure::insertIntoPropertyMapHashTable(const PropertyMapEntry& entry)
{
ASSERT(m_propertyTable);
- unsigned i = entry.key->computedHash();
+ unsigned i = entry.key->existingHash();
unsigned k = 0;
#if DUMP_PROPERTYMAP_STATS
@@ -962,7 +979,7 @@ void Structure::insertIntoPropertyMapHashTable(const PropertyMapEntry& entry)
break;
if (k == 0) {
- k = 1 | doubleHash(entry.key->computedHash());
+ k = 1 | doubleHash(entry.key->existingHash());
#if DUMP_PROPERTYMAP_STATS
++numCollisions;
#endif
@@ -1045,7 +1062,7 @@ void Structure::rehashPropertyMapHashTable(unsigned newTableSize)
checkConsistency();
}
-static int comparePropertyMapEntryIndices(const void* a, const void* b)
+int comparePropertyMapEntryIndices(const void* a, const void* b)
{
unsigned ia = static_cast<PropertyMapEntry* const*>(a)[0]->index;
unsigned ib = static_cast<PropertyMapEntry* const*>(b)[0]->index;
@@ -1056,7 +1073,7 @@ static int comparePropertyMapEntryIndices(const void* a, const void* b)
return 0;
}
-void Structure::getNamesFromPropertyTable(PropertyNameArray& propertyNames, bool includeNonEnumerable)
+void Structure::getPropertyNames(PropertyNameArray& propertyNames, EnumerationMode mode)
{
materializePropertyMapIfNecessary();
if (!m_propertyTable)
@@ -1067,7 +1084,8 @@ void Structure::getNamesFromPropertyTable(PropertyNameArray& propertyNames, bool
int i = 0;
unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
for (unsigned k = 1; k <= entryCount; k++) {
- if (m_propertyTable->entries()[k].key && (!(m_propertyTable->entries()[k].attributes & DontEnum) || includeNonEnumerable)) {
+ ASSERT(m_hasNonEnumerableProperties || !(m_propertyTable->entries()[k].attributes & DontEnum));
+ if (m_propertyTable->entries()[k].key && (!(m_propertyTable->entries()[k].attributes & DontEnum) || (mode == IncludeDontEnumProperties))) {
PropertyMapEntry* value = &m_propertyTable->entries()[k];
int j;
for (j = i - 1; j >= 0 && a[j]->index > value->index; --j)
@@ -1094,7 +1112,7 @@ void Structure::getNamesFromPropertyTable(PropertyNameArray& propertyNames, bool
PropertyMapEntry** p = sortedEnumerables.data();
unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
for (unsigned i = 1; i <= entryCount; i++) {
- if (m_propertyTable->entries()[i].key && (!(m_propertyTable->entries()[i].attributes & DontEnum) || includeNonEnumerable))
+ if (m_propertyTable->entries()[i].key && (!(m_propertyTable->entries()[i].attributes & DontEnum) || (mode == IncludeDontEnumProperties)))
*p++ = &m_propertyTable->entries()[i];
}
@@ -1113,25 +1131,6 @@ void Structure::getNamesFromPropertyTable(PropertyNameArray& propertyNames, bool
}
}
-void Structure::getNamesFromClassInfoTable(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, bool includeNonEnumerable)
-{
- // Add properties from the static hashtables of properties
- for (; classInfo; classInfo = classInfo->parentClass) {
- const HashTable* table = classInfo->propHashTable(exec);
- if (!table)
- continue;
- table->initializeIfNeeded(exec);
- ASSERT(table->table);
-
- int hashSizeMask = table->compactSize - 1;
- const HashEntry* entry = table->table;
- for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
- if (entry->key() && (!(entry->attributes() & DontEnum) || includeNonEnumerable))
- propertyNames.add(entry->key());
- }
- }
-}
-
#if DO_PROPERTYMAP_CONSTENCY_CHECK
void Structure::checkConsistency()
@@ -1173,11 +1172,12 @@ void Structure::checkConsistency()
unsigned nonEmptyEntryCount = 0;
for (unsigned c = 1; c <= m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; ++c) {
+ ASSERT(m_hasNonEnumerableProperties || !(m_propertyTable->entries()[c].attributes & DontEnum));
UString::Rep* rep = m_propertyTable->entries()[c].key;
if (!rep)
continue;
++nonEmptyEntryCount;
- unsigned i = rep->computedHash();
+ unsigned i = rep->existingHash();
unsigned k = 0;
unsigned entryIndex;
while (1) {
@@ -1186,7 +1186,7 @@ void Structure::checkConsistency()
if (rep == m_propertyTable->entries()[entryIndex - 1].key)
break;
if (k == 0)
- k = 1 | doubleHash(rep->computedHash());
+ k = 1 | doubleHash(rep->existingHash());
i += k;
}
ASSERT(entryIndex == c + 1);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h
index d012ba9..5284258 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Structure.h
@@ -30,6 +30,8 @@
#include "JSType.h"
#include "JSValue.h"
#include "PropertyMapHashTable.h"
+#include "PropertyNameArray.h"
+#include "Protect.h"
#include "StructureTransitionTable.h"
#include "JSTypeInfo.h"
#include "UString.h"
@@ -49,6 +51,11 @@ namespace JSC {
class PropertyNameArrayData;
class StructureChain;
+ enum EnumerationMode {
+ ExcludeDontEnumProperties,
+ IncludeDontEnumProperties
+ };
+
class Structure : public RefCounted<Structure> {
public:
friend class JIT;
@@ -72,11 +79,10 @@ namespace JSC {
static PassRefPtr<Structure> getterSetterTransition(Structure*);
static PassRefPtr<Structure> toCacheableDictionaryTransition(Structure*);
static PassRefPtr<Structure> toUncacheableDictionaryTransition(Structure*);
- static PassRefPtr<Structure> fromDictionaryTransition(Structure*);
- ~Structure();
+ PassRefPtr<Structure> flattenDictionaryStructure(JSObject*);
- void markAggregate(MarkStack&);
+ ~Structure();
// These should be used with caution.
size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
@@ -95,8 +101,8 @@ namespace JSC {
Structure* previousID() const { return m_previous.get(); }
void growPropertyStorageCapacity();
- size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; }
- size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; }
+ unsigned propertyStorageCapacity() const { return m_propertyStorageCapacity; }
+ unsigned propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; }
bool isUsingInlineStorage() const;
size_t get(const Identifier& propertyName);
@@ -116,17 +122,22 @@ namespace JSC {
return hasTransition(propertyName._ustring.rep(), attributes);
}
- void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
- void getOwnPropertyNames(ExecState*, PropertyNameArray&, JSObject*, bool includeNonEnumerable = false);
-
bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
void setHasGetterSetterProperties(bool hasGetterSetterProperties) { m_hasGetterSetterProperties = hasGetterSetterProperties; }
+ bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
+
+ bool hasAnonymousSlots() const { return m_propertyTable && m_propertyTable->anonymousSlotCount; }
+
bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; }
- JSCell* specificValue() { return m_specificValueInPrevious; }
void despecifyDictionaryFunction(const Identifier& propertyName);
+ void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
+ void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
+ JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); }
+ void getPropertyNames(PropertyNameArray&, EnumerationMode mode);
+
private:
Structure(JSValue prototype, const TypeInfo&);
@@ -140,8 +151,6 @@ namespace JSC {
size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
size_t remove(const Identifier& propertyName);
void addAnonymousSlots(unsigned slotCount);
- void getNamesFromPropertyTable(PropertyNameArray&, bool includeNonEnumerable = false);
- void getNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&, bool includeNonEnumerable = false);
void expandPropertyMapHashTable();
void rehashPropertyMapHashTable();
@@ -152,6 +161,7 @@ namespace JSC {
void checkConsistency();
bool despecifyFunction(const Identifier&);
+ void despecifyAllFunctions();
PropertyMapHashTable* copyPropertyTable();
void materializePropertyMap();
@@ -162,8 +172,6 @@ namespace JSC {
materializePropertyMap();
}
- void clearEnumerationCache();
-
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.
@@ -178,6 +186,8 @@ namespace JSC {
static const signed char noOffset = -1;
+ static const unsigned maxSpecificFunctionThrashCount = 3;
+
TypeInfo m_typeInfo;
JSValue m_prototype;
@@ -189,16 +199,17 @@ namespace JSC {
StructureTransitionTable table;
- RefPtr<PropertyNameArrayData> m_cachedPropertyNameArrayData;
+ ProtectedPtr<JSPropertyNameIterator> m_enumerationCache;
PropertyMapHashTable* m_propertyTable;
- size_t m_propertyStorageCapacity;
+ uint32_t m_propertyStorageCapacity;
signed char m_offset;
unsigned m_dictionaryKind : 2;
bool m_isPinnedPropertyTable : 1;
bool m_hasGetterSetterProperties : 1;
+ bool m_hasNonEnumerableProperties : 1;
#if COMPILER(WINSCW)
// Workaround for Symbian WINSCW compiler that cannot resolve unsigned type of the declared
// bitfield, when used as argument in make_pair() function calls in structure.ccp.
@@ -208,6 +219,8 @@ namespace JSC {
unsigned m_attributesInPrevious : 7;
#endif
unsigned m_anonymousSlotsInPrevious : 6;
+ unsigned m_specificFunctionThrashCount : 2;
+ // 4 free bits
};
inline size_t Structure::get(const Identifier& propertyName)
@@ -220,7 +233,7 @@ namespace JSC {
UString::Rep* rep = propertyName._ustring.rep();
- unsigned i = rep->computedHash();
+ unsigned i = rep->existingHash();
#if DUMP_PROPERTYMAP_STATS
++numProbes;
@@ -237,7 +250,7 @@ namespace JSC {
++numCollisions;
#endif
- unsigned k = 1 | WTF::doubleHash(rep->computedHash());
+ unsigned k = 1 | WTF::doubleHash(rep->existingHash());
while (1) {
i += k;
@@ -304,7 +317,7 @@ namespace JSC {
TransitionTable* transitionTable = new TransitionTable;
setTransitionTable(transitionTable);
if (existingTransition)
- add(make_pair(RefPtr<UString::Rep>(existingTransition->m_nameInPrevious.get()), existingTransition->m_attributesInPrevious), existingTransition, existingTransition->m_specificValueInPrevious);
+ add(std::make_pair(RefPtr<UString::Rep>(existingTransition->m_nameInPrevious.get()), existingTransition->m_attributesInPrevious), existingTransition, existingTransition->m_specificValueInPrevious);
}
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp
index 2c38b67..76e5518 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.cpp
@@ -25,7 +25,6 @@
#include "config.h"
#include "StructureChain.h"
-#include "Structure.h"
#include "JSObject.h"
#include "Structure.h"
@@ -47,23 +46,11 @@ StructureChain::StructureChain(Structure* head)
m_vector[i] = 0;
}
+#if OS(HPUX)
PassRefPtr<StructureChain> StructureChain::create(Structure* head)
{
return adoptRef(new StructureChain(head));
}
-
-bool StructureChain::isCacheable() const
-{
- uint32_t i = 0;
-
- while (m_vector[i]) {
- // Both classes of dictionary structure may change arbitrarily so we can't cache them
- if (m_vector[i]->isDictionary())
- return false;
- if (!m_vector[i++]->typeInfo().hasDefaultGetPropertyNames())
- return false;
- }
- return true;
-}
+#endif
} // namespace JSC
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.h
index 5990e17..3496400 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureChain.h
@@ -36,10 +36,15 @@ namespace JSC {
class Structure;
class StructureChain : public RefCounted<StructureChain> {
+ friend class JIT;
+
public:
+#if OS(HPUX)
static PassRefPtr<StructureChain> create(Structure* head);
+#else
+ static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); }
+#endif
RefPtr<Structure>* head() { return m_vector.get(); }
- bool isCacheable() const;
private:
StructureChain(Structure* head);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h
index 0fa7b73..35fb7e4 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/StructureTransitionTable.h
@@ -42,7 +42,7 @@ namespace JSC {
typedef std::pair<RefPtr<UString::Rep>, unsigned> Key;
static unsigned hash(const Key& p)
{
- return p.first->computedHash();
+ return p.first->existingHash();
}
static bool equal(const Key& a, const Key& b)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp
index 0a8bbd3..9e1f8b4 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/TimeoutChecker.cpp
@@ -33,9 +33,9 @@
#include "CallFrame.h"
#include "JSGlobalObject.h"
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
#include <mach/mach.h>
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
#include <windows.h>
#else
#include "CurrentTime.h"
@@ -54,7 +54,7 @@ static const int defaultIntervalBetweenChecks = 1000;
// Returns the time the current thread has spent executing, in milliseconds.
static inline unsigned getCPUTime()
{
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
thread_basic_info_data_t info;
@@ -67,7 +67,7 @@ static inline unsigned getCPUTime()
time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000;
return time;
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
union {
FILETIME fileTime;
unsigned long long fileTimeAsLong;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.h
index e544f66..c28c85f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Tracing.h
@@ -33,7 +33,7 @@
#define JAVASCRIPTCORE_GC_BEGIN()
#define JAVASCRIPTCORE_GC_BEGIN_ENABLED() 0
-#define JAVASCRIPTCORE_GC_END(arg0, arg1)
+#define JAVASCRIPTCORE_GC_END()
#define JAVASCRIPTCORE_GC_END_ENABLED() 0
#define JAVASCRIPTCORE_GC_MARKED()
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp
index e66ca93..a6b66cb 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.cpp
@@ -30,12 +30,12 @@
#include "Identifier.h"
#include "Operations.h"
#include <ctype.h>
-#include <float.h>
#include <limits.h>
#include <limits>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <wtf/ASCIICType.h>
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
@@ -44,9 +44,6 @@
#include <wtf/unicode/UTF8.h>
#include <wtf/StringExtras.h>
-#if HAVE(STRING_H)
-#include <string.h>
-#endif
#if HAVE(STRINGS_H)
#include <strings.h>
#endif
@@ -55,52 +52,11 @@ using namespace WTF;
using namespace WTF::Unicode;
using namespace std;
-// This can be tuned differently per platform by putting platform #ifs right here.
-// If you don't define this macro at all, then copyChars will just call directly
-// to memcpy.
-#define USTRING_COPY_CHARS_INLINE_CUTOFF 20
-
namespace JSC {
extern const double NaN;
extern const double Inf;
-// This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
-static const int minLengthToShare = 10;
-
-static inline size_t overflowIndicator() { return std::numeric_limits<size_t>::max(); }
-static inline size_t maxUChars() { return std::numeric_limits<size_t>::max() / sizeof(UChar); }
-
-static inline PossiblyNull<UChar*> allocChars(size_t length)
-{
- ASSERT(length);
- if (length > maxUChars())
- return 0;
- return tryFastMalloc(sizeof(UChar) * length);
-}
-
-static inline PossiblyNull<UChar*> reallocChars(UChar* buffer, size_t length)
-{
- ASSERT(length);
- if (length > maxUChars())
- return 0;
- return tryFastRealloc(buffer, sizeof(UChar) * length);
-}
-
-static inline void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
-{
-#ifdef USTRING_COPY_CHARS_INLINE_CUTOFF
- if (numCharacters <= USTRING_COPY_CHARS_INLINE_CUTOFF) {
- for (unsigned i = 0; i < numCharacters; ++i)
- destination[i] = source[i];
- return;
- }
-#endif
- memcpy(destination, source, numCharacters * sizeof(UChar));
-}
-
-COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes);
-
CString::CString(const char* c)
: m_length(strlen(c))
, m_data(new char[m_length + 1])
@@ -193,389 +149,52 @@ 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::BaseString* UString::Rep::nullBaseString;
-UString::BaseString* UString::Rep::emptyBaseString;
+UStringImpl* UStringImpl::s_null;
+UStringImpl* UStringImpl::s_empty;
UString* UString::nullUString;
-static void initializeStaticBaseString(UString::BaseString& base)
-{
- base.rc = INT_MAX / 2;
- base.m_identifierTableAndFlags.setFlag(UString::Rep::StaticFlag);
- base.checkConsistency();
-}
-
void initializeUString()
{
- UString::Rep::nullBaseString = new UString::BaseString(0, 0);
- initializeStaticBaseString(*UString::Rep::nullBaseString);
-
- UString::Rep::emptyBaseString = new UString::BaseString(&sharedEmptyChar, 0);
- initializeStaticBaseString(*UString::Rep::emptyBaseString);
-
+ UStringImpl::s_null = new UStringImpl(0, 0, UStringImpl::ConstructStaticString);
+ UStringImpl::s_empty = new UStringImpl(&sharedEmptyChar, 0, UStringImpl::ConstructStaticString);
UString::nullUString = new UString;
}
-static char* statBuffer = 0; // Only used for debugging via UString::ascii().
-
-PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar* d, int l)
-{
- UChar* copyD = static_cast<UChar*>(fastMalloc(l * sizeof(UChar)));
- copyChars(copyD, d, l);
- return create(copyD, l);
-}
-
-PassRefPtr<UString::Rep> UString::Rep::createFromUTF8(const char* string)
+static PassRefPtr<UString::Rep> createRep(const char* c)
{
- if (!string)
- 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))
+ if (!c)
return &UString::Rep::null();
- return UString::Rep::createCopying(buffer.data(), p - buffer.data());
-}
-
-PassRefPtr<UString::Rep> UString::Rep::create(UChar* string, int length, PassRefPtr<UString::SharedUChar> sharedBuffer)
-{
- PassRefPtr<UString::Rep> rep = create(string, length);
- rep->baseString()->setSharedBuffer(sharedBuffer);
- rep->checkConsistency();
- return rep;
-}
-
-UString::SharedUChar* UString::Rep::sharedBuffer()
-{
- UString::BaseString* base = baseString();
- if (len < minLengthToShare)
- return 0;
-
- return base->sharedBuffer();
-}
-
-void UString::Rep::destroy()
-{
- checkConsistency();
-
- // Static null and empty strings can never be destroyed, but we cannot rely on
- // reference counting, because ref/deref are not thread-safe.
- if (!isStatic()) {
- if (identifierTable())
- Identifier::remove(this);
-
- UString::BaseString* base = baseString();
- if (base == this) {
- if (m_sharedBuffer)
- m_sharedBuffer->deref();
- else
- fastFree(base->buf);
- } else
- base->deref();
-
- delete this;
- }
-}
-
-// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
-// or anything like that.
-const unsigned PHI = 0x9e3779b9U;
-
-// Paul Hsieh's SuperFastHash
-// http://www.azillionmonkeys.com/qed/hash.html
-unsigned UString::Rep::computeHash(const UChar* s, int len)
-{
- unsigned l = len;
- uint32_t hash = PHI;
- uint32_t tmp;
-
- int rem = l & 1;
- l >>= 1;
-
- // Main loop
- for (; l > 0; l--) {
- hash += s[0];
- tmp = (s[1] << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- s += 2;
- hash += hash >> 11;
- }
-
- // Handle end case
- if (rem) {
- hash += s[0];
- hash ^= hash << 11;
- hash += hash >> 17;
- }
-
- // Force "avalanching" of final 127 bits
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 2;
- hash += hash >> 15;
- hash ^= hash << 10;
-
- // this avoids ever returning a hash code of 0, since that is used to
- // signal "hash not computed yet", using a value that is likely to be
- // effectively the same as 0 when the low bits are masked
- if (hash == 0)
- hash = 0x80000000;
-
- return hash;
-}
-
-// Paul Hsieh's SuperFastHash
-// http://www.azillionmonkeys.com/qed/hash.html
-unsigned UString::Rep::computeHash(const char* s, int l)
-{
- // This hash is designed to work on 16-bit chunks at a time. But since the normal case
- // (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they
- // were 16-bit chunks, which should give matching results
-
- uint32_t hash = PHI;
- uint32_t tmp;
-
- size_t rem = l & 1;
- l >>= 1;
-
- // Main loop
- for (; l > 0; l--) {
- hash += static_cast<unsigned char>(s[0]);
- tmp = (static_cast<unsigned char>(s[1]) << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- s += 2;
- hash += hash >> 11;
- }
-
- // Handle end case
- if (rem) {
- hash += static_cast<unsigned char>(s[0]);
- hash ^= hash << 11;
- hash += hash >> 17;
- }
-
- // Force "avalanching" of final 127 bits
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 2;
- hash += hash >> 15;
- hash ^= hash << 10;
-
- // this avoids ever returning a hash code of 0, since that is used to
- // signal "hash not computed yet", using a value that is likely to be
- // effectively the same as 0 when the low bits are masked
- if (hash == 0)
- hash = 0x80000000;
-
- return hash;
-}
-
-#ifndef NDEBUG
-void UString::Rep::checkConsistency() const
-{
- const UString::BaseString* base = baseString();
-
- // There is no recursion for base strings.
- ASSERT(base == base->baseString());
-
- if (isStatic()) {
- // There are only two static strings: null and empty.
- ASSERT(!len);
-
- // Static strings cannot get in identifier tables, because they are globally shared.
- ASSERT(!identifierTable());
- }
-
- // The string fits in buffer.
- ASSERT(base->usedPreCapacity <= base->preCapacity);
- ASSERT(base->usedCapacity <= base->capacity);
- ASSERT(-offset <= base->usedPreCapacity);
- ASSERT(offset + len <= base->usedCapacity);
-}
-#endif
-
-UString::SharedUChar* UString::BaseString::sharedBuffer()
-{
- if (!m_sharedBuffer)
- setSharedBuffer(SharedUChar::create(new OwnFastMallocPtr<UChar>(buf)));
- return m_sharedBuffer;
-}
-
-void UString::BaseString::setSharedBuffer(PassRefPtr<UString::SharedUChar> sharedBuffer)
-{
- // The manual steps below are because m_sharedBuffer can't be a RefPtr. m_sharedBuffer
- // is in a union with another variable to avoid making BaseString any larger.
- if (m_sharedBuffer)
- m_sharedBuffer->deref();
- m_sharedBuffer = sharedBuffer.releaseRef();
-}
-
-bool UString::BaseString::slowIsBufferReadOnly()
-{
- // The buffer may not be modified as soon as the underlying data has been shared with another class.
- if (m_sharedBuffer->isShared())
- return true;
-
- // At this point, we know it that the underlying buffer isn't shared outside of this base class,
- // so get rid of m_sharedBuffer.
- OwnPtr<OwnFastMallocPtr<UChar> > mallocPtr(m_sharedBuffer->release());
- UChar* unsharedBuf = const_cast<UChar*>(mallocPtr->release());
- setSharedBuffer(0);
- preCapacity += (buf - unsharedBuf);
- buf = unsharedBuf;
- return false;
-}
-
-// Put these early so they can be inlined.
-static inline size_t expandedSize(size_t capacitySize, size_t precapacitySize)
-{
- // Combine capacitySize & precapacitySize to produce a single size to allocate,
- // check that doing so does not result in overflow.
- size_t size = capacitySize + precapacitySize;
- if (size < capacitySize)
- return overflowIndicator();
-
- // Small Strings (up to 4 pages):
- // Expand the allocation size to 112.5% of the amount requested. This is largely sicking
- // to our previous policy, however 112.5% is cheaper to calculate.
- if (size < 0x4000) {
- size_t expandedSize = ((size + (size >> 3)) | 15) + 1;
- // Given the limited range within which we calculate the expansion in this
- // fashion the above calculation should never overflow.
- ASSERT(expandedSize >= size);
- ASSERT(expandedSize < maxUChars());
- return expandedSize;
- }
-
- // Medium Strings (up to 128 pages):
- // For pages covering multiple pages over-allocation is less of a concern - any unused
- // space will not be paged in if it is not used, so this is purely a VM overhead. For
- // these strings allocate 2x the requested size.
- if (size < 0x80000) {
- size_t expandedSize = ((size + size) | 0xfff) + 1;
- // Given the limited range within which we calculate the expansion in this
- // fashion the above calculation should never overflow.
- ASSERT(expandedSize >= size);
- ASSERT(expandedSize < maxUChars());
- return expandedSize;
- }
-
- // Large Strings (to infinity and beyond!):
- // Revert to our 112.5% policy - probably best to limit the amount of unused VM we allow
- // any individual string be responsible for.
- size_t expandedSize = ((size + (size >> 3)) | 0xfff) + 1;
-
- // Check for overflow - any result that is at least as large as requested (but
- // still below the limit) is okay.
- if ((expandedSize >= size) && (expandedSize < maxUChars()))
- return expandedSize;
- return overflowIndicator();
-}
-
-static inline bool expandCapacity(UString::Rep* rep, int requiredLength)
-{
- rep->checkConsistency();
- ASSERT(!rep->baseString()->isBufferReadOnly());
-
- UString::BaseString* base = rep->baseString();
-
- if (requiredLength > base->capacity) {
- size_t newCapacity = expandedSize(requiredLength, base->preCapacity);
- UChar* oldBuf = base->buf;
- if (!reallocChars(base->buf, newCapacity).getValue(base->buf)) {
- base->buf = oldBuf;
- return false;
- }
- base->capacity = newCapacity - base->preCapacity;
- }
- if (requiredLength > base->usedCapacity)
- base->usedCapacity = requiredLength;
-
- rep->checkConsistency();
- return true;
-}
-
-bool UString::Rep::reserveCapacity(int capacity)
-{
- // If this is an empty string there is no point 'growing' it - just allocate a new one.
- // If the BaseString is shared with another string that is using more capacity than this
- // string is, then growing the buffer won't help.
- // If the BaseString's buffer is readonly, then it isn't allowed to grow.
- UString::BaseString* base = baseString();
- if (!base->buf || !base->capacity || (offset + len) != base->usedCapacity || base->isBufferReadOnly())
- return false;
-
- // If there is already sufficient capacity, no need to grow!
- if (capacity <= base->capacity)
- return true;
-
- checkConsistency();
-
- size_t newCapacity = expandedSize(capacity, base->preCapacity);
- UChar* oldBuf = base->buf;
- if (!reallocChars(base->buf, newCapacity).getValue(base->buf)) {
- base->buf = oldBuf;
- return false;
- }
- base->capacity = newCapacity - base->preCapacity;
-
- checkConsistency();
- return true;
-}
-
-void UString::expandCapacity(int requiredLength)
-{
- if (!JSC::expandCapacity(m_rep.get(), requiredLength))
- makeNull();
-}
-
-void UString::expandPreCapacity(int requiredPreCap)
-{
- m_rep->checkConsistency();
- ASSERT(!m_rep->baseString()->isBufferReadOnly());
-
- BaseString* base = m_rep->baseString();
-
- if (requiredPreCap > base->preCapacity) {
- size_t newCapacity = expandedSize(requiredPreCap, base->capacity);
- int delta = newCapacity - base->capacity - base->preCapacity;
-
- UChar* newBuf;
- if (!allocChars(newCapacity).getValue(newBuf)) {
- makeNull();
- return;
- }
- copyChars(newBuf + delta, base->buf, base->capacity + base->preCapacity);
- fastFree(base->buf);
- base->buf = newBuf;
+ if (!c[0])
+ return &UString::Rep::empty();
- base->preCapacity = newCapacity - base->capacity;
- }
- if (requiredPreCap > base->usedPreCapacity)
- base->usedPreCapacity = requiredPreCap;
+ size_t length = strlen(c);
+ UChar* d;
+ PassRefPtr<UStringImpl> result = UStringImpl::tryCreateUninitialized(length, d);
+ if (!result)
+ return &UString::Rep::null();
- m_rep->checkConsistency();
+ for (size_t i = 0; i < length; i++)
+ d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
+ return result;
}
-static PassRefPtr<UString::Rep> createRep(const char* c)
+static inline PassRefPtr<UString::Rep> createRep(const char* c, int length)
{
if (!c)
return &UString::Rep::null();
- if (!c[0])
+ if (!length)
return &UString::Rep::empty();
- size_t length = strlen(c);
UChar* d;
- if (!allocChars(length).getValue(d))
+ PassRefPtr<UStringImpl> result = UStringImpl::tryCreateUninitialized(length, d);
+ if (!result)
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
- return UString::Rep::create(d, static_cast<int>(length));
- }
+ for (int i = 0; i < length; i++)
+ d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
+ return result;
}
UString::UString(const char* c)
@@ -583,335 +202,31 @@ UString::UString(const char* c)
{
}
-UString::UString(const UChar* c, int length)
+UString::UString(const char* c, int length)
+ : m_rep(createRep(c, length))
{
- if (length == 0)
- m_rep = &Rep::empty();
- else
- m_rep = Rep::createCopying(c, length);
}
-UString::UString(UChar* c, int length, bool copy)
+UString::UString(const UChar* c, int length)
{
- if (length == 0)
+ if (length == 0)
m_rep = &Rep::empty();
- else if (copy)
- m_rep = Rep::createCopying(c, length);
else
m_rep = Rep::create(c, length);
}
-UString::UString(const Vector<UChar>& buffer)
-{
- if (!buffer.size())
- m_rep = &Rep::empty();
- else
- m_rep = Rep::createCopying(buffer.data(), buffer.size());
-}
-
-static ALWAYS_INLINE int newCapacityWithOverflowCheck(const int currentCapacity, const int extendLength, const bool plusOne = false)
-{
- ASSERT_WITH_MESSAGE(extendLength >= 0, "extendedLength = %d", extendLength);
-
- const int plusLength = plusOne ? 1 : 0;
- if (currentCapacity > std::numeric_limits<int>::max() - extendLength - plusLength)
- CRASH();
-
- return currentCapacity + extendLength + plusLength;
-}
-
-static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Rep> r, const UChar* tData, int tSize)
-{
- RefPtr<UString::Rep> rep = r;
-
- rep->checkConsistency();
-
- int thisSize = rep->size();
- int thisOffset = rep->offset;
- int length = thisSize + tSize;
- UString::BaseString* base = rep->baseString();
-
- // possible cases:
- if (tSize == 0) {
- // t is empty
- } else if (thisSize == 0) {
- // this is empty
- rep = UString::Rep::createCopying(tData, tSize);
- } else if (rep == base && !base->isShared()) {
- // this is direct and has refcount of 1 (so we can just alter it directly)
- if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)))
- rep = &UString::Rep::null();
- if (rep->data()) {
- copyChars(rep->data() + thisSize, tData, tSize);
- rep->len = length;
- rep->_hash = 0;
- }
- } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
- // this reaches the end of the buffer - extend it if it's long enough to append to
- if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)))
- rep = &UString::Rep::null();
- if (rep->data()) {
- copyChars(rep->data() + thisSize, tData, tSize);
- rep = UString::Rep::create(rep, 0, length);
- }
- } else {
- // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
- size_t newCapacity = expandedSize(length, 0);
- UChar* d;
- if (!allocChars(newCapacity).getValue(d))
- rep = &UString::Rep::null();
- else {
- copyChars(d, rep->data(), thisSize);
- copyChars(d + thisSize, tData, tSize);
- rep = UString::Rep::create(d, length);
- rep->baseString()->capacity = newCapacity;
- }
- }
-
- rep->checkConsistency();
-
- return rep.release();
-}
-
-static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Rep> r, const char* t)
-{
- RefPtr<UString::Rep> rep = r;
-
- rep->checkConsistency();
-
- int thisSize = rep->size();
- 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) {
- // this is empty
- rep = createRep(t);
- } else if (tSize == 0) {
- // t is empty, we'll just return *this below.
- } else if (rep == base && !base->isShared()) {
- // this is direct and has refcount of 1 (so we can just alter it directly)
- expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
- UChar* d = rep->data();
- if (d) {
- 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->len = length;
- rep->_hash = 0;
- }
- } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
- // this string reaches the end of the buffer - extend it
- expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
- UChar* d = rep->data();
- if (d) {
- 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(rep, 0, length);
- }
- } else {
- // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
- size_t newCapacity = expandedSize(length, 0);
- UChar* d;
- if (!allocChars(newCapacity).getValue(d))
- 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->baseString()->capacity = newCapacity;
- }
- }
-
- rep->checkConsistency();
-
- return rep.release();
-}
-
-PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
-{
- a->checkConsistency();
- b->checkConsistency();
-
- int aSize = a->size();
- int bSize = b->size();
- int aOffset = a->offset;
-
- // possible cases:
-
- UString::BaseString* aBase = a->baseString();
- if (bSize == 1 && aOffset + aSize == aBase->usedCapacity && aOffset + aSize < aBase->capacity && !aBase->isBufferReadOnly()) {
- // b is a single character (common fast case)
- ++aBase->usedCapacity;
- a->data()[aSize] = b->data()[0];
- return UString::Rep::create(a, 0, aSize + 1);
- }
-
- // a is empty
- if (aSize == 0)
- return b;
- // b is empty
- if (bSize == 0)
- return a;
-
- int bOffset = b->offset;
- int length = aSize + bSize;
-
- UString::BaseString* bBase = b->baseString();
- if (aOffset + aSize == aBase->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize
- && (-bOffset != bBase->usedPreCapacity || aSize >= bSize) && !aBase->isBufferReadOnly()) {
- // - a reaches the end of its buffer so it qualifies for shared append
- // - also, it's at least a quarter the length of b - appending to a much shorter
- // string does more harm than good
- // - however, if b qualifies for prepend and is longer than a, we'd rather prepend
-
- UString x(a);
- x.expandCapacity(newCapacityWithOverflowCheck(aOffset, length));
- if (!a->data() || !x.data())
- return 0;
- copyChars(a->data() + aSize, b->data(), bSize);
- PassRefPtr<UString::Rep> result = UString::Rep::create(a, 0, length);
-
- a->checkConsistency();
- b->checkConsistency();
- result->checkConsistency();
-
- return result;
- }
-
- if (-bOffset == bBase->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize && !bBase->isBufferReadOnly()) {
- // - b reaches the beginning of its buffer so it qualifies for shared prepend
- // - also, it's at least a quarter the length of a - prepending to a much shorter
- // string does more harm than good
- UString y(b);
- y.expandPreCapacity(-bOffset + aSize);
- if (!b->data() || !y.data())
- return 0;
- copyChars(b->data() - aSize, a->data(), aSize);
- PassRefPtr<UString::Rep> result = UString::Rep::create(b, -aSize, length);
-
- a->checkConsistency();
- b->checkConsistency();
- result->checkConsistency();
-
- return result;
- }
-
- // a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string
- size_t newCapacity = expandedSize(length, 0);
- UChar* d;
- if (!allocChars(newCapacity).getValue(d))
- return 0;
- copyChars(d, a->data(), aSize);
- copyChars(d + aSize, b->data(), bSize);
- PassRefPtr<UString::Rep> result = UString::Rep::create(d, length);
- result->baseString()->capacity = newCapacity;
-
- a->checkConsistency();
- b->checkConsistency();
- result->checkConsistency();
-
- return result;
-}
-
-PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, int i)
-{
- UChar buf[1 + sizeof(i) * 3];
- UChar* end = buf + sizeof(buf) / sizeof(UChar);
- UChar* p = end;
-
- if (i == 0)
- *--p = '0';
- else if (i == INT_MIN) {
- char minBuf[1 + sizeof(i) * 3];
- sprintf(minBuf, "%d", INT_MIN);
- return concatenate(rep, minBuf);
- } else {
- bool negative = false;
- if (i < 0) {
- negative = true;
- i = -i;
- }
- while (i) {
- *--p = static_cast<unsigned short>((i % 10) + '0');
- i /= 10;
- }
- if (negative)
- *--p = '-';
- }
-
- return concatenate(rep, p, static_cast<int>(end - p));
-
-}
-
-PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d)
+UString UString::createFromUTF8(const char* string)
{
- // avoid ever printing -NaN, in JS conceptually there is only one NaN value
- if (isnan(d))
- return concatenate(rep, "NaN");
-
- if (d == 0.0) // stringify -0 as 0
- d = 0.0;
+ if (!string)
+ return null();
- char buf[80];
- int decimalPoint;
- int sign;
+ size_t length = strlen(string);
+ Vector<UChar, 1024> buffer(length);
+ UChar* p = buffer.data();
+ if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length))
+ return null();
- char result[80];
- WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
- int length = static_cast<int>(strlen(result));
-
- int i = 0;
- if (sign)
- buf[i++] = '-';
-
- if (decimalPoint <= 0 && decimalPoint > -6) {
- buf[i++] = '0';
- buf[i++] = '.';
- for (int j = decimalPoint; j < 0; j++)
- buf[i++] = '0';
- strcpy(buf + i, result);
- } else if (decimalPoint <= 21 && decimalPoint > 0) {
- if (length <= decimalPoint) {
- strcpy(buf + i, result);
- i += length;
- for (int j = 0; j < decimalPoint - length; j++)
- buf[i++] = '0';
- buf[i] = '\0';
- } else {
- strncpy(buf + i, result, decimalPoint);
- i += decimalPoint;
- buf[i++] = '.';
- strcpy(buf + i, result + decimalPoint);
- }
- } else if (result[0] < '0' || result[0] > '9')
- strcpy(buf + i, result);
- else {
- buf[i++] = result[0];
- if (length > 1) {
- buf[i++] = '.';
- strcpy(buf + i, result + 1);
- i += length - 1;
- }
-
- buf[i++] = 'e';
- buf[i++] = (decimalPoint >= 0) ? '+' : '-';
- // decimalPoint can't be more than 3 digits decimal given the
- // nature of float representation
- int exponential = decimalPoint - 1;
- if (exponential < 0)
- exponential = -exponential;
- if (exponential >= 100)
- buf[i++] = static_cast<char>('0' + exponential / 100);
- if (exponential >= 10)
- buf[i++] = static_cast<char>('0' + (exponential % 100) / 10);
- buf[i++] = static_cast<char>('0' + exponential % 10);
- buf[i++] = '\0';
- }
-
- return concatenate(rep, buf);
+ return UString(buffer.data(), p - buffer.data());
}
UString UString::from(int i)
@@ -953,7 +268,7 @@ UString UString::from(long long i)
*--p = '0';
else if (i == std::numeric_limits<long long>::min()) {
char minBuf[1 + sizeof(i) * 3];
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
snprintf(minBuf, sizeof(minBuf) - 1, "%I64d", std::numeric_limits<long long>::min());
#else
snprintf(minBuf, sizeof(minBuf) - 1, "%lld", std::numeric_limits<long long>::min());
@@ -1025,69 +340,10 @@ UString UString::from(long l)
UString UString::from(double d)
{
- // avoid ever printing -NaN, in JS conceptually there is only one NaN value
- if (isnan(d))
- return "NaN";
- if (!d)
- return "0"; // -0 -> "0"
-
- char buf[80];
- int decimalPoint;
- int sign;
-
- char result[80];
- WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
- int length = static_cast<int>(strlen(result));
-
- int i = 0;
- if (sign)
- buf[i++] = '-';
-
- if (decimalPoint <= 0 && decimalPoint > -6) {
- buf[i++] = '0';
- buf[i++] = '.';
- for (int j = decimalPoint; j < 0; j++)
- buf[i++] = '0';
- strcpy(buf + i, result);
- } else if (decimalPoint <= 21 && decimalPoint > 0) {
- if (length <= decimalPoint) {
- strcpy(buf + i, result);
- i += length;
- for (int j = 0; j < decimalPoint - length; j++)
- buf[i++] = '0';
- buf[i] = '\0';
- } else {
- strncpy(buf + i, result, decimalPoint);
- i += decimalPoint;
- buf[i++] = '.';
- strcpy(buf + i, result + decimalPoint);
- }
- } else if (result[0] < '0' || result[0] > '9')
- strcpy(buf + i, result);
- else {
- buf[i++] = result[0];
- if (length > 1) {
- buf[i++] = '.';
- strcpy(buf + i, result + 1);
- i += length - 1;
- }
-
- buf[i++] = 'e';
- buf[i++] = (decimalPoint >= 0) ? '+' : '-';
- // decimalPoint can't be more than 3 digits decimal given the
- // nature of float representation
- int exponential = decimalPoint - 1;
- if (exponential < 0)
- exponential = -exponential;
- if (exponential >= 100)
- buf[i++] = static_cast<char>('0' + exponential / 100);
- if (exponential >= 10)
- buf[i++] = static_cast<char>('0' + (exponential % 100) / 10);
- buf[i++] = static_cast<char>('0' + exponential % 10);
- buf[i++] = '\0';
- }
-
- return UString(buf);
+ DtoaBuffer buffer;
+ unsigned length;
+ doubleToStringInJavaScriptFormat(d, buffer, &length);
+ return UString(buffer, length);
}
UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const
@@ -1113,23 +369,24 @@ UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, in
return "";
UChar* buffer;
- if (!allocChars(totalLength).getValue(buffer))
+ PassRefPtr<Rep> rep = Rep::tryCreateUninitialized(totalLength, buffer);
+ if (!rep)
return null();
int maxCount = max(rangeCount, separatorCount);
int bufferPos = 0;
for (int i = 0; i < maxCount; i++) {
if (i < rangeCount) {
- copyChars(buffer + bufferPos, data() + substringRanges[i].position, substringRanges[i].length);
+ UStringImpl::copyChars(buffer + bufferPos, data() + substringRanges[i].position, substringRanges[i].length);
bufferPos += substringRanges[i].length;
}
if (i < separatorCount) {
- copyChars(buffer + bufferPos, separators[i].data(), separators[i].size());
+ UStringImpl::copyChars(buffer + bufferPos, separators[i].data(), separators[i].size());
bufferPos += separators[i].size();
}
}
- return UString::Rep::create(buffer, totalLength);
+ return rep;
}
UString UString::replaceRange(int rangeStart, int rangeLength, const UString& replacement) const
@@ -1142,136 +399,16 @@ UString UString::replaceRange(int rangeStart, int rangeLength, const UString& re
return "";
UChar* buffer;
- if (!allocChars(totalLength).getValue(buffer))
+ PassRefPtr<Rep> rep = Rep::tryCreateUninitialized(totalLength, buffer);
+ if (!rep)
return null();
- copyChars(buffer, data(), rangeStart);
- copyChars(buffer + rangeStart, replacement.data(), replacementLength);
+ UStringImpl::copyChars(buffer, data(), rangeStart);
+ UStringImpl::copyChars(buffer + rangeStart, replacement.data(), replacementLength);
int rangeEnd = rangeStart + rangeLength;
- copyChars(buffer + rangeStart + replacementLength, data() + rangeEnd, size() - rangeEnd);
-
- return UString::Rep::create(buffer, totalLength);
-}
-
-
-UString& UString::append(const UString &t)
-{
- m_rep->checkConsistency();
- t.rep()->checkConsistency();
-
- int thisSize = size();
- int thisOffset = m_rep->offset;
- int tSize = t.size();
- int length = thisSize + tSize;
- BaseString* base = m_rep->baseString();
-
- // possible cases:
- if (thisSize == 0) {
- // this is empty
- *this = t;
- } else if (tSize == 0) {
- // t is empty
- } else if (m_rep == base && !base->isShared()) {
- // this is direct and has refcount of 1 (so we can just alter it directly)
- expandCapacity(newCapacityWithOverflowCheck(thisOffset, length));
- if (data()) {
- copyChars(m_rep->data() + thisSize, t.data(), tSize);
- m_rep->len = length;
- m_rep->_hash = 0;
- }
- } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
- // this reaches the end of the buffer - extend it if it's long enough to append to
- expandCapacity(newCapacityWithOverflowCheck(thisOffset, length));
- if (data()) {
- copyChars(m_rep->data() + thisSize, t.data(), tSize);
- m_rep = Rep::create(m_rep, 0, length);
- }
- } else {
- // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
- size_t newCapacity = expandedSize(length, 0);
- UChar* d;
- if (!allocChars(newCapacity).getValue(d))
- makeNull();
- else {
- copyChars(d, data(), thisSize);
- copyChars(d + thisSize, t.data(), tSize);
- m_rep = Rep::create(d, length);
- m_rep->baseString()->capacity = newCapacity;
- }
- }
-
- m_rep->checkConsistency();
- t.rep()->checkConsistency();
-
- return *this;
-}
-
-UString& UString::append(const UChar* tData, int tSize)
-{
- m_rep = concatenate(m_rep.release(), tData, tSize);
- return *this;
-}
-
-UString& UString::append(const char* t)
-{
- m_rep = concatenate(m_rep.release(), t);
- return *this;
-}
-
-UString& UString::append(UChar c)
-{
- m_rep->checkConsistency();
+ UStringImpl::copyChars(buffer + rangeStart + replacementLength, data() + rangeEnd, size() - rangeEnd);
- int thisOffset = m_rep->offset;
- int length = size();
- BaseString* base = m_rep->baseString();
-
- // possible cases:
- if (length == 0) {
- // this is empty - must make a new m_rep because we don't want to pollute the shared empty one
- size_t newCapacity = expandedSize(1, 0);
- UChar* d;
- if (!allocChars(newCapacity).getValue(d))
- makeNull();
- else {
- d[0] = c;
- m_rep = Rep::create(d, 1);
- m_rep->baseString()->capacity = newCapacity;
- }
- } else if (m_rep == base && !base->isShared()) {
- // this is direct and has refcount of 1 (so we can just alter it directly)
- expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true));
- UChar* d = m_rep->data();
- if (d) {
- d[length] = c;
- m_rep->len = length + 1;
- m_rep->_hash = 0;
- }
- } else if (thisOffset + length == base->usedCapacity && length >= minShareSize && !base->isBufferReadOnly()) {
- // this reaches the end of the string - extend it and share
- expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true));
- UChar* d = m_rep->data();
- if (d) {
- d[length] = c;
- m_rep = Rep::create(m_rep, 0, length + 1);
- }
- } else {
- // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
- size_t newCapacity = expandedSize(length + 1, 0);
- UChar* d;
- if (!allocChars(newCapacity).getValue(d))
- makeNull();
- else {
- copyChars(d, data(), length);
- d[length] = c;
- m_rep = Rep::create(d, length + 1);
- m_rep->baseString()->capacity = newCapacity;
- }
- }
-
- m_rep->checkConsistency();
-
- return *this;
+ return rep;
}
bool UString::getCString(CStringBuffer& buffer) const
@@ -1299,13 +436,15 @@ bool UString::getCString(CStringBuffer& buffer) const
char* UString::ascii() const
{
+ static char* asciiBuffer = 0;
+
int length = size();
int neededSize = length + 1;
- delete[] statBuffer;
- statBuffer = new char[neededSize];
+ delete[] asciiBuffer;
+ asciiBuffer = new char[neededSize];
const UChar* p = data();
- char* q = statBuffer;
+ char* q = asciiBuffer;
const UChar* limit = p + length;
while (p != limit) {
*q = static_cast<char>(p[0]);
@@ -1314,7 +453,7 @@ char* UString::ascii() const
}
*q = '\0';
- return statBuffer;
+ return asciiBuffer;
}
UString& UString::operator=(const char* c)
@@ -1330,21 +469,13 @@ UString& UString::operator=(const char* c)
}
int l = static_cast<int>(strlen(c));
- UChar* d;
- BaseString* base = m_rep->baseString();
- if (!base->isShared() && l <= base->capacity && m_rep == base && m_rep->offset == 0 && base->preCapacity == 0) {
- d = base->buf;
- m_rep->_hash = 0;
- m_rep->len = l;
- } else {
- if (!allocChars(l).getValue(d)) {
- makeNull();
- return *this;
- }
- m_rep = Rep::create(d, l);
- }
- for (int i = 0; i < l; i++)
- d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
+ UChar* d = 0;
+ m_rep = Rep::tryCreateUninitialized(l, d);
+ if (m_rep) {
+ for (int i = 0; i < l; i++)
+ d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
+ } else
+ makeNull();
return *this;
}
@@ -1502,7 +633,7 @@ uint32_t UString::toStrictUInt32(bool* ok) const
*ok = false;
// Empty string is not OK.
- int len = m_rep->len;
+ int len = m_rep->size();
if (len == 0)
return 0;
const UChar* p = m_rep->data();
@@ -1727,10 +858,15 @@ int compare(const UString& s1, const UString& s2)
return (l1 > l2) ? 1 : -1;
}
+#if OS(SOLARIS) && COMPILER(SUNCC)
+// Signature must match that of UStringImpl.h, otherwise the linker complains about undefined symbol.
+bool equal(const UStringImpl* r, const UStringImpl* b)
+#else
bool equal(const UString::Rep* r, const UString::Rep* b)
+#endif
{
- int length = r->len;
- if (length != b->len)
+ int length = r->size();
+ if (length != b->size())
return false;
const UChar* d = r->data();
const UChar* s = b->data();
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h
index 58c3615..c1f32db 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UString.h
@@ -24,6 +24,7 @@
#define UString_h
#include "Collector.h"
+#include "UStringImpl.h"
#include <stdint.h>
#include <string.h>
#include <wtf/Assertions.h>
@@ -35,13 +36,15 @@
#include <wtf/Vector.h>
#include <wtf/unicode/Unicode.h>
+#if PLATFORM(QT)
+#include <QtCore/qstring.h>
+#endif
+
namespace JSC {
using WTF::PlacementNewAdoptType;
using WTF::PlacementNewAdopt;
- class IdentifierTable;
-
class CString {
public:
CString()
@@ -71,192 +74,58 @@ namespace JSC {
char* m_data;
};
+ bool operator==(const CString&, const CString&);
+
typedef Vector<char, 32> CStringBuffer;
class UString {
friend class JIT;
public:
+#if PLATFORM(QT)
+ operator QT_PREPEND_NAMESPACE(QString)() const
+ {
+ return QT_PREPEND_NAMESPACE(QString)(reinterpret_cast<const QT_PREPEND_NAMESPACE(QChar)*>(this->data()), this->size());
+ }
- typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar;
- struct BaseString;
- struct Rep : Noncopyable {
- friend class JIT;
-
- static PassRefPtr<Rep> create(UChar* buffer, int length)
- {
- return adoptRef(new BaseString(buffer, length));
- }
-
- static PassRefPtr<Rep> createEmptyBuffer(size_t size)
- {
- // Guard against integer overflow
- if (size < (std::numeric_limits<size_t>::max() / sizeof(UChar))) {
- void* buf = 0;
- if (tryFastMalloc(size * sizeof(UChar)).getValue(buf))
- return adoptRef(new BaseString(static_cast<UChar*>(buf), 0, size));
- }
- return adoptRef(new BaseString(0, 0, 0));
- }
-
- static PassRefPtr<Rep> createCopying(const UChar*, int);
- static PassRefPtr<Rep> create(PassRefPtr<Rep> base, int offset, int length);
-
- // Constructs a string from a UTF-8 string, using strict conversion (see comments in UTF8.h).
- // Returns UString::Rep::null for null input or conversion failure.
- static PassRefPtr<Rep> createFromUTF8(const char*);
-
- // Uses SharedUChar to have joint ownership over the UChar*.
- static PassRefPtr<Rep> create(UChar*, int, PassRefPtr<SharedUChar>);
-
- SharedUChar* sharedBuffer();
- void destroy();
-
- bool baseIsSelf() const { return m_identifierTableAndFlags.isFlagSet(BaseStringFlag); }
- UChar* data() const;
- int size() const { return len; }
-
- unsigned hash() const { if (_hash == 0) _hash = computeHash(data(), len); return _hash; }
- unsigned computedHash() const { ASSERT(_hash); return _hash; } // fast path for Identifiers
-
- static unsigned computeHash(const UChar*, int length);
- static unsigned computeHash(const char*, int length);
- static unsigned computeHash(const char* s) { return computeHash(s, strlen(s)); }
-
- IdentifierTable* identifierTable() const { return m_identifierTableAndFlags.get(); }
- void setIdentifierTable(IdentifierTable* table) { ASSERT(!isStatic()); m_identifierTableAndFlags.set(table); }
-
- 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;
- PtrAndFlags<IdentifierTable, UStringFlags> m_identifierTableAndFlags;
-
- static BaseString& null() { return *nullBaseString; }
- static BaseString& empty() { return *emptyBaseString; }
-
- bool reserveCapacity(int capacity);
-
- protected:
- // Constructor for use by BaseString subclass; they use the union with m_baseString for another purpose.
- Rep(int length)
- : offset(0)
- , len(length)
- , rc(1)
- , _hash(0)
- , m_baseString(0)
- {
- }
-
- Rep(PassRefPtr<BaseString> base, int offsetInBase, int length)
- : offset(offsetInBase)
- , len(length)
- , rc(1)
- , _hash(0)
- , m_baseString(base.releaseRef())
- {
- checkConsistency();
- }
-
- union {
- // If !baseIsSelf()
- BaseString* m_baseString;
- // If baseIsSelf()
- SharedUChar* m_sharedBuffer;
- };
-
- private:
- // For SmallStringStorage which allocates an array and does initialization manually.
- Rep() { }
-
- friend class SmallStringsStorage;
- friend void initializeUString();
- JS_EXPORTDATA static BaseString* nullBaseString;
- JS_EXPORTDATA static BaseString* emptyBaseString;
- };
-
-
- struct BaseString : public Rep {
- bool isShared() { return rc != 1 || isBufferReadOnly(); }
- void setSharedBuffer(PassRefPtr<SharedUChar>);
-
- bool isBufferReadOnly()
- {
- if (!m_sharedBuffer)
- return false;
- return slowIsBufferReadOnly();
- }
-
- // potentially shared data.
- UChar* buf;
- int preCapacity;
- int usedPreCapacity;
- int capacity;
- int usedCapacity;
-
- size_t reportedCost;
-
- private:
- BaseString(UChar* buffer, int length, int additionalCapacity = 0)
- : Rep(length)
- , buf(buffer)
- , preCapacity(0)
- , usedPreCapacity(0)
- , capacity(length + additionalCapacity)
- , usedCapacity(length)
- , reportedCost(0)
- {
- m_identifierTableAndFlags.setFlag(BaseStringFlag);
- checkConsistency();
- }
-
- SharedUChar* sharedBuffer();
- bool slowIsBufferReadOnly();
-
- friend struct Rep;
- friend class SmallStringsStorage;
- friend void initializeUString();
- };
-
+ UString(const QT_PREPEND_NAMESPACE(QString)& str)
+ {
+ *this = JSC::UString(reinterpret_cast<const UChar*>(str.constData()), str.length());
+ }
+#endif
+ typedef UStringImpl Rep;
+
public:
+ // UString constructors passed char*s assume ISO Latin-1 encoding; for UTF8 use 'createFromUTF8', below.
UString();
- UString(const char*);
+ UString(const char*); // Constructor for null-terminated string.
+ UString(const char*, int length);
UString(const UChar*, int length);
- UString(UChar*, int length, bool copy);
+ UString(const Vector<UChar>& buffer);
UString(const UString& s)
: m_rep(s.m_rep)
{
}
- UString(const Vector<UChar>& buffer);
+ // Special constructor for cases where we overwrite an object in place.
+ UString(PlacementNewAdoptType)
+ : m_rep(PlacementNewAdopt)
+ {
+ }
~UString()
{
}
- // Special constructor for cases where we overwrite an object in place.
- UString(PlacementNewAdoptType)
- : m_rep(PlacementNewAdopt)
+ template<size_t inlineCapacity>
+ static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
{
+ return Rep::adopt(vector);
}
+ static UString createFromUTF8(const char*);
+
static UString from(int);
static UString from(long long);
static UString from(unsigned int);
@@ -283,12 +152,6 @@ namespace JSC {
UString replaceRange(int rangeStart, int RangeEnd, const UString& replacement) const;
- UString& append(const UString&);
- UString& append(const char*);
- UString& append(UChar);
- UString& append(char c) { return append(static_cast<UChar>(static_cast<unsigned char>(c))); }
- UString& append(const UChar*, int size);
-
bool getCString(CStringBuffer&) const;
// NOTE: This method should only be used for *debugging* purposes as it
@@ -307,13 +170,10 @@ namespace JSC {
UString& operator=(const char*c);
- UString& operator+=(const UString& s) { return append(s); }
- UString& operator+=(const char* s) { return append(s); }
-
const UChar* data() const { return m_rep->data(); }
- bool isNull() const { return (m_rep == &Rep::null()); }
- bool isEmpty() const { return (!m_rep->len); }
+ bool isNull() const { return m_rep == &Rep::null(); }
+ bool isEmpty() const { return !m_rep->size(); }
bool is8Bit() const;
@@ -349,36 +209,9 @@ namespace JSC {
ASSERT(m_rep);
}
- size_t cost() const;
-
- // Attempt to grow this string such that it can grow to a total length of 'capacity'
- // without reallocation. This may fail a number of reasons - if the BasicString is
- // shared and another string is using part of the capacity beyond our end point, if
- // the realloc fails, or if this string is empty and has no storage.
- //
- // This method returns a boolean indicating success.
- bool reserveCapacity(int capacity)
- {
- return m_rep->reserveCapacity(capacity);
- }
-
-#if PLATFORM(QT)
- operator QT_PREPEND_NAMESPACE(QString)() const
- {
- QT_USE_NAMESPACE;
- return QString(reinterpret_cast<const QChar*>(this->data()), this->size());
- }
-
- UString(const QT_PREPEND_NAMESPACE(QString)& str)
- {
- *this = JSC::UString(reinterpret_cast<const UChar*>(str.constData()), str.length());
- }
-#endif
-
+ size_t cost() const { return m_rep->cost(); }
private:
- void expandCapacity(int requiredLength);
- void expandPreCapacity(int requiredPreCap);
void makeNull();
RefPtr<Rep> m_rep;
@@ -386,13 +219,9 @@ namespace JSC {
friend void initializeUString();
friend bool operator==(const UString&, const UString&);
- friend PassRefPtr<Rep> concatenate(Rep*, Rep*); // returns 0 if out of memory
};
- PassRefPtr<UString::Rep> concatenate(UString::Rep*, UString::Rep*);
- PassRefPtr<UString::Rep> concatenate(UString::Rep*, int);
- PassRefPtr<UString::Rep> concatenate(UString::Rep*, double);
- inline bool operator==(const UString& s1, const UString& s2)
+ ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2)
{
int size = s1.size();
switch (size) {
@@ -438,72 +267,8 @@ namespace JSC {
return !JSC::operator==(s1, s2);
}
- bool operator==(const CString&, const CString&);
-
- inline UString operator+(const UString& s1, const UString& s2)
- {
- RefPtr<UString::Rep> result = concatenate(s1.rep(), s2.rep());
- return UString(result ? result.release() : UString::nullRep());
- }
-
int compare(const UString&, const UString&);
- bool equal(const UString::Rep*, const UString::Rep*);
-
- inline PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<UString::Rep> rep, int offset, int length)
- {
- ASSERT(rep);
- rep->checkConsistency();
-
- int repOffset = rep->offset;
-
- PassRefPtr<BaseString> base = rep->baseString();
-
- ASSERT(-(offset + repOffset) <= base->usedPreCapacity);
- ASSERT(offset + repOffset + length <= base->usedCapacity);
-
- // Steal the single reference this Rep was created with.
- return adoptRef(new Rep(base, repOffset + offset, length));
- }
-
- inline UChar* UString::Rep::data() const
- {
- const BaseString* base = baseString();
- 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);
- ASSERT(!baseIsSelf());
- m_baseString = base.releaseRef();
- }
-
- inline UString::BaseString* UString::Rep::baseString()
- {
- return !baseIsSelf() ? m_baseString : reinterpret_cast<BaseString*>(this) ;
- }
-
- inline const UString::BaseString* UString::Rep::baseString() const
- {
- return const_cast<Rep*>(this)->baseString();
- }
-
-#ifdef NDEBUG
- inline void UString::Rep::checkConsistency() const
- {
- }
-#endif
-
inline UString::UString()
: m_rep(&Rep::null())
{
@@ -524,45 +289,288 @@ namespace JSC {
// huge buffer.
// FIXME: this should be size_t but that would cause warnings until we
// fix UString sizes to be size_t instead of int
- static const int minShareSize = Heap::minExtraCostSize / sizeof(UChar);
+ static const int minShareSize = Heap::minExtraCost / sizeof(UChar);
- inline size_t UString::cost() const
- {
- BaseString* base = m_rep->baseString();
- size_t capacity = (base->capacity + base->preCapacity) * sizeof(UChar);
- size_t reportedCost = base->reportedCost;
- ASSERT(capacity >= reportedCost);
+ struct IdentifierRepHash : PtrHash<RefPtr<JSC::UString::Rep> > {
+ static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->existingHash(); }
+ static unsigned hash(JSC::UString::Rep* key) { return key->existingHash(); }
+ };
- size_t capacityDelta = capacity - reportedCost;
+ void initializeUString();
+
+ template<typename StringType>
+ class StringTypeAdapter {
+ };
- if (capacityDelta < static_cast<size_t>(minShareSize))
- return 0;
+ template<>
+ class StringTypeAdapter<char*> {
+ public:
+ StringTypeAdapter<char*>(char* buffer)
+ : m_buffer((unsigned char*)buffer)
+ , m_length(strlen(buffer))
+ {
+ }
- base->reportedCost = capacity;
+ unsigned length() { return m_length; }
- return capacityDelta;
- }
+ void writeTo(UChar* destination)
+ {
+ for (unsigned i = 0; i < m_length; ++i)
+ destination[i] = m_buffer[i];
+ }
-#if PLATFORM(QT)
+ private:
+ const unsigned char* m_buffer;
+ unsigned m_length;
+ };
- inline UString operator+(const char* s1, const UString& s2)
+ template<>
+ class StringTypeAdapter<const char*> {
+ public:
+ StringTypeAdapter<const char*>(const char* buffer)
+ : m_buffer((unsigned char*)buffer)
+ , m_length(strlen(buffer))
{
- return operator+(UString(s1), s2);
}
- inline UString operator+(const UString& s1, const char* s2)
+ unsigned length() { return m_length; }
+
+ void writeTo(UChar* destination)
{
- return operator+(s1, UString(s2));
+ for (unsigned i = 0; i < m_length; ++i)
+ destination[i] = m_buffer[i];
}
-#endif
+ private:
+ const unsigned char* m_buffer;
+ unsigned m_length;
+ };
- struct IdentifierRepHash : PtrHash<RefPtr<JSC::UString::Rep> > {
- static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->computedHash(); }
- static unsigned hash(JSC::UString::Rep* key) { return key->computedHash(); }
+ template<>
+ class StringTypeAdapter<UString> {
+ public:
+ StringTypeAdapter<UString>(UString& string)
+ : m_data(string.data())
+ , m_length(string.size())
+ {
+ }
+
+ unsigned length() { return m_length; }
+
+ void writeTo(UChar* destination)
+ {
+ for (unsigned i = 0; i < m_length; ++i)
+ destination[i] = m_data[i];
+ }
+
+ private:
+ const UChar* m_data;
+ unsigned m_length;
};
- void initializeUString();
+ template<typename StringType1, typename StringType2>
+ UString makeString(StringType1 string1, StringType2 string2)
+ {
+ StringTypeAdapter<StringType1> adapter1(string1);
+ StringTypeAdapter<StringType2> adapter2(string2);
+
+ UChar* buffer;
+ unsigned length = adapter1.length() + adapter2.length();
+ PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
+ if (!resultImpl)
+ return UString();
+
+ UChar* result = buffer;
+ adapter1.writeTo(result);
+ result += adapter1.length();
+ adapter2.writeTo(result);
+
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
+ {
+ StringTypeAdapter<StringType1> adapter1(string1);
+ StringTypeAdapter<StringType2> adapter2(string2);
+ StringTypeAdapter<StringType3> adapter3(string3);
+
+ UChar* buffer;
+ unsigned length = adapter1.length() + adapter2.length() + adapter3.length();
+ PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
+ if (!resultImpl)
+ return UString();
+
+ UChar* result = buffer;
+ adapter1.writeTo(result);
+ result += adapter1.length();
+ adapter2.writeTo(result);
+ result += adapter2.length();
+ adapter3.writeTo(result);
+
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+ {
+ StringTypeAdapter<StringType1> adapter1(string1);
+ StringTypeAdapter<StringType2> adapter2(string2);
+ StringTypeAdapter<StringType3> adapter3(string3);
+ StringTypeAdapter<StringType4> adapter4(string4);
+
+ UChar* buffer;
+ unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length();
+ PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
+ if (!resultImpl)
+ return UString();
+
+ UChar* result = buffer;
+ adapter1.writeTo(result);
+ result += adapter1.length();
+ adapter2.writeTo(result);
+ result += adapter2.length();
+ adapter3.writeTo(result);
+ result += adapter3.length();
+ adapter4.writeTo(result);
+
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+ {
+ StringTypeAdapter<StringType1> adapter1(string1);
+ StringTypeAdapter<StringType2> adapter2(string2);
+ StringTypeAdapter<StringType3> adapter3(string3);
+ StringTypeAdapter<StringType4> adapter4(string4);
+ StringTypeAdapter<StringType5> adapter5(string5);
+
+ UChar* buffer;
+ unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length();
+ PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
+ if (!resultImpl)
+ return UString();
+
+ UChar* result = buffer;
+ adapter1.writeTo(result);
+ result += adapter1.length();
+ adapter2.writeTo(result);
+ result += adapter2.length();
+ adapter3.writeTo(result);
+ result += adapter3.length();
+ adapter4.writeTo(result);
+ result += adapter4.length();
+ adapter5.writeTo(result);
+
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+ {
+ StringTypeAdapter<StringType1> adapter1(string1);
+ StringTypeAdapter<StringType2> adapter2(string2);
+ StringTypeAdapter<StringType3> adapter3(string3);
+ StringTypeAdapter<StringType4> adapter4(string4);
+ StringTypeAdapter<StringType5> adapter5(string5);
+ StringTypeAdapter<StringType6> adapter6(string6);
+
+ UChar* buffer;
+ unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length();
+ PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
+ if (!resultImpl)
+ return UString();
+
+ UChar* result = buffer;
+ adapter1.writeTo(result);
+ result += adapter1.length();
+ adapter2.writeTo(result);
+ result += adapter2.length();
+ adapter3.writeTo(result);
+ result += adapter3.length();
+ adapter4.writeTo(result);
+ result += adapter4.length();
+ adapter5.writeTo(result);
+ result += adapter5.length();
+ adapter6.writeTo(result);
+
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
+ {
+ StringTypeAdapter<StringType1> adapter1(string1);
+ StringTypeAdapter<StringType2> adapter2(string2);
+ StringTypeAdapter<StringType3> adapter3(string3);
+ StringTypeAdapter<StringType4> adapter4(string4);
+ StringTypeAdapter<StringType5> adapter5(string5);
+ StringTypeAdapter<StringType6> adapter6(string6);
+ StringTypeAdapter<StringType7> adapter7(string7);
+
+ UChar* buffer;
+ unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length();
+ PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
+ if (!resultImpl)
+ return UString();
+
+ UChar* result = buffer;
+ adapter1.writeTo(result);
+ result += adapter1.length();
+ adapter2.writeTo(result);
+ result += adapter2.length();
+ adapter3.writeTo(result);
+ result += adapter3.length();
+ adapter4.writeTo(result);
+ result += adapter4.length();
+ adapter5.writeTo(result);
+ result += adapter5.length();
+ adapter6.writeTo(result);
+ result += adapter6.length();
+ adapter7.writeTo(result);
+
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
+ {
+ StringTypeAdapter<StringType1> adapter1(string1);
+ StringTypeAdapter<StringType2> adapter2(string2);
+ StringTypeAdapter<StringType3> adapter3(string3);
+ StringTypeAdapter<StringType4> adapter4(string4);
+ StringTypeAdapter<StringType5> adapter5(string5);
+ StringTypeAdapter<StringType6> adapter6(string6);
+ StringTypeAdapter<StringType7> adapter7(string7);
+ StringTypeAdapter<StringType8> adapter8(string8);
+
+ UChar* buffer;
+ unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length() + adapter8.length();
+ PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
+ if (!resultImpl)
+ return UString();
+
+ UChar* result = buffer;
+ adapter1.writeTo(result);
+ result += adapter1.length();
+ adapter2.writeTo(result);
+ result += adapter2.length();
+ adapter3.writeTo(result);
+ result += adapter3.length();
+ adapter4.writeTo(result);
+ result += adapter4.length();
+ adapter5.writeTo(result);
+ result += adapter5.length();
+ adapter6.writeTo(result);
+ result += adapter6.length();
+ adapter7.writeTo(result);
+ result += adapter7.length();
+ adapter8.writeTo(result);
+
+ return resultImpl;
+ }
+
} // namespace JSC
namespace WTF {
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.cpp
new file mode 100644
index 0000000..4b0d1c9
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "UStringImpl.h"
+
+#include "Identifier.h"
+#include "UString.h"
+#include <wtf/unicode/UTF8.h>
+
+using namespace WTF::Unicode;
+using namespace std;
+
+namespace JSC {
+
+SharedUChar* UStringImpl::baseSharedBuffer()
+{
+ ASSERT((bufferOwnership() == BufferShared)
+ || ((bufferOwnership() == BufferOwned) && !m_dataBuffer.asPtr<void*>()));
+
+ if (bufferOwnership() != BufferShared)
+ m_dataBuffer = UntypedPtrAndBitfield(SharedUChar::create(new OwnFastMallocPtr<UChar>(m_data)).releaseRef(), BufferShared);
+
+ return m_dataBuffer.asPtr<SharedUChar*>();
+}
+
+SharedUChar* UStringImpl::sharedBuffer()
+{
+ if (m_length < s_minLengthToShare)
+ return 0;
+ ASSERT(!isStatic());
+
+ UStringImpl* owner = bufferOwnerString();
+ if (owner->bufferOwnership() == BufferInternal)
+ return 0;
+
+ return owner->baseSharedBuffer();
+}
+
+UStringImpl::~UStringImpl()
+{
+ ASSERT(!isStatic());
+ checkConsistency();
+
+ if (isIdentifier())
+ Identifier::remove(this);
+
+ if (bufferOwnership() != BufferInternal) {
+ if (bufferOwnership() == BufferOwned)
+ fastFree(m_data);
+ else if (bufferOwnership() == BufferSubstring)
+ m_dataBuffer.asPtr<UStringImpl*>()->deref();
+ else {
+ ASSERT(bufferOwnership() == BufferShared);
+ m_dataBuffer.asPtr<SharedUChar*>()->deref();
+ }
+ }
+}
+
+}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.h
new file mode 100644
index 0000000..4e1ddc7
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/UStringImpl.h
@@ -0,0 +1,313 @@
+/*
+ * 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 UStringImpl_h
+#define UStringImpl_h
+
+#include <limits>
+#include <wtf/CrossThreadRefCounted.h>
+#include <wtf/OwnFastMallocPtr.h>
+#include <wtf/PossiblyNull.h>
+#include <wtf/StringHashFunctions.h>
+#include <wtf/Vector.h>
+#include <wtf/unicode/Unicode.h>
+
+namespace JSC {
+
+class IdentifierTable;
+
+typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar;
+
+class UntypedPtrAndBitfield {
+public:
+ UntypedPtrAndBitfield() {}
+
+ UntypedPtrAndBitfield(void* ptrValue, uintptr_t bitValue)
+ : m_value(reinterpret_cast<uintptr_t>(ptrValue) | bitValue)
+#ifndef NDEBUG
+ , m_leaksPtr(ptrValue)
+#endif
+ {
+ ASSERT(ptrValue == asPtr<void*>());
+ ASSERT((*this & ~s_alignmentMask) == bitValue);
+ }
+
+ template<typename T>
+ T asPtr() const { return reinterpret_cast<T>(m_value & s_alignmentMask); }
+
+ UntypedPtrAndBitfield& operator&=(uintptr_t bits)
+ {
+ m_value &= bits | s_alignmentMask;
+ return *this;
+ }
+
+ UntypedPtrAndBitfield& operator|=(uintptr_t bits)
+ {
+ m_value |= bits & ~s_alignmentMask;
+ return *this;
+ }
+
+ uintptr_t operator&(uintptr_t mask) const
+ {
+ return m_value & mask & ~s_alignmentMask;
+ }
+
+private:
+ static const uintptr_t s_alignmentMask = ~static_cast<uintptr_t>(0x7);
+ uintptr_t m_value;
+#ifndef NDEBUG
+ void* m_leaksPtr; // Only used to allow tools like leaks on OSX to detect that the memory is referenced.
+#endif
+};
+
+class UStringImpl : Noncopyable {
+public:
+ template<size_t inlineCapacity>
+ static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
+ {
+ if (unsigned length = vector.size())
+ return adoptRef(new UStringImpl(vector.releaseBuffer(), length, BufferOwned));
+ return &empty();
+ }
+
+ static PassRefPtr<UStringImpl> create(const UChar* buffer, int length)
+ {
+ UChar* newBuffer;
+ if (PassRefPtr<UStringImpl> impl = tryCreateUninitialized(length, newBuffer)) {
+ copyChars(newBuffer, buffer, length);
+ return impl;
+ }
+ return &null();
+ }
+
+ static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, int offset, int length)
+ {
+ ASSERT(rep);
+ rep->checkConsistency();
+ return adoptRef(new UStringImpl(rep->m_data + offset, length, rep->bufferOwnerString()));
+ }
+
+ static PassRefPtr<UStringImpl> create(PassRefPtr<SharedUChar> sharedBuffer, UChar* buffer, int length)
+ {
+ return adoptRef(new UStringImpl(buffer, length, sharedBuffer));
+ }
+
+ static PassRefPtr<UStringImpl> createUninitialized(unsigned length, UChar*& output)
+ {
+ if (!length) {
+ output = 0;
+ return &empty();
+ }
+
+ if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar)))
+ CRASH();
+ UStringImpl* resultImpl = static_cast<UStringImpl*>(fastMalloc(sizeof(UChar) * length + sizeof(UStringImpl)));
+ output = reinterpret_cast<UChar*>(resultImpl + 1);
+ return adoptRef(new(resultImpl) UStringImpl(output, length, BufferInternal));
+ }
+
+ static PassRefPtr<UStringImpl> tryCreateUninitialized(unsigned length, UChar*& output)
+ {
+ if (!length) {
+ output = 0;
+ return &empty();
+ }
+
+ if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar)))
+ return 0;
+ UStringImpl* resultImpl;
+ if (!tryFastMalloc(sizeof(UChar) * length + sizeof(UStringImpl)).getValue(resultImpl))
+ return 0;
+ output = reinterpret_cast<UChar*>(resultImpl + 1);
+ return adoptRef(new(resultImpl) UStringImpl(output, length, BufferInternal));
+ }
+
+ SharedUChar* sharedBuffer();
+ UChar* data() const { return m_data; }
+ int size() const { return m_length; }
+ size_t cost()
+ {
+ // For substrings, return the cost of the base string.
+ if (bufferOwnership() == BufferSubstring)
+ return m_dataBuffer.asPtr<UStringImpl*>()->cost();
+
+ if (m_dataBuffer & s_reportedCostBit)
+ return 0;
+ m_dataBuffer |= s_reportedCostBit;
+ return m_length;
+ }
+ unsigned hash() const { if (!m_hash) m_hash = computeHash(data(), m_length); return m_hash; }
+ unsigned existingHash() const { ASSERT(m_hash); return m_hash; } // fast path for Identifiers
+ void setHash(unsigned hash) { ASSERT(hash == computeHash(data(), m_length)); m_hash = hash; } // fast path for Identifiers
+ bool isIdentifier() const { return m_isIdentifier; }
+ void setIsIdentifier(bool isIdentifier) { m_isIdentifier = isIdentifier; }
+
+ UStringImpl* ref() { m_refCount += s_refCountIncrement; return this; }
+ ALWAYS_INLINE void deref() { if (!(m_refCount -= s_refCountIncrement)) delete this; }
+
+ static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
+ {
+ if (numCharacters <= s_copyCharsInlineCutOff) {
+ for (unsigned i = 0; i < numCharacters; ++i)
+ destination[i] = source[i];
+ } else
+ memcpy(destination, source, numCharacters * sizeof(UChar));
+ }
+
+ static unsigned computeHash(const UChar* s, int length) { ASSERT(length >= 0); return WTF::stringHash(s, length); }
+ static unsigned computeHash(const char* s, int length) { ASSERT(length >= 0); return WTF::stringHash(s, length); }
+ static unsigned computeHash(const char* s) { return WTF::stringHash(s); }
+
+ static UStringImpl& null() { return *s_null; }
+ static UStringImpl& empty() { return *s_empty; }
+
+ ALWAYS_INLINE void checkConsistency() const
+ {
+ // There is no recursion of substrings.
+ ASSERT(bufferOwnerString()->bufferOwnership() != BufferSubstring);
+ // Static strings cannot be put in identifier tables, because they are globally shared.
+ ASSERT(!isStatic() || !isIdentifier());
+ }
+
+private:
+ enum BufferOwnership {
+ BufferInternal,
+ BufferOwned,
+ BufferSubstring,
+ BufferShared,
+ };
+
+ // For SmallStringStorage, which allocates an array and uses an in-place new.
+ UStringImpl() { }
+
+ // Used to construct normal strings with an internal or external buffer.
+ UStringImpl(UChar* data, int length, BufferOwnership ownership)
+ : m_data(data)
+ , m_length(length)
+ , m_refCount(s_refCountIncrement)
+ , m_hash(0)
+ , m_isIdentifier(false)
+ , m_dataBuffer(0, ownership)
+ {
+ ASSERT((ownership == BufferInternal) || (ownership == BufferOwned));
+ checkConsistency();
+ }
+
+ // Used to construct static strings, which have an special refCount that can never hit zero.
+ // This means that the static string will never be destroyed, which is important because
+ // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
+ enum StaticStringConstructType { ConstructStaticString };
+ UStringImpl(UChar* data, int length, StaticStringConstructType)
+ : m_data(data)
+ , m_length(length)
+ , m_refCount(s_staticRefCountInitialValue)
+ , m_hash(0)
+ , m_isIdentifier(false)
+ , m_dataBuffer(0, BufferOwned)
+ {
+ checkConsistency();
+ }
+
+ // Used to create new strings that are a substring of an existing string.
+ UStringImpl(UChar* data, int length, PassRefPtr<UStringImpl> base)
+ : m_data(data)
+ , m_length(length)
+ , m_refCount(s_refCountIncrement)
+ , m_hash(0)
+ , m_isIdentifier(false)
+ , m_dataBuffer(base.releaseRef(), BufferSubstring)
+ {
+ // Do use static strings as a base for substrings; UntypedPtrAndBitfield assumes
+ // that all pointers will be at least 8-byte aligned, we cannot guarantee that of
+ // UStringImpls that are not heap allocated.
+ ASSERT(m_dataBuffer.asPtr<UStringImpl*>()->size());
+ ASSERT(!m_dataBuffer.asPtr<UStringImpl*>()->isStatic());
+ checkConsistency();
+ }
+
+ // Used to construct new strings sharing an existing shared buffer.
+ UStringImpl(UChar* data, int length, PassRefPtr<SharedUChar> sharedBuffer)
+ : m_data(data)
+ , m_length(length)
+ , m_refCount(s_refCountIncrement)
+ , m_hash(0)
+ , m_isIdentifier(false)
+ , m_dataBuffer(sharedBuffer.releaseRef(), BufferShared)
+ {
+ checkConsistency();
+ }
+
+#if OS(SOLARIS) && COMPILER(SUNCC)
+public: // Otherwise the compiler complains about operator new not being accessible.
+#endif
+#if COMPILER(WINSCW) || COMPILER(XLC)
+ void* operator new(size_t size) { return Noncopyable::operator new(size); }
+#else
+ using Noncopyable::operator new;
+#endif
+#if OS(SOLARIS) && COMPILER(SUNCC)
+private:
+#endif
+ void* operator new(size_t, void* p) { return p; }
+
+ ~UStringImpl();
+
+ // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
+ static const int s_minLengthToShare = 10;
+ static const unsigned s_copyCharsInlineCutOff = 20;
+ static const uintptr_t s_bufferOwnershipMask = 3;
+ static const uintptr_t s_reportedCostBit = 4;
+ // We initialize and increment/decrement the refCount for all normal (non-static) strings by the value 2.
+ // We initialize static strings with an odd number (specifically, 1), such that the refCount cannot reach zero.
+ static const int s_refCountIncrement = 2;
+ static const int s_staticRefCountInitialValue = 1;
+
+ UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() : this; }
+ const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() : this; }
+ SharedUChar* baseSharedBuffer();
+ unsigned bufferOwnership() const { return m_dataBuffer & s_bufferOwnershipMask; }
+ bool isStatic() const { return m_refCount & 1; }
+
+ // unshared data
+ UChar* m_data;
+ int m_length;
+ unsigned m_refCount;
+ mutable unsigned m_hash : 31;
+ mutable unsigned m_isIdentifier : 1;
+ UntypedPtrAndBitfield m_dataBuffer;
+
+ JS_EXPORTDATA static UStringImpl* s_null;
+ JS_EXPORTDATA static UStringImpl* s_empty;
+
+ friend class JIT;
+ friend class SmallStringsStorage;
+ friend void initializeUString();
+};
+
+bool equal(const UStringImpl*, const UStringImpl*);
+
+}
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakGCMap.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakGCMap.h
new file mode 100644
index 0000000..39a91c5
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakGCMap.h
@@ -0,0 +1,122 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WeakGCMap_h
+#define WeakGCMap_h
+
+#include "Collector.h"
+#include <wtf/HashMap.h>
+
+namespace JSC {
+
+class JSCell;
+
+// A HashMap whose get() function returns emptyValue() for cells awaiting destruction.
+template<typename KeyType, typename MappedType>
+class WeakGCMap : public FastAllocBase {
+ /*
+ Invariants:
+ * A value enters the WeakGCMap marked. (Guaranteed by set().)
+ * A value that becomes unmarked leaves the WeakGCMap before being recycled. (Guaranteed by the value's destructor removing it from the WeakGCMap.)
+ * A value that becomes unmarked leaves the WeakGCMap before becoming marked again. (Guaranteed by all destructors running before the mark phase begins.)
+ * During the mark phase, all values in the WeakGCMap are valid. (Guaranteed by all destructors running before the mark phase begins.)
+ */
+
+public:
+ typedef typename HashMap<KeyType, MappedType>::iterator iterator;
+ typedef typename HashMap<KeyType, MappedType>::const_iterator const_iterator;
+
+ bool isEmpty() { return m_map.isEmpty(); }
+
+ MappedType get(const KeyType& key) const;
+ pair<iterator, bool> set(const KeyType&, const MappedType&);
+ MappedType take(const KeyType& key);
+
+ // These unchecked functions provide access to a value even if the value's
+ // mark bit is not set. This is used, among other things, to retrieve values
+ // during the GC mark phase, which begins by clearing all mark bits.
+
+ MappedType uncheckedGet(const KeyType& key) const { return m_map.get(key); }
+ bool uncheckedRemove(const KeyType&, const MappedType&);
+
+ iterator uncheckedBegin() { return m_map.begin(); }
+ iterator uncheckedEnd() { return m_map.end(); }
+
+ const_iterator uncheckedBegin() const { return m_map.begin(); }
+ const_iterator uncheckedEnd() const { return m_map.end(); }
+
+private:
+ HashMap<KeyType, MappedType> m_map;
+};
+
+template<typename KeyType, typename MappedType>
+inline MappedType WeakGCMap<KeyType, MappedType>::get(const KeyType& key) const
+{
+ MappedType result = m_map.get(key);
+ if (result == HashTraits<MappedType>::emptyValue())
+ return result;
+ if (!Heap::isCellMarked(result))
+ return HashTraits<MappedType>::emptyValue();
+ return result;
+}
+
+template<typename KeyType, typename MappedType>
+MappedType WeakGCMap<KeyType, MappedType>::take(const KeyType& key)
+{
+ MappedType result = m_map.take(key);
+ if (result == HashTraits<MappedType>::emptyValue())
+ return result;
+ if (!Heap::isCellMarked(result))
+ return HashTraits<MappedType>::emptyValue();
+ return result;
+}
+
+template<typename KeyType, typename MappedType>
+pair<typename HashMap<KeyType, MappedType>::iterator, bool> WeakGCMap<KeyType, MappedType>::set(const KeyType& key, const MappedType& value)
+{
+ Heap::markCell(value); // If value is newly allocated, it's not marked, so mark it now.
+ pair<iterator, bool> result = m_map.add(key, value);
+ if (!result.second) { // pre-existing entry
+ result.second = !Heap::isCellMarked(result.first->second);
+ result.first->second = value;
+ }
+ return result;
+}
+
+template<typename KeyType, typename MappedType>
+bool WeakGCMap<KeyType, MappedType>::uncheckedRemove(const KeyType& key, const MappedType& value)
+{
+ iterator it = m_map.find(key);
+ if (it == m_map.end())
+ return false;
+ if (it->second != value)
+ return false;
+ m_map.remove(it);
+ return true;
+}
+
+} // namespace JSC
+
+#endif // WeakGCMap_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakGCPtr.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakGCPtr.h
new file mode 100644
index 0000000..8653721
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakGCPtr.h
@@ -0,0 +1,128 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WeakGCPtr_h
+#define WeakGCPtr_h
+
+#include "Collector.h"
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+// A smart pointer whose get() function returns 0 for cells awaiting destruction.
+template <typename T> class WeakGCPtr : Noncopyable {
+public:
+ WeakGCPtr() : m_ptr(0) { }
+ WeakGCPtr(T* ptr) { assign(ptr); }
+
+ T* get() const
+ {
+ if (!m_ptr || !Heap::isCellMarked(m_ptr))
+ return 0;
+ return m_ptr;
+ }
+
+ void clear() { m_ptr = 0; }
+
+ T& operator*() const { return *get(); }
+ T* operator->() const { return get(); }
+
+ bool operator!() const { return !get(); }
+
+ // 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* WeakGCPtr::*UnspecifiedBoolType;
+ operator UnspecifiedBoolType() const { return get() ? &WeakGCPtr::m_ptr : 0; }
+#endif
+
+ WeakGCPtr& operator=(T*);
+
+private:
+ void assign(T* ptr)
+ {
+ if (ptr)
+ Heap::markCell(ptr);
+ m_ptr = ptr;
+ }
+
+ T* m_ptr;
+};
+
+template <typename T> inline WeakGCPtr<T>& WeakGCPtr<T>::operator=(T* optr)
+{
+ assign(optr);
+ return *this;
+}
+
+template <typename T, typename U> inline bool operator==(const WeakGCPtr<T>& a, const WeakGCPtr<U>& b)
+{
+ return a.get() == b.get();
+}
+
+template <typename T, typename U> inline bool operator==(const WeakGCPtr<T>& a, U* b)
+{
+ return a.get() == b;
+}
+
+template <typename T, typename U> inline bool operator==(T* a, const WeakGCPtr<U>& b)
+{
+ return a == b.get();
+}
+
+template <typename T, typename U> inline bool operator!=(const WeakGCPtr<T>& a, const WeakGCPtr<U>& b)
+{
+ return a.get() != b.get();
+}
+
+template <typename T, typename U> inline bool operator!=(const WeakGCPtr<T>& a, U* b)
+{
+ return a.get() != b;
+}
+
+template <typename T, typename U> inline bool operator!=(T* a, const WeakGCPtr<U>& b)
+{
+ return a != b.get();
+}
+
+template <typename T, typename U> inline WeakGCPtr<T> static_pointer_cast(const WeakGCPtr<U>& p)
+{
+ return WeakGCPtr<T>(static_cast<T*>(p.get()));
+}
+
+template <typename T, typename U> inline WeakGCPtr<T> const_pointer_cast(const WeakGCPtr<U>& p)
+{
+ return WeakGCPtr<T>(const_cast<T*>(p.get()));
+}
+
+template <typename T> inline T* getPtr(const WeakGCPtr<T>& p)
+{
+ return p.get();
+}
+
+} // namespace JSC
+
+#endif // WeakGCPtr_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakRandom.h b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakRandom.h
new file mode 100644
index 0000000..ff3995e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/WeakRandom.h
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ *
+ *
+ * Copyright (c) 2009 Ian C. Bullard
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * 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 AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef WeakRandom_h
+#define WeakRandom_h
+
+#include <limits.h>
+#include <wtf/StdLibExtras.h>
+
+namespace JSC {
+
+class WeakRandom {
+public:
+ WeakRandom(unsigned seed)
+ : m_low(seed ^ 0x49616E42)
+ , m_high(seed)
+ {
+ }
+
+ double get()
+ {
+ return advance() / (UINT_MAX + 1.0);
+ }
+
+private:
+ unsigned advance()
+ {
+ m_high = (m_high << 16) + (m_high >> 16);
+ m_high += m_low;
+ m_low += m_high;
+ return m_high;
+ }
+
+ unsigned m_low;
+ unsigned m_high;
+};
+
+} // namespace JSC
+
+#endif // WeakRandom_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WREC.h b/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WREC.h
index 483dce0..13324e7 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WREC.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WREC.h
@@ -32,7 +32,7 @@
#include <wtf/unicode/Unicode.h>
-#if COMPILER(GCC) && PLATFORM(X86)
+#if COMPILER(GCC) && CPU(X86)
#define WREC_CALL __attribute__ ((regparm (3)))
#else
#define WREC_CALL
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.cpp
index e62add3..7105984 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.cpp
@@ -40,7 +40,7 @@ namespace JSC { namespace WREC {
void Generator::generateEnter()
{
-#if PLATFORM(X86)
+#if CPU(X86)
// On x86 edi & esi are callee preserved registers.
push(X86Registers::edi);
push(X86Registers::esi);
@@ -71,7 +71,7 @@ void Generator::generateReturnSuccess()
store32(index, Address(output, 4)); // match end
// Restore callee save registers.
-#if PLATFORM(X86)
+#if CPU(X86)
pop(X86Registers::esi);
pop(X86Registers::edi);
#endif
@@ -110,7 +110,7 @@ void Generator::generateReturnFailure()
pop();
move(Imm32(-1), returnRegister);
-#if PLATFORM(X86)
+#if CPU(X86)
pop(X86Registers::esi);
pop(X86Registers::edi);
#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.h b/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.h
index 294c3d0..d707a6e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wrec/WRECGenerator.h
@@ -62,7 +62,7 @@ namespace JSC {
{
}
-#if PLATFORM(X86)
+#if CPU(X86)
static const RegisterID input = X86Registers::eax;
static const RegisterID index = X86Registers::edx;
static const RegisterID length = X86Registers::ecx;
@@ -73,7 +73,7 @@ namespace JSC {
static const RegisterID returnRegister = X86Registers::eax;
#endif
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
static const RegisterID input = X86Registers::edi;
static const RegisterID index = X86Registers::esi;
static const RegisterID length = X86Registers::edx;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wscript b/src/3rdparty/javascriptcore/JavaScriptCore/wscript
index 9dd37c9..356950f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wscript
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wscript
@@ -29,8 +29,8 @@ import commands
from settings import *
-jscore_excludes = ['jsc.cpp', 'ucptable.cpp', 'GOwnPtr.cpp']
-jscore_excludes.extend(get_excludes(jscore_dir, ['*CF.cpp']))
+jscore_excludes = ['jsc.cpp', 'ucptable.cpp']
+jscore_excludes.extend(get_excludes(jscore_dir, ['*CF.cpp', '*Symbian.cpp']))
sources = []
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/AlwaysInline.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/AlwaysInline.h
index 64fdd99..4e7224c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/AlwaysInline.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/AlwaysInline.h
@@ -23,7 +23,7 @@
#ifndef ALWAYS_INLINE
#if COMPILER(GCC) && defined(NDEBUG) && !COMPILER(MINGW)
#define ALWAYS_INLINE inline __attribute__((__always_inline__))
-#elif COMPILER(MSVC) && defined(NDEBUG)
+#elif (COMPILER(MSVC) || COMPILER(RVCT)) && defined(NDEBUG)
#define ALWAYS_INLINE __forceinline
#else
#define ALWAYS_INLINE inline
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.cpp
index 5af1377..4615810 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.cpp
@@ -35,7 +35,7 @@
#include <CoreFoundation/CFString.h>
#endif
-#if COMPILER(MSVC) && !PLATFORM(WINCE)
+#if COMPILER(MSVC) && !OS(WINCE)
#ifndef WINVER
#define WINVER 0x0500
#endif
@@ -46,7 +46,7 @@
#include <crtdbg.h>
#endif
-#if PLATFORM(WINCE)
+#if OS(WINCE)
#include <winbase.h>
#endif
@@ -85,7 +85,7 @@ static void vprintf_stderr_common(const char* format, va_list args)
break;
if (_vsnprintf(buffer, size, format, args) != -1) {
-#if PLATFORM(WINCE)
+#if OS(WINCE)
// WinCE only supports wide chars
wchar_t* wideBuffer = (wchar_t*)malloc(size * sizeof(wchar_t));
if (wideBuffer == NULL)
@@ -108,7 +108,7 @@ static void vprintf_stderr_common(const char* format, va_list args)
} while (size > 1024);
}
#endif
-#if PLATFORM(SYMBIAN)
+#if OS(SYMBIAN)
vfprintf(stdout, format, args);
#else
vfprintf(stderr, format, args);
@@ -126,7 +126,7 @@ static void printf_stderr_common(const char* format, ...)
static void printCallSite(const char* file, int line, const char* function)
{
-#if PLATFORM(WIN) && !PLATFORM(WINCE) && defined _DEBUG
+#if OS(WIN) && !OS(WINCE) && defined _DEBUG
_CrtDbgReport(_CRT_WARN, file, line, NULL, "%s\n", function);
#else
printf_stderr_common("(%s:%d %s)\n", file, line, function);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h
index f529a62..352a74b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Assertions.h
@@ -50,7 +50,7 @@
#include <inttypes.h>
#endif
-#if PLATFORM(SYMBIAN)
+#if OS(SYMBIAN)
#include <e32def.h>
#include <e32debug.h>
#endif
@@ -61,24 +61,50 @@
#define ASSERTIONS_DISABLED_DEFAULT 0
#endif
+#if COMPILER(MSVC7) || COMPILER(WINSCW)
+#define HAVE_VARIADIC_MACRO 0
+#else
+#define HAVE_VARIADIC_MACRO 1
+#endif
+
#ifndef ASSERT_DISABLED
#define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT
#endif
+#ifndef ASSERT_MSG_DISABLED
+#if HAVE(VARIADIC_MACRO)
+#define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT
+#else
+#define ASSERT_MSG_DISABLED 1
+#endif
+#endif
+
#ifndef ASSERT_ARG_DISABLED
#define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT
#endif
#ifndef FATAL_DISABLED
+#if HAVE(VARIADIC_MACRO)
#define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT
+#else
+#define FATAL_DISABLED 1
+#endif
#endif
#ifndef ERROR_DISABLED
+#if HAVE(VARIADIC_MACRO)
#define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT
+#else
+#define ERROR_DISABLED 1
+#endif
#endif
#ifndef LOG_DISABLED
+#if HAVE(VARIADIC_MACRO)
#define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT
+#else
+#define LOG_DISABLED 1
+#endif
#endif
#if COMPILER(GCC)
@@ -125,7 +151,7 @@ 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
-#if PLATFORM(SYMBIAN)
+#if OS(SYMBIAN)
#define CRASH() do { \
__DEBUGGER(); \
User::Panic(_L("Webkit CRASH"),0); \
@@ -138,9 +164,9 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
#endif
#endif
-/* ASSERT, ASSERT_WITH_MESSAGE, ASSERT_NOT_REACHED */
+/* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED */
-#if PLATFORM(WINCE) && !PLATFORM(TORCHMOBILE)
+#if OS(WINCE) && !PLATFORM(TORCHMOBILE)
/* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
#include <windows.h>
#undef min
@@ -148,7 +174,7 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
#undef ERROR
#endif
-#if PLATFORM(WIN_OS) || PLATFORM(SYMBIAN)
+#if OS(WINDOWS) || OS(SYMBIAN)
/* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
#undef ASSERT
#endif
@@ -156,13 +182,6 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
#if ASSERT_DISABLED
#define ASSERT(assertion) ((void)0)
-#if COMPILER(MSVC7)
-#define ASSERT_WITH_MESSAGE(assertion) ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define ASSERT_WITH_MESSAGE(assertion...) ((void)0)
-#else
-#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
-#endif /* COMPILER(MSVC7) */
#define ASSERT_NOT_REACHED() ((void)0)
#define ASSERT_UNUSED(variable, assertion) ((void)variable)
@@ -174,10 +193,24 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
CRASH(); \
} \
while (0)
+
+#define ASSERT_NOT_REACHED() do { \
+ WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
+ CRASH(); \
+} while (0)
+
+#define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
+
+#endif
+
+/* ASSERT_WITH_MESSAGE */
+
#if COMPILER(MSVC7)
#define ASSERT_WITH_MESSAGE(assertion) ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define ASSERT_WITH_MESSAGE(assertion...) ((void)0)
+#elif COMPILER(WINSCW)
+#define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0)
+#elif ASSERT_MSG_DISABLED
+#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
#else
#define ASSERT_WITH_MESSAGE(assertion, ...) do \
if (!(assertion)) { \
@@ -185,16 +218,9 @@ while (0)
CRASH(); \
} \
while (0)
-#endif /* COMPILER(MSVC7) */
-#define ASSERT_NOT_REACHED() do { \
- WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
- CRASH(); \
-} while (0)
-
-#define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
-
#endif
-
+
+
/* ASSERT_ARG */
#if ASSERT_ARG_DISABLED
@@ -219,12 +245,12 @@ while (0)
/* FATAL */
-#if FATAL_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN)
-#define FATAL(...) ((void)0)
-#elif COMPILER(MSVC7)
+#if COMPILER(MSVC7)
#define FATAL() ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define FATAL(args...) ((void)0)
+#elif COMPILER(WINSCW)
+#define FATAL(arg...) ((void)0)
+#elif FATAL_DISABLED
+#define FATAL(...) ((void)0)
#else
#define FATAL(...) do { \
WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
@@ -234,24 +260,24 @@ while (0)
/* LOG_ERROR */
-#if ERROR_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN)
-#define LOG_ERROR(...) ((void)0)
-#elif COMPILER(MSVC7)
+#if COMPILER(MSVC7)
#define LOG_ERROR() ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define LOG_ERROR(args...) ((void)0)
+#elif COMPILER(WINSCW)
+#define LOG_ERROR(arg...) ((void)0)
+#elif ERROR_DISABLED
+#define LOG_ERROR(...) ((void)0)
#else
#define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
#endif
/* LOG */
-#if LOG_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN)
-#define LOG(channel, ...) ((void)0)
-#elif COMPILER(MSVC7)
+#if COMPILER(MSVC7)
#define LOG() ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define LOG(channel, args...) ((void)0)
+#elif COMPILER(WINSCW)
+#define LOG(arg...) ((void)0)
+#elif LOG_DISABLED
+#define LOG(channel, ...) ((void)0)
#else
#define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
#define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
@@ -260,12 +286,12 @@ while (0)
/* LOG_VERBOSE */
-#if LOG_DISABLED && !COMPILER(MSVC7) && !PLATFORM(SYMBIAN)
-#define LOG_VERBOSE(channel, ...) ((void)0)
-#elif COMPILER(MSVC7)
+#if COMPILER(MSVC7)
#define LOG_VERBOSE(channel) ((void)0)
-#elif PLATFORM(SYMBIAN)
-#define LOG_VERBOSE(channel, args...) ((void)0)
+#elif COMPILER(WINSCW)
+#define LOG_VERBOSE(channel, arg...) ((void)0)
+#elif LOG_DISABLED
+#define LOG_VERBOSE(channel, ...) ((void)0)
#else
#define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CrossThreadRefCounted.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CrossThreadRefCounted.h
index 6a05211..f682f0d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CrossThreadRefCounted.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CrossThreadRefCounted.h
@@ -70,10 +70,6 @@ namespace WTF {
return !m_refCounter.hasOneRef() || (m_threadSafeRefCounter && !m_threadSafeRefCounter->hasOneRef());
}
-#ifndef NDEBUG
- bool mayBePassedToAnotherThread() const { ASSERT(!m_threadId); return m_refCounter.hasOneRef(); }
-#endif
-
private:
CrossThreadRefCounted(T* data, ThreadSafeSharedBase* threadedCounter)
: m_threadSafeRefCounter(threadedCounter)
@@ -92,6 +88,10 @@ namespace WTF {
void threadSafeDeref();
+#ifndef NDEBUG
+ bool isOwnedByCurrentThread() const { return !m_threadId || m_threadId == currentThread(); }
+#endif
+
RefCountedBase m_refCounter;
ThreadSafeSharedBase* m_threadSafeRefCounter;
T* m_data;
@@ -103,7 +103,7 @@ namespace WTF {
template<class T>
void CrossThreadRefCounted<T>::ref()
{
- ASSERT(!m_threadId || m_threadId == currentThread());
+ ASSERT(isOwnedByCurrentThread());
m_refCounter.ref();
#ifndef NDEBUG
// Store the threadId as soon as the ref count gets to 2.
@@ -119,7 +119,7 @@ namespace WTF {
template<class T>
void CrossThreadRefCounted<T>::deref()
{
- ASSERT(!m_threadId || m_threadId == currentThread());
+ ASSERT(isOwnedByCurrentThread());
if (m_refCounter.derefBase()) {
threadSafeDeref();
delete this;
@@ -146,10 +146,12 @@ namespace WTF {
template<class T>
PassRefPtr<CrossThreadRefCounted<T> > CrossThreadRefCounted<T>::crossThreadCopy()
{
+ ASSERT(isOwnedByCurrentThread());
if (m_threadSafeRefCounter)
m_threadSafeRefCounter->ref();
else
m_threadSafeRefCounter = new ThreadSafeSharedBase(2);
+
return adoptRef(new CrossThreadRefCounted<T>(m_data, m_threadSafeRefCounter));
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.cpp
index a3d5290..b272874 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.cpp
@@ -33,7 +33,7 @@
#include "config.h"
#include "CurrentTime.h"
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
// Windows is first since we want to use hires timers, despite PLATFORM(CF)
// being defined.
@@ -45,7 +45,7 @@
#include <time.h>
#if USE(QUERY_PERFORMANCE_COUNTER)
-#if PLATFORM(WINCE)
+#if OS(WINCE)
extern "C" time_t mktime(struct tm *t);
#else
#include <sys/timeb.h>
@@ -63,11 +63,15 @@ extern "C" time_t mktime(struct tm *t);
#include <sys/time.h>
#endif
+#if PLATFORM(CHROMIUM)
+#error Chromium uses a different timer implementation
+#endif
+
namespace WTF {
const double msPerSecond = 1000.0;
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#if USE(QUERY_PERFORMANCE_COUNTER)
@@ -119,7 +123,7 @@ static double highResUpTime()
static double lowResUTCTime()
{
-#if PLATFORM(WINCE)
+#if OS(WINCE)
SYSTEMTIME systemTime;
GetSystemTime(&systemTime);
struct tm tmtime;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.h
index 31f1ec8..334a6e9 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/CurrentTime.h
@@ -32,13 +32,32 @@
#ifndef CurrentTime_h
#define CurrentTime_h
+#include <time.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
+ // Returns the current UTC time in seconds, counted from January 1, 1970.
+ // Precision varies depending on platform but is usually as good or better
// than a millisecond.
double currentTime();
+ // Same thing, in milliseconds.
+ inline double currentTimeMS()
+ {
+ return currentTime() * 1000.0;
+ }
+
+ inline void getLocalTime(const time_t* localTime, struct tm* localTM)
+ {
+ #if COMPILER(MSVC7) || COMPILER(MINGW) || OS(WINCE)
+ *localTM = *localtime(localTime);
+ #elif COMPILER(MSVC)
+ localtime_s(localTM, localTime);
+ #else
+ localtime_r(localTime, localTM);
+ #endif
+ }
+
} // namespace WTF
using WTF::currentTime;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp
index 0386494..b9a0207 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.cpp
@@ -39,6 +39,33 @@
* other provisions required by the MPL or the GPL, as the case may be.
* If you do not delete the provisions above, a recipient may use your
* version of this file under any of the LGPL, the MPL or the GPL.
+
+ * Copyright 2006-2008 the V8 project authors. 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"
@@ -61,11 +88,7 @@
#include <errno.h>
#endif
-#if PLATFORM(DARWIN)
-#include <notify.h>
-#endif
-
-#if PLATFORM(WINCE)
+#if OS(WINCE)
extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t);
extern "C" struct tm * localtime(const time_t *timer);
#endif
@@ -78,8 +101,14 @@ extern "C" struct tm * localtime(const time_t *timer);
#include <sys/timeb.h>
#endif
+#if USE(JSC)
+#include "CallFrame.h"
+#endif
+
#define NaN std::numeric_limits<double>::quiet_NaN()
+using namespace WTF;
+
namespace WTF {
/* Constants */
@@ -91,6 +120,10 @@ static const double secondsPerYear = 24.0 * 60.0 * 60.0 * 365.0;
static const double usecPerSec = 1000000.0;
static const double maxUnixTime = 2145859200.0; // 12/31/2037
+// ECMAScript asks not to support for a date of which total
+// millisecond value is larger than the following value.
+// See 15.9.1.14 of ECMA-262 5th edition.
+static const double maxECMAScriptTime = 8.64E15;
// Day of year for the first day of each month, where index 0 is January, and day 0 is January 1.
// First for non-leap years, then for leap years.
@@ -139,7 +172,7 @@ static inline double msToDays(double ms)
return floor(ms / msPerDay);
}
-static inline int msToYear(double ms)
+int msToYear(double ms)
{
int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970);
double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear);
@@ -150,7 +183,7 @@ static inline int msToYear(double ms)
return approxYear;
}
-static inline int dayInYear(double ms, int year)
+int dayInYear(double ms, int year)
{
return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year));
}
@@ -196,7 +229,7 @@ static inline int msToHours(double ms)
return static_cast<int>(result);
}
-static inline int monthFromDayInYear(int dayInYear, bool leapYear)
+int monthFromDayInYear(int dayInYear, bool leapYear)
{
const int d = dayInYear;
int step;
@@ -234,7 +267,7 @@ static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& star
return (dayInYear <= startDayOfNextMonth);
}
-static inline int dayInMonthFromDayInYear(int dayInYear, bool leapYear)
+int dayInMonthFromDayInYear(int dayInYear, bool leapYear)
{
const int d = dayInYear;
int step;
@@ -277,7 +310,7 @@ static inline double timeToMS(double hour, double min, double sec, double ms)
return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms);
}
-static int dateToDayInYear(int year, int month, int day)
+double dateToDaysFrom1970(int year, int month, int day)
{
year += month / 12;
@@ -287,34 +320,13 @@ static int dateToDayInYear(int year, int month, int day)
--year;
}
- int yearday = static_cast<int>(floor(daysFrom1970ToYear(year)));
+ double yearday = floor(daysFrom1970ToYear(year));
+ ASSERT((year >= 1970 && yearday >= 0) || (year < 1970 && yearday < 0));
int monthday = monthToDayInYear(month, isLeapYear(year));
return yearday + monthday + day - 1;
}
-double getCurrentUTCTime()
-{
- return floor(getCurrentUTCTimeWithMicroseconds());
-}
-
-// Returns current time in milliseconds since 1 Jan 1970.
-double getCurrentUTCTimeWithMicroseconds()
-{
- return currentTime() * 1000.0;
-}
-
-void getLocalTime(const time_t* localTime, struct tm* localTM)
-{
-#if COMPILER(MSVC7) || COMPILER(MINGW) || PLATFORM(WINCE)
- *localTM = *localtime(localTime);
-#elif COMPILER(MSVC)
- localtime_s(localTM, localTime);
-#else
- localtime_r(localTime, localTM);
-#endif
-}
-
// There is a hard limit at 2038 that we currently do not have a workaround
// for (rdar://problem/5052975).
static inline int maximumYearForDST()
@@ -328,7 +340,7 @@ static inline int minimumYearForDST()
// greater than the max year minus 27 (2010), we want to use the max year
// minus 27 instead, to ensure there is a range of 28 years that all years
// can map to.
- return std::min(msToYear(getCurrentUTCTime()), maximumYearForDST() - 27) ;
+ return std::min(msToYear(jsCurrentTime()), maximumYearForDST() - 27) ;
}
/*
@@ -367,7 +379,11 @@ int equivalentYearForDST(int year)
static int32_t calculateUTCOffset()
{
+#if PLATFORM(BREWMP)
+ time_t localTime = static_cast<time_t>(currentTime());
+#else
time_t localTime = time(0);
+#endif
tm localt;
getLocalTime(&localTime, &localt);
@@ -399,44 +415,10 @@ static int32_t calculateUTCOffset()
return static_cast<int32_t>(utcOffset * 1000);
}
-#if PLATFORM(DARWIN)
-static int32_t s_cachedUTCOffset; // In milliseconds. An assumption here is that access to an int32_t variable is atomic on platforms that take this code path.
-static bool s_haveCachedUTCOffset;
-static int s_notificationToken;
-#endif
-
-/*
- * Get the difference in milliseconds between this time zone and UTC (GMT)
- * NOT including DST.
- */
-double getUTCOffset()
-{
-#if PLATFORM(DARWIN)
- if (s_haveCachedUTCOffset) {
- int notified;
- uint32_t status = notify_check(s_notificationToken, &notified);
- if (status == NOTIFY_STATUS_OK && !notified)
- return s_cachedUTCOffset;
- }
-#endif
-
- int32_t utcOffset = calculateUTCOffset();
-
-#if PLATFORM(DARWIN)
- // Theoretically, it is possible that several threads will be executing this code at once, in which case we will have a race condition,
- // and a newer value may be overwritten. In practice, time zones don't change that often.
- s_cachedUTCOffset = utcOffset;
-#endif
-
- return utcOffset;
-}
-
/*
- * Get the DST offset for the time passed in. Takes
- * seconds (not milliseconds) and cannot handle dates before 1970
- * on some OS'
+ * Get the DST offset for the time passed in.
*/
-static double getDSTOffsetSimple(double localTimeSeconds, double utcOffset)
+static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset)
{
if (localTimeSeconds > maxUnixTime)
localTimeSeconds = maxUnixTime;
@@ -465,9 +447,9 @@ static double getDSTOffsetSimple(double localTimeSeconds, double utcOffset)
}
// Get the DST offset, given a time in UTC
-static double getDSTOffset(double ms, double utcOffset)
+static double calculateDSTOffset(double ms, double utcOffset)
{
- // On Mac OS X, the call to localtime (see getDSTOffsetSimple) will return historically accurate
+ // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will return historically accurate
// DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript
// standard explicitly dictates that historical information should not be considered when
// determining DST. For this reason we shift away from years that localtime can handle but would
@@ -479,70 +461,22 @@ static double getDSTOffset(double ms, double utcOffset)
int dayInYearLocal = dayInYear(ms, year);
int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear);
int month = monthFromDayInYear(dayInYearLocal, leapYear);
- int day = dateToDayInYear(equivalentYear, month, dayInMonth);
+ double day = dateToDaysFrom1970(equivalentYear, month, dayInMonth);
ms = (day * msPerDay) + msToMilliseconds(ms);
}
- return getDSTOffsetSimple(ms / msPerSecond, utcOffset);
-}
-
-double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
-{
- int day = dateToDayInYear(t.year + 1900, t.month, t.monthDay);
- double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds);
- double result = (day * msPerDay) + ms;
-
- if (!inputIsUTC) { // convert to UTC
- double utcOffset = getUTCOffset();
- result -= utcOffset;
- result -= getDSTOffset(result, utcOffset);
- }
-
- return result;
-}
-
-void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm)
-{
- // input is UTC
- double dstOff = 0.0;
- const double utcOff = getUTCOffset();
-
- if (!outputIsUTC) { // convert to local time
- dstOff = getDSTOffset(ms, utcOff);
- ms += dstOff + utcOff;
- }
-
- const int year = msToYear(ms);
- tm.second = msToSeconds(ms);
- tm.minute = msToMinutes(ms);
- tm.hour = msToHours(ms);
- tm.weekDay = msToWeekDay(ms);
- tm.yearDay = dayInYear(ms, year);
- tm.monthDay = dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year));
- tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year));
- tm.year = year - 1900;
- tm.isDST = dstOff != 0.0;
-
- tm.utcOffset = outputIsUTC ? 0 : static_cast<long>((dstOff + utcOff) / msPerSecond);
- tm.timeZone = NULL;
+ return calculateDSTOffsetSimple(ms / msPerSecond, utcOffset);
}
void initializeDates()
{
#ifndef NDEBUG
static bool alreadyInitialized;
- ASSERT(!alreadyInitialized++);
+ ASSERT(!alreadyInitialized);
+ alreadyInitialized = true;
#endif
equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.
-#if PLATFORM(DARWIN)
- // Register for a notification whenever the time zone changes.
- uint32_t status = notify_register_check("com.apple.system.timezone", &s_notificationToken);
- if (status == NOTIFY_STATUS_OK) {
- s_cachedUTCOffset = calculateUTCOffset();
- s_haveCachedUTCOffset = true;
- }
-#endif
}
static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, int second)
@@ -558,7 +492,7 @@ static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int
// We follow the recommendation of RFC 2822 to consider all
// obsolete time zones not listed here equivalent to "-0000".
static const struct KnownZone {
-#if !PLATFORM(WIN_OS)
+#if !OS(WINDOWS)
const
#endif
char tzName[4];
@@ -623,8 +557,12 @@ static bool parseLong(const char* string, char** stopPosition, int base, long* r
return true;
}
-double parseDateFromNullTerminatedCharacters(const char* dateString)
+// Odd case where 'exec' is allowed to be 0, to accomodate a caller in WebCore.
+static double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset)
{
+ haveTZ = false;
+ offset = 0;
+
// This parses a date in the form:
// Tuesday, 09-Nov-99 23:12:40 GMT
// or
@@ -825,9 +763,6 @@ double parseDateFromNullTerminatedCharacters(const char* dateString)
}
}
- bool haveTZ = false;
- int offset = 0;
-
// Don't fail if the time zone is missing.
// Some websites omit the time zone (4275206).
if (*dateString) {
@@ -890,33 +825,172 @@ double parseDateFromNullTerminatedCharacters(const char* dateString)
else
year += 1900;
}
+
+ return ymdhmsToSeconds(year, month + 1, day, hour, minute, second) * msPerSecond;
+}
+
+double parseDateFromNullTerminatedCharacters(const char* dateString)
+{
+ bool haveTZ;
+ int offset;
+ double ms = parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
+ if (isnan(ms))
+ return NaN;
// fall back to local timezone
if (!haveTZ) {
- GregorianDateTime t;
- t.monthDay = day;
- t.month = month;
- t.year = year - 1900;
- t.isDST = -1;
- t.second = second;
- t.minute = minute;
- t.hour = hour;
-
- // Use our gregorianDateTimeToMS() rather than mktime() as the latter can't handle the full year range.
- return gregorianDateTimeToMS(t, 0, false);
+ double utcOffset = calculateUTCOffset();
+ double dstOffset = calculateDSTOffset(ms, utcOffset);
+ offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
}
-
- return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond;
+ return ms - (offset * msPerMinute);
}
double timeClip(double t)
{
if (!isfinite(t))
return NaN;
- if (fabs(t) > 8.64E15)
+ if (fabs(t) > maxECMAScriptTime)
return NaN;
return trunc(t);
}
+} // namespace WTF
+
+#if USE(JSC)
+namespace JSC {
+
+// Get the DST offset for the time passed in.
+//
+// NOTE: The implementation relies on the fact that no time zones have
+// more than one daylight savings offset change per month.
+// If this function is called with NaN it returns NaN.
+static double getDSTOffset(ExecState* exec, double ms, double utcOffset)
+{
+ DSTOffsetCache& cache = exec->globalData().dstOffsetCache;
+ double start = cache.start;
+ double end = cache.end;
+
+ if (start <= ms) {
+ // If the time fits in the cached interval, return the cached offset.
+ if (ms <= end) return cache.offset;
+
+ // Compute a possible new interval end.
+ double newEnd = end + cache.increment;
+
+ if (ms <= newEnd) {
+ double endOffset = calculateDSTOffset(newEnd, utcOffset);
+ if (cache.offset == endOffset) {
+ // If the offset at the end of the new interval still matches
+ // the offset in the cache, we grow the cached time interval
+ // and return the offset.
+ cache.end = newEnd;
+ cache.increment = msPerMonth;
+ return endOffset;
+ } else {
+ double offset = calculateDSTOffset(ms, utcOffset);
+ if (offset == endOffset) {
+ // The offset at the given time is equal to the offset at the
+ // new end of the interval, so that means that we've just skipped
+ // the point in time where the DST offset change occurred. Updated
+ // the interval to reflect this and reset the increment.
+ cache.start = ms;
+ cache.end = newEnd;
+ cache.increment = msPerMonth;
+ } else {
+ // The interval contains a DST offset change and the given time is
+ // before it. Adjust the increment to avoid a linear search for
+ // the offset change point and change the end of the interval.
+ cache.increment /= 3;
+ cache.end = ms;
+ }
+ // Update the offset in the cache and return it.
+ cache.offset = offset;
+ return offset;
+ }
+ }
+ }
+
+ // Compute the DST offset for the time and shrink the cache interval
+ // to only contain the time. This allows fast repeated DST offset
+ // computations for the same time.
+ double offset = calculateDSTOffset(ms, utcOffset);
+ cache.offset = offset;
+ cache.start = ms;
+ cache.end = ms;
+ cache.increment = msPerMonth;
+ return offset;
+}
+
+/*
+ * Get the difference in milliseconds between this time zone and UTC (GMT)
+ * NOT including DST.
+ */
+double getUTCOffset(ExecState* exec)
+{
+ double utcOffset = exec->globalData().cachedUTCOffset;
+ if (!isnan(utcOffset))
+ return utcOffset;
+ exec->globalData().cachedUTCOffset = calculateUTCOffset();
+ return exec->globalData().cachedUTCOffset;
+}
+double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
+{
+ double day = dateToDaysFrom1970(t.year + 1900, t.month, t.monthDay);
+ double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds);
+ double result = (day * WTF::msPerDay) + ms;
-} // namespace WTF
+ if (!inputIsUTC) { // convert to UTC
+ double utcOffset = getUTCOffset(exec);
+ result -= utcOffset;
+ result -= getDSTOffset(exec, result, utcOffset);
+ }
+
+ return result;
+}
+
+// input is UTC
+void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm)
+{
+ double dstOff = 0.0;
+ double utcOff = 0.0;
+ if (!outputIsUTC) {
+ utcOff = getUTCOffset(exec);
+ dstOff = getDSTOffset(exec, ms, utcOff);
+ ms += dstOff + utcOff;
+ }
+
+ const int year = msToYear(ms);
+ tm.second = msToSeconds(ms);
+ tm.minute = msToMinutes(ms);
+ tm.hour = msToHours(ms);
+ tm.weekDay = msToWeekDay(ms);
+ tm.yearDay = dayInYear(ms, year);
+ tm.monthDay = dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year));
+ tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year));
+ tm.year = year - 1900;
+ tm.isDST = dstOff != 0.0;
+ tm.utcOffset = static_cast<long>((dstOff + utcOff) / WTF::msPerSecond);
+ tm.timeZone = NULL;
+}
+
+double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateString)
+{
+ ASSERT(exec);
+ bool haveTZ;
+ int offset;
+ double ms = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
+ if (isnan(ms))
+ return NaN;
+
+ // fall back to local timezone
+ if (!haveTZ) {
+ double utcOffset = getUTCOffset(exec);
+ double dstOffset = getDSTOffset(exec, ms, utcOffset);
+ offset = static_cast<int>((utcOffset + dstOffset) / WTF::msPerMinute);
+ }
+ return ms - (offset * WTF::msPerMinute);
+}
+
+} // namespace JSC
+#endif // USE(JSC)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.h
index 6110f76..033d25e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/DateMath.h
@@ -42,27 +42,27 @@
#ifndef DateMath_h
#define DateMath_h
-#include <time.h>
+#include <math.h>
#include <string.h>
+#include <time.h>
+#include <wtf/CurrentTime.h>
#include <wtf/Noncopyable.h>
+#include <wtf/UnusedParam.h>
namespace WTF {
-
-struct GregorianDateTime;
-
void initializeDates();
-void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&);
-double gregorianDateTimeToMS(const GregorianDateTime&, double, bool inputIsUTC);
-double getUTCOffset();
int equivalentYearForDST(int year);
-double getCurrentUTCTime();
-double getCurrentUTCTimeWithMicroseconds();
-void getLocalTime(const time_t*, tm*);
// Not really math related, but this is currently the only shared place to put these.
-double parseDateFromNullTerminatedCharacters(const char*);
+double parseDateFromNullTerminatedCharacters(const char* dateString);
double timeClip(double);
+inline double jsCurrentTime()
+{
+ // JavaScript doesn't recognize fractions of a millisecond.
+ return floor(WTF::currentTimeMS());
+}
+
const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
@@ -74,9 +74,39 @@ const double msPerSecond = 1000.0;
const double msPerMinute = 60.0 * 1000.0;
const double msPerHour = 60.0 * 60.0 * 1000.0;
const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0;
+const double msPerMonth = 2592000000.0;
-// Intentionally overridding the default tm of the system
-// Tee members of tm differ on various operating systems.
+// Returns the number of days from 1970-01-01 to the specified date.
+double dateToDaysFrom1970(int year, int month, int day);
+int msToYear(double ms);
+int dayInYear(double ms, int year);
+int monthFromDayInYear(int dayInYear, bool leapYear);
+int dayInMonthFromDayInYear(int dayInYear, bool leapYear);
+
+} // namespace WTF
+
+using WTF::dateToDaysFrom1970;
+using WTF::dayInMonthFromDayInYear;
+using WTF::dayInYear;
+using WTF::minutesPerHour;
+using WTF::monthFromDayInYear;
+using WTF::msPerDay;
+using WTF::msPerSecond;
+using WTF::msToYear;
+using WTF::secondsPerMinute;
+
+#if USE(JSC)
+namespace JSC {
+class ExecState;
+struct GregorianDateTime;
+
+void msToGregorianDateTime(ExecState*, double, bool outputIsUTC, GregorianDateTime&);
+double gregorianDateTimeToMS(ExecState*, const GregorianDateTime&, double, bool inputIsUTC);
+double getUTCOffset(ExecState*);
+double parseDateFromNullTerminatedCharacters(ExecState*, const char* dateString);
+
+// Intentionally overridding the default tm of the system.
+// The members of tm differ on various operating systems.
struct GregorianDateTime : Noncopyable {
GregorianDateTime()
: second(0)
@@ -98,7 +128,7 @@ struct GregorianDateTime : Noncopyable {
delete [] timeZone;
}
- GregorianDateTime(const tm& inTm)
+ GregorianDateTime(ExecState* exec, const tm& inTm)
: second(inTm.tm_sec)
, minute(inTm.tm_min)
, hour(inTm.tm_hour)
@@ -109,10 +139,11 @@ struct GregorianDateTime : Noncopyable {
, year(inTm.tm_year)
, isDST(inTm.tm_isdst)
{
+ UNUSED_PARAM(exec);
#if HAVE(TM_GMTOFF)
utcOffset = static_cast<int>(inTm.tm_gmtoff);
#else
- utcOffset = static_cast<int>(getUTCOffset() / msPerSecond + (isDST ? secondsPerHour : 0));
+ utcOffset = static_cast<int>(getUTCOffset(exec) / WTF::msPerSecond + (isDST ? WTF::secondsPerHour : 0));
#endif
#if HAVE(TM_ZONE)
@@ -186,7 +217,7 @@ static inline int gmtoffset(const GregorianDateTime& t)
{
return t.utcOffset;
}
-
-} // namespace WTF
+} // namespace JSC
+#endif // USE(JSC)
#endif // DateMath_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp
index f3ded7e..d95f078 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp
@@ -119,11 +119,13 @@ static void initializeIsForbiddenKey()
pthread_key_create(&isForbiddenKey, 0);
}
+#if !ASSERT_DISABLED
static bool isForbidden()
{
pthread_once(&isForbiddenKeyOnce, initializeIsForbiddenKey);
return !!pthread_getspecific(isForbiddenKey);
}
+#endif
void fastMallocForbid()
{
@@ -182,6 +184,17 @@ void* fastZeroedMalloc(size_t n)
memset(result, 0, n);
return result;
}
+
+char* fastStrDup(const char* src)
+{
+ int len = strlen(src) + 1;
+ char* dup = static_cast<char*>(fastMalloc(len));
+
+ if (dup)
+ memcpy(dup, src, len);
+
+ return dup;
+}
TryMallocReturnValue tryFastZeroedMalloc(size_t n)
{
@@ -196,13 +209,6 @@ TryMallocReturnValue tryFastZeroedMalloc(size_t n)
#if FORCE_SYSTEM_MALLOC
-#include <stdlib.h>
-#if !PLATFORM(WIN_OS)
- #include <pthread.h>
-#else
- #include "windows.h"
-#endif
-
namespace WTF {
TryMallocReturnValue tryFastMalloc(size_t n)
@@ -354,7 +360,7 @@ FastMallocStatistics fastMallocStatistics()
} // namespace WTF
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
// This symbol is present in the JavaScriptCore exports file even when FastMalloc is disabled.
// It will never be used in this case, so it's type and value are less interesting than its presence.
extern "C" const int jscore_fastmalloc_introspection = 0;
@@ -384,7 +390,7 @@ extern "C" const int jscore_fastmalloc_introspection = 0;
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
-#if PLATFORM(UNIX)
+#if OS(UNIX)
#include <unistd.h>
#endif
#if COMPILER(MSVC)
@@ -396,11 +402,15 @@ extern "C" const int jscore_fastmalloc_introspection = 0;
#if WTF_CHANGES
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
#include "MallocZoneSupport.h"
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
#endif
+#if HAVE(DISPATCH_H)
+#include <dispatch/dispatch.h>
+#endif
+
#ifndef PRIuS
#define PRIuS "zu"
@@ -410,7 +420,7 @@ extern "C" const int jscore_fastmalloc_introspection = 0;
// call to the function on Mac OS X, and it's used in performance-critical code. So we
// use a function pointer. But that's not necessarily faster on other platforms, and we had
// problems with this technique on Windows, so we'll do this only on Mac OS X.
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
static void* (*pthread_getspecific_function_pointer)(pthread_key_t) = pthread_getspecific;
#define pthread_getspecific(key) pthread_getspecific_function_pointer(key)
#endif
@@ -438,7 +448,7 @@ namespace WTF {
#define MESSAGE LOG_ERROR
#define CHECK_CONDITION ASSERT
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
class Span;
class TCMalloc_Central_FreeListPadded;
class TCMalloc_PageHeap;
@@ -995,7 +1005,7 @@ class PageHeapAllocator {
int inuse() const { return inuse_; }
-#if defined(WTF_CHANGES) && PLATFORM(DARWIN)
+#if defined(WTF_CHANGES) && OS(DARWIN)
template <class Recorder>
void recordAdministrativeRegions(Recorder& recorder, const RemoteMemoryReader& reader)
{
@@ -1177,7 +1187,7 @@ template <int BITS> class MapSelector {
};
#if defined(WTF_CHANGES)
-#if PLATFORM(X86_64)
+#if CPU(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
@@ -1228,7 +1238,7 @@ static const int kScavengeTimerDelayInSeconds = 5;
static const size_t kMinimumFreeCommittedPageCount = 512;
// During a scavenge, we'll release up to a fraction of the free committed pages.
-#if PLATFORM(WIN)
+#if OS(WINDOWS)
// We are slightly less aggressive in releasing memory on Windows due to performance reasons.
static const int kMaxScavengeAmountFactor = 3;
#else
@@ -1377,26 +1387,34 @@ class TCMalloc_PageHeap {
// Index of last free list we scavenged
size_t scavenge_index_;
-#if defined(WTF_CHANGES) && PLATFORM(DARWIN)
+#if defined(WTF_CHANGES) && OS(DARWIN)
friend class FastMallocZone;
#endif
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
- static NO_RETURN void* runScavengerThread(void*);
+ void initializeScavenger();
+ ALWAYS_INLINE void signalScavenger();
+ void scavenge();
+ ALWAYS_INLINE bool shouldContinueScavenging() const;
+#if !HAVE(DISPATCH_H)
+ static NO_RETURN void* runScavengerThread(void*);
NO_RETURN void scavengerThread();
- void scavenge();
-
- inline bool shouldContinueScavenging() const;
+ // Keeps track of whether the background thread is actively scavenging memory every kScavengeTimerDelayInSeconds, or
+ // it's blocked waiting for more pages to be deleted.
+ bool m_scavengeThreadActive;
pthread_mutex_t m_scavengeMutex;
-
pthread_cond_t m_scavengeCondition;
+#else // !HAVE(DISPATCH_H)
+ void periodicScavenge();
+
+ dispatch_queue_t m_scavengeQueue;
+ dispatch_source_t m_scavengeTimer;
+ bool m_scavengingScheduled;
+#endif
- // Keeps track of whether the background thread is actively scavenging memory every kScavengeTimerDelayInSeconds, or
- // it's blocked waiting for more pages to be deleted.
- bool m_scavengeThreadActive;
#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
};
@@ -1424,24 +1442,60 @@ void TCMalloc_PageHeap::init()
}
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+ initializeScavenger();
+#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+}
+
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+
+#if !HAVE(DISPATCH_H)
+
+void TCMalloc_PageHeap::initializeScavenger()
+{
pthread_mutex_init(&m_scavengeMutex, 0);
pthread_cond_init(&m_scavengeCondition, 0);
m_scavengeThreadActive = true;
pthread_t thread;
pthread_create(&thread, 0, runScavengerThread, this);
-#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
}
-#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
void* TCMalloc_PageHeap::runScavengerThread(void* context)
{
static_cast<TCMalloc_PageHeap*>(context)->scavengerThread();
-#if COMPILER(MSVC) || PLATFORM(SOLARIS)
+#if COMPILER(MSVC) || OS(SOLARIS)
// Without this, Visual Studio will complain that this method does not return a value.
return 0;
#endif
}
+ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
+{
+ if (!m_scavengeThreadActive && shouldContinueScavenging())
+ pthread_cond_signal(&m_scavengeCondition);
+}
+
+#else // !HAVE(DISPATCH_H)
+
+void TCMalloc_PageHeap::initializeScavenger()
+{
+ m_scavengeQueue = dispatch_queue_create("com.apple.JavaScriptCore.FastMallocSavenger", NULL);
+ m_scavengeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_scavengeQueue);
+ dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, kScavengeTimerDelayInSeconds * NSEC_PER_SEC);
+ dispatch_source_set_timer(m_scavengeTimer, startTime, kScavengeTimerDelayInSeconds * NSEC_PER_SEC, 1000 * NSEC_PER_USEC);
+ dispatch_source_set_event_handler(m_scavengeTimer, ^{ periodicScavenge(); });
+ m_scavengingScheduled = false;
+}
+
+ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
+{
+ if (!m_scavengingScheduled && shouldContinueScavenging()) {
+ m_scavengingScheduled = true;
+ dispatch_resume(m_scavengeTimer);
+ }
+}
+
+#endif
+
void TCMalloc_PageHeap::scavenge()
{
// If we have to commit memory in the last 5 seconds, it means we don't have enough free committed pages
@@ -1477,7 +1531,7 @@ void TCMalloc_PageHeap::scavenge()
free_committed_pages_ -= pagesDecommitted;
}
-inline bool TCMalloc_PageHeap::shouldContinueScavenging() const
+ALWAYS_INLINE bool TCMalloc_PageHeap::shouldContinueScavenging() const
{
return free_committed_pages_ > kMinimumFreeCommittedPageCount;
}
@@ -1739,8 +1793,7 @@ inline void TCMalloc_PageHeap::Delete(Span* span) {
}
// Make sure the scavenge thread becomes active if we have enough freed pages to release some back to the system.
- if (!m_scavengeThreadActive && shouldContinueScavenging())
- pthread_cond_signal(&m_scavengeCondition);
+ signalScavenger();
#else
IncrementalScavenge(n);
#endif
@@ -2283,7 +2336,9 @@ static inline TCMalloc_PageHeap* getPageHeap()
#define pageheap getPageHeap()
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
-#if PLATFORM(WIN_OS)
+
+#if !HAVE(DISPATCH_H)
+#if OS(WINDOWS)
static void sleep(unsigned seconds)
{
::Sleep(seconds * 1000);
@@ -2312,6 +2367,23 @@ void TCMalloc_PageHeap::scavengerThread()
}
}
}
+
+#else
+
+void TCMalloc_PageHeap::periodicScavenge()
+{
+ {
+ SpinLockHolder h(&pageheap_lock);
+ pageheap->scavenge();
+ }
+
+ if (!shouldContinueScavenging()) {
+ m_scavengingScheduled = false;
+ dispatch_suspend(m_scavengeTimer);
+ }
+}
+#endif // HAVE(DISPATCH_H)
+
#endif
// If TLS is available, we also store a copy
@@ -2821,7 +2893,7 @@ void TCMalloc_ThreadCache::InitModule() {
}
pageheap->init();
phinited = 1;
-#if defined(WTF_CHANGES) && PLATFORM(DARWIN)
+#if defined(WTF_CHANGES) && OS(DARWIN)
FastMallocZone::init();
#endif
}
@@ -3800,7 +3872,7 @@ void* realloc(void* old_ptr, size_t new_size) {
return new_ptr;
} else {
#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
- old_ptr = pByte + sizeof(AllocAlignmentInteger); // Set old_ptr back to the user pointer.
+ old_ptr = static_cast<AllocAlignmentInteger*>(old_ptr) + 1; // Set old_ptr back to the user pointer.
#endif
return old_ptr;
}
@@ -4019,7 +4091,7 @@ void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride;
#endif
-#if defined(WTF_CHANGES) && PLATFORM(DARWIN)
+#if defined(WTF_CHANGES) && OS(DARWIN)
class FreeObjectFinder {
const RemoteMemoryReader& m_reader;
@@ -4302,7 +4374,7 @@ extern "C" {
malloc_introspection_t jscore_fastmalloc_introspection = { &FastMallocZone::enumerate, &FastMallocZone::goodSize, &FastMallocZone::check, &FastMallocZone::print,
&FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE)
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !OS(IPHONE_OS)
, 0 // zone_locked will not be called on the zone unless it advertises itself as version five or higher.
#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h
index ca0961c..74d4307 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.h
@@ -33,6 +33,7 @@ namespace WTF {
void* fastZeroedMalloc(size_t);
void* fastCalloc(size_t numElements, size_t elementSize);
void* fastRealloc(void*, size_t);
+ char* fastStrDup(const char*);
struct TryMallocReturnValue {
TryMallocReturnValue(void* data)
@@ -188,17 +189,18 @@ using WTF::tryFastZeroedMalloc;
using WTF::tryFastCalloc;
using WTF::tryFastRealloc;
using WTF::fastFree;
+using WTF::fastStrDup;
#ifndef NDEBUG
using WTF::fastMallocForbid;
using WTF::fastMallocAllow;
#endif
-#if COMPILER(GCC) && PLATFORM(DARWIN)
+#if COMPILER(GCC) && OS(DARWIN)
#define WTF_PRIVATE_INLINE __private_extern__ inline __attribute__((always_inline))
#elif COMPILER(GCC)
#define WTF_PRIVATE_INLINE inline __attribute__((always_inline))
-#elif COMPILER(MSVC)
+#elif COMPILER(MSVC) || COMPILER(RVCT)
#define WTF_PRIVATE_INLINE __forceinline
#else
#define WTF_PRIVATE_INLINE inline
@@ -216,14 +218,21 @@ using WTF::fastMallocAllow;
// We musn't customize the global operator new and delete for the Qt port.
#if !PLATFORM(QT)
-WTF_PRIVATE_INLINE void* operator new(size_t size) { return fastMalloc(size); }
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable: 4290) // Disable the C++ exception specification ignored warning.
+#endif
+WTF_PRIVATE_INLINE void* operator new(size_t size) throw (std::bad_alloc) { return fastMalloc(size); }
WTF_PRIVATE_INLINE void* operator new(size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); }
-WTF_PRIVATE_INLINE void operator delete(void* p) { fastFree(p); }
+WTF_PRIVATE_INLINE void operator delete(void* p) throw() { fastFree(p); }
WTF_PRIVATE_INLINE void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); }
-WTF_PRIVATE_INLINE void* operator new[](size_t size) { return fastMalloc(size); }
+WTF_PRIVATE_INLINE void* operator new[](size_t size) throw (std::bad_alloc) { return fastMalloc(size); }
WTF_PRIVATE_INLINE void* operator new[](size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); }
-WTF_PRIVATE_INLINE void operator delete[](void* p) { fastFree(p); }
+WTF_PRIVATE_INLINE void operator delete[](void* p) throw() { fastFree(p); }
WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); }
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/GOwnPtr.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/GOwnPtr.cpp
deleted file mode 100644
index 432885f..0000000
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/GOwnPtr.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include "GOwnPtr.h"
-
-namespace WTF {
-
-template <> void freeOwnedGPtr<GError>(GError* ptr)
-{
- if (ptr)
- g_error_free(ptr);
-}
-
-template <> void freeOwnedGPtr<GList>(GList* ptr)
-{
- g_list_free(ptr);
-}
-
-template <> void freeOwnedGPtr<GCond>(GCond* ptr)
-{
- if (ptr)
- g_cond_free(ptr);
-}
-
-template <> void freeOwnedGPtr<GMutex>(GMutex* ptr)
-{
- if (ptr)
- g_mutex_free(ptr);
-}
-
-template <> void freeOwnedGPtr<GPatternSpec>(GPatternSpec* ptr)
-{
- if (ptr)
- g_pattern_spec_free(ptr);
-}
-
-template <> void freeOwnedGPtr<GDir>(GDir* ptr)
-{
- if (ptr)
- g_dir_close(ptr);
-}
-
-template <> void freeOwnedGPtr<GHashTable>(GHashTable* ptr)
-{
- if (ptr)
- g_hash_table_unref(ptr);
-}
-
-} // namespace WTF
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/GOwnPtr.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/GOwnPtr.h
deleted file mode 100644
index 4993348..0000000
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/GOwnPtr.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef GOwnPtr_h
-#define GOwnPtr_h
-
-#include <algorithm>
-#include <glib.h>
-#include <wtf/Assertions.h>
-#include <wtf/Noncopyable.h>
-
-namespace WTF {
- template <typename T> inline void freeOwnedGPtr(T* ptr) { g_free(reinterpret_cast<void*>(ptr)); }
- template<> void freeOwnedGPtr<GError>(GError*);
- template<> void freeOwnedGPtr<GList>(GList*);
- template<> void freeOwnedGPtr<GCond>(GCond*);
- template<> void freeOwnedGPtr<GMutex>(GMutex*);
- template<> void freeOwnedGPtr<GPatternSpec>(GPatternSpec*);
- template<> void freeOwnedGPtr<GDir>(GDir*);
- template<> void freeOwnedGPtr<GHashTable>(GHashTable*);
-
- template <typename T> class GOwnPtr : public Noncopyable {
- public:
- explicit GOwnPtr(T* ptr = 0) : m_ptr(ptr) { }
- ~GOwnPtr() { freeOwnedGPtr(m_ptr); }
-
- T* get() const { return m_ptr; }
- T* release() { T* ptr = m_ptr; m_ptr = 0; return ptr; }
- T*& outPtr() { ASSERT(!m_ptr); return m_ptr; }
-
- void set(T* ptr) { ASSERT(!ptr || m_ptr != ptr); freeOwnedGPtr(m_ptr); m_ptr = ptr; }
- void clear() { freeOwnedGPtr(m_ptr); m_ptr = 0; }
-
- T& operator*() const { ASSERT(m_ptr); return *m_ptr; }
- T* operator->() const { ASSERT(m_ptr); return m_ptr; }
-
- bool operator!() const { return !m_ptr; }
-
- // This conversion operator allows implicit conversion to bool but not to other integer types.
- typedef T* GOwnPtr::*UnspecifiedBoolType;
- operator UnspecifiedBoolType() const { return m_ptr ? &GOwnPtr::m_ptr : 0; }
-
- void swap(GOwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
-
- private:
- T* m_ptr;
- };
-
- template <typename T> inline void swap(GOwnPtr<T>& a, GOwnPtr<T>& b) { a.swap(b); }
-
- template <typename T, typename U> inline bool operator==(const GOwnPtr<T>& a, U* b)
- {
- return a.get() == b;
- }
-
- template <typename T, typename U> inline bool operator==(T* a, const GOwnPtr<U>& b)
- {
- return a == b.get();
- }
-
- template <typename T, typename U> inline bool operator!=(const GOwnPtr<T>& a, U* b)
- {
- return a.get() != b;
- }
-
- template <typename T, typename U> inline bool operator!=(T* a, const GOwnPtr<U>& b)
- {
- return a != b.get();
- }
-
- template <typename T> inline typename GOwnPtr<T>::PtrType getPtr(const GOwnPtr<T>& p)
- {
- return p.get();
- }
-
-} // namespace WTF
-
-using WTF::GOwnPtr;
-
-#endif // GOwnPtr_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashCountedSet.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashCountedSet.h
index 5fb6da8..165eb41 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashCountedSet.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashCountedSet.h
@@ -65,8 +65,8 @@ namespace WTF {
void remove(iterator);
// removes the value, regardless of its count
- void clear(iterator);
- void clear(const ValueType&);
+ void removeAll(iterator);
+ void removeAll(const ValueType&);
// clears the whole set
void clear();
@@ -171,13 +171,13 @@ namespace WTF {
}
template<typename Value, typename HashFunctions, typename Traits>
- inline void HashCountedSet<Value, HashFunctions, Traits>::clear(const ValueType& value)
+ inline void HashCountedSet<Value, HashFunctions, Traits>::removeAll(const ValueType& value)
{
- clear(find(value));
+ removeAll(find(value));
}
template<typename Value, typename HashFunctions, typename Traits>
- inline void HashCountedSet<Value, HashFunctions, Traits>::clear(iterator it)
+ inline void HashCountedSet<Value, HashFunctions, Traits>::removeAll(iterator it)
{
if (it == end())
return;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashFunctions.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashFunctions.h
index 13afb72..2c66a2d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashFunctions.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashFunctions.h
@@ -173,9 +173,6 @@ 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/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashMap.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashMap.h
index 8ff9170..de4743a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashMap.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashMap.h
@@ -83,6 +83,23 @@ namespace WTF {
MappedType take(const KeyType&); // efficient combination of get with remove
+ // An alternate version of find() that finds the object by hashing and comparing
+ // with some other type, to avoid the cost of type conversion. HashTranslator
+ // must have the following function members:
+ // static unsigned hash(const T&);
+ // static bool equal(const ValueType&, const T&);
+ template<typename T, typename HashTranslator> iterator find(const T&);
+ template<typename T, typename HashTranslator> const_iterator find(const T&) const;
+ template<typename T, typename HashTranslator> bool contains(const T&) const;
+
+ // An alternate version of add() that finds the object by hashing and comparing
+ // with some other type, to avoid the cost of type conversion if the object is already
+ // in the table. HashTranslator must have the following function members:
+ // static unsigned hash(const T&);
+ // static bool equal(const ValueType&, const T&);
+ // static translate(ValueType&, const T&, unsigned hashCode);
+ template<typename T, typename HashTranslator> pair<iterator, bool> add(const T&, const MappedType&);
+
private:
pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&);
@@ -107,6 +124,19 @@ namespace WTF {
}
};
+ template<typename ValueType, typename ValueTraits, typename T, typename Translator>
+ struct HashMapTranslatorAdapter {
+ typedef typename ValueType::first_type KeyType;
+ typedef typename ValueType::second_type MappedType;
+
+ static unsigned hash(const T& key) { return Translator::hash(key); }
+ static bool equal(const KeyType& a, const T& b) { return Translator::equal(a, b); }
+ static void translate(ValueType& location, const T& key, const MappedType&, unsigned hashCode)
+ {
+ Translator::translate(location.first, key, hashCode);
+ }
+ };
+
template<typename T, typename U, typename V, typename W, typename X>
inline void HashMap<T, U, V, W, X>::swap(HashMap& other)
{
@@ -174,6 +204,33 @@ namespace WTF {
}
template<typename T, typename U, typename V, typename W, typename X>
+ template<typename TYPE, typename HashTranslator>
+ inline typename HashMap<T, U, V, W, X>::iterator
+ HashMap<T, U, V, W, X>::find(const TYPE& value)
+ {
+ typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter;
+ return m_impl.template find<TYPE, Adapter>(value);
+ }
+
+ template<typename T, typename U, typename V, typename W, typename X>
+ template<typename TYPE, typename HashTranslator>
+ inline typename HashMap<T, U, V, W, X>::const_iterator
+ HashMap<T, U, V, W, X>::find(const TYPE& value) const
+ {
+ typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter;
+ return m_impl.template find<TYPE, Adapter>(value);
+ }
+
+ template<typename T, typename U, typename V, typename W, typename X>
+ template<typename TYPE, typename HashTranslator>
+ inline bool
+ HashMap<T, U, V, W, X>::contains(const TYPE& value) const
+ {
+ typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter;
+ return m_impl.template contains<TYPE, Adapter>(value);
+ }
+
+ template<typename T, typename U, typename V, typename W, typename X>
inline pair<typename HashMap<T, U, V, W, X>::iterator, bool>
HashMap<T, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped)
{
@@ -197,6 +254,15 @@ namespace WTF {
}
template<typename T, typename U, typename V, typename W, typename X>
+ template<typename TYPE, typename HashTranslator>
+ pair<typename HashMap<T, U, V, W, X>::iterator, bool>
+ HashMap<T, U, V, W, X>::add(const TYPE& key, const MappedType& value)
+ {
+ typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter;
+ return m_impl.template addPassingHashCode<TYPE, MappedType, Adapter>(key, value);
+ }
+
+ template<typename T, typename U, typename V, typename W, typename X>
pair<typename HashMap<T, U, V, W, X>::iterator, bool>
HashMap<T, U, V, W, X>::add(const KeyType& key, const MappedType& mapped)
{
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashSet.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashSet.h
index 3906a36..e56e384 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashSet.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashSet.h
@@ -81,7 +81,7 @@ namespace WTF {
// An alternate version of add() that finds the object by hashing and comparing
// with some other type, to avoid the cost of type conversion if the object is already
- // in the table. HashTranslator must have the following methods:
+ // in the table. HashTranslator must have the following function members:
// static unsigned hash(const T&);
// static bool equal(const ValueType&, const T&);
// static translate(ValueType&, const T&, unsigned hashCode);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashTable.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashTable.h
index 3b283f8..92533fa 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashTable.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/HashTable.h
@@ -197,7 +197,7 @@ namespace WTF {
void checkValidity(const const_iterator& other) const
{
ASSERT(m_table);
- ASSERT(other.m_table);
+ ASSERT_UNUSED(other, other.m_table);
ASSERT(m_table == other.m_table);
}
#else
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListHashSet.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListHashSet.h
index 38cc998..54ed36b 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListHashSet.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListHashSet.h
@@ -51,7 +51,7 @@ namespace WTF {
template<typename ValueArg> struct ListHashSetNodeAllocator;
template<typename ValueArg, typename HashArg> struct ListHashSetNodeHashFunctions;
- template<typename ValueArg, typename HashArg = typename DefaultHash<ValueArg>::Hash> class ListHashSet {
+ template<typename ValueArg, typename HashArg = typename DefaultHash<ValueArg>::Hash> class ListHashSet : public FastAllocBase {
private:
typedef ListHashSetNode<ValueArg> Node;
typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListRefPtr.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListRefPtr.h
index d863226..8bf6447 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListRefPtr.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ListRefPtr.h
@@ -44,6 +44,9 @@ namespace WTF {
template <typename U> ListRefPtr& operator=(const PassRefPtr<U>& o) { RefPtr<T>::operator=(o); return *this; }
};
+ // Remove inline for winscw compiler to prevent the compiler agressively resolving
+ // T::ref() in RefPtr<T>'s copy constructor. The bug is reported at:
+ // https://xdabug001.ext.nokia.com/bugzilla/show_bug.cgi?id=9812.
template <typename T>
#if !COMPILER(WINSCW)
inline
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.cpp
index e999094..40a4ae5 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.cpp
@@ -39,10 +39,12 @@ namespace WTF {
struct FunctionWithContext {
MainThreadFunction* function;
void* context;
+ ThreadCondition* syncFlag;
- FunctionWithContext(MainThreadFunction* function = 0, void* context = 0)
+ FunctionWithContext(MainThreadFunction* function = 0, void* context = 0, ThreadCondition* syncFlag = 0)
: function(function)
, context(context)
+ , syncFlag(syncFlag)
{
}
};
@@ -92,6 +94,8 @@ void dispatchFunctionsFromMainThread()
}
invocation.function(invocation.context);
+ if (invocation.syncFlag)
+ invocation.syncFlag->signal();
// If we are running accumulated functions for too long so UI may become unresponsive, we need to
// yield so the user input can be processed. Otherwise user may not be able to even close the window.
@@ -117,6 +121,24 @@ void callOnMainThread(MainThreadFunction* function, void* context)
scheduleDispatchFunctionsOnMainThread();
}
+void callOnMainThreadAndWait(MainThreadFunction* function, void* context)
+{
+ ASSERT(function);
+
+ if (isMainThread()) {
+ function(context);
+ return;
+ }
+
+ ThreadCondition syncFlag;
+ Mutex& functionQueueMutex = mainThreadFunctionQueueMutex();
+ MutexLocker locker(functionQueueMutex);
+ functionQueue().append(FunctionWithContext(function, context, &syncFlag));
+ if (functionQueue().size() == 1)
+ scheduleDispatchFunctionsOnMainThread();
+ syncFlag.wait(functionQueueMutex);
+}
+
void setMainThreadCallbacksPaused(bool paused)
{
ASSERT(isMainThread());
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.h
index b8305b5..11a5eb1 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MainThread.h
@@ -40,6 +40,9 @@ extern "C" {
void callOnMainThread(MainThreadFunction*, void* context);
+// Blocks the thread until the call finishes on the main thread. Misusing this can easily cause deadlocks.
+void callOnMainThreadAndWait(MainThreadFunction*, void* context);
+
void setMainThreadCallbacksPaused(bool paused);
// Must be called from the main thread (Darwin is an exception to this rule).
@@ -54,6 +57,7 @@ void dispatchFunctionsFromMainThread();
} // namespace WTF
using WTF::callOnMainThread;
+using WTF::callOnMainThreadAndWait;
using WTF::setMainThreadCallbacksPaused;
#endif // MainThread_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MathExtras.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MathExtras.h
index 324300d..9ea57fd 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MathExtras.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MathExtras.h
@@ -26,28 +26,24 @@
#ifndef WTF_MathExtras_h
#define WTF_MathExtras_h
+#include <float.h>
#include <math.h>
#include <stdlib.h>
-#if PLATFORM(SOLARIS)
+#if OS(SOLARIS)
#include <ieeefp.h>
#endif
-#if PLATFORM(OPENBSD)
+#if OS(OPENBSD)
#include <sys/types.h>
#include <machine/ieee.h>
#endif
#if COMPILER(MSVC)
-#if PLATFORM(WINCE)
+#if OS(WINCE)
#include <stdlib.h>
#endif
#include <limits>
-
-#if HAVE(FLOAT_H)
-#include <float.h>
-#endif
-
#endif
#ifndef M_PI
@@ -66,7 +62,7 @@ const double piOverFourDouble = M_PI_4;
const float piOverFourFloat = static_cast<float>(M_PI_4);
#endif
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
// Work around a bug in the Mac OS X libc where ceil(-0.1) return +0.
inline double wtf_ceil(double x) { return copysign(ceil(x), x); }
@@ -75,7 +71,7 @@ inline double wtf_ceil(double x) { return copysign(ceil(x), x); }
#endif
-#if PLATFORM(SOLARIS)
+#if OS(SOLARIS)
#ifndef isfinite
inline bool isfinite(double x) { return finite(x) && !isnand(x); }
@@ -89,7 +85,7 @@ inline bool signbit(double x) { return x < 0.0; } // FIXME: Wrong for negative 0
#endif
-#if PLATFORM(OPENBSD)
+#if OS(OPENBSD)
#ifndef isfinite
inline bool isfinite(double x) { return finite(x); }
@@ -102,6 +98,8 @@ inline bool signbit(double x) { struct ieee_double *p = (struct ieee_double *)&x
#if COMPILER(MSVC) || COMPILER(RVCT)
+inline long long llround(double num) { return static_cast<long long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); }
+inline long long llroundf(float num) { return static_cast<long long>(num > 0 ? num + 0.5f : ceil(num - 0.5f)); }
inline long lround(double num) { return static_cast<long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); }
inline long lroundf(float num) { return static_cast<long>(num > 0 ? num + 0.5f : ceilf(num - 0.5f)); }
inline double round(double num) { return num > 0 ? floor(num + 0.5) : ceil(num - 0.5); }
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MessageQueue.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MessageQueue.h
index 070b76c..48bd10a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MessageQueue.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/MessageQueue.h
@@ -41,23 +41,31 @@ 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.
+ MessageQueueMessageReceived, // A message was successfully received and returned.
};
+ // The queue takes ownership of messages and transfer it to the new owner
+ // when messages are fetched from the queue.
+ // Essentially, MessageQueue acts as a queue of OwnPtr<DataType>.
template<typename DataType>
class MessageQueue : public Noncopyable {
public:
MessageQueue() : m_killed(false) { }
-
- void append(const DataType&);
- bool appendAndCheckEmpty(const DataType&);
- void prepend(const DataType&);
- bool waitForMessage(DataType&);
+ ~MessageQueue();
+
+ void append(PassOwnPtr<DataType>);
+ bool appendAndCheckEmpty(PassOwnPtr<DataType>);
+ void prepend(PassOwnPtr<DataType>);
+
+ PassOwnPtr<DataType> waitForMessage();
+ PassOwnPtr<DataType> tryGetMessage();
template<typename Predicate>
- MessageQueueWaitResult waitForMessageFilteredWithTimeout(DataType&, Predicate&, double absoluteTime);
- void kill();
+ PassOwnPtr<DataType> waitForMessageFilteredWithTimeout(MessageQueueWaitResult&, Predicate&, double absoluteTime);
+
+ template<typename Predicate>
+ void removeIf(Predicate&);
- bool tryGetMessage(DataType&);
+ void kill();
bool killed() const;
// The result of isEmpty() is only valid if no other thread is manipulating the queue at the same time.
@@ -66,86 +74,115 @@ namespace WTF {
static double infiniteTime() { return std::numeric_limits<double>::max(); }
private:
- static bool alwaysTruePredicate(DataType&) { return true; }
+ static bool alwaysTruePredicate(DataType*) { return true; }
mutable Mutex m_mutex;
ThreadCondition m_condition;
- Deque<DataType> m_queue;
+ Deque<DataType*> m_queue;
bool m_killed;
};
template<typename DataType>
- inline void MessageQueue<DataType>::append(const DataType& message)
+ MessageQueue<DataType>::~MessageQueue()
+ {
+ deleteAllValues(m_queue);
+ }
+
+ template<typename DataType>
+ inline void MessageQueue<DataType>::append(PassOwnPtr<DataType> message)
{
MutexLocker lock(m_mutex);
- m_queue.append(message);
+ m_queue.append(message.release());
m_condition.signal();
}
// Returns true if the queue was empty before the item was added.
template<typename DataType>
- inline bool MessageQueue<DataType>::appendAndCheckEmpty(const DataType& message)
+ inline bool MessageQueue<DataType>::appendAndCheckEmpty(PassOwnPtr<DataType> message)
{
MutexLocker lock(m_mutex);
bool wasEmpty = m_queue.isEmpty();
- m_queue.append(message);
+ m_queue.append(message.release());
m_condition.signal();
return wasEmpty;
}
template<typename DataType>
- inline void MessageQueue<DataType>::prepend(const DataType& message)
+ inline void MessageQueue<DataType>::prepend(PassOwnPtr<DataType> message)
{
MutexLocker lock(m_mutex);
- m_queue.prepend(message);
+ m_queue.prepend(message.release());
m_condition.signal();
}
template<typename DataType>
- inline bool MessageQueue<DataType>::waitForMessage(DataType& result)
+ inline PassOwnPtr<DataType> MessageQueue<DataType>::waitForMessage()
{
- MessageQueueWaitResult exitReason = waitForMessageFilteredWithTimeout(result, MessageQueue<DataType>::alwaysTruePredicate, infiniteTime());
+ MessageQueueWaitResult exitReason;
+ PassOwnPtr<DataType> result = waitForMessageFilteredWithTimeout(exitReason, MessageQueue<DataType>::alwaysTruePredicate, infiniteTime());
ASSERT(exitReason == MessageQueueTerminated || exitReason == MessageQueueMessageReceived);
- return exitReason == MessageQueueMessageReceived;
+ return result;
}
template<typename DataType>
template<typename Predicate>
- inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageFilteredWithTimeout(DataType& result, Predicate& predicate, double absoluteTime)
+ inline PassOwnPtr<DataType> MessageQueue<DataType>::waitForMessageFilteredWithTimeout(MessageQueueWaitResult& result, Predicate& predicate, double absoluteTime)
{
MutexLocker lock(m_mutex);
bool timedOut = false;
- DequeConstIterator<DataType> found = m_queue.end();
+ DequeConstIterator<DataType*> found = m_queue.end();
while (!m_killed && !timedOut && (found = m_queue.findIf(predicate)) == m_queue.end())
timedOut = !m_condition.timedWait(m_mutex, absoluteTime);
ASSERT(!timedOut || absoluteTime != infiniteTime());
- if (m_killed)
- return MessageQueueTerminated;
+ if (m_killed) {
+ result = MessageQueueTerminated;
+ return 0;
+ }
- if (timedOut)
- return MessageQueueTimeout;
+ if (timedOut) {
+ result = MessageQueueTimeout;
+ return 0;
+ }
ASSERT(found != m_queue.end());
- result = *found;
+ DataType* message = *found;
m_queue.remove(found);
- return MessageQueueMessageReceived;
+ result = MessageQueueMessageReceived;
+ return message;
}
template<typename DataType>
- inline bool MessageQueue<DataType>::tryGetMessage(DataType& result)
+ inline PassOwnPtr<DataType> MessageQueue<DataType>::tryGetMessage()
{
MutexLocker lock(m_mutex);
if (m_killed)
- return false;
+ return 0;
if (m_queue.isEmpty())
- return false;
+ return 0;
- result = m_queue.first();
+ DataType* message = m_queue.first();
m_queue.removeFirst();
- return true;
+ return message;
+ }
+
+ template<typename DataType>
+ template<typename Predicate>
+ inline void MessageQueue<DataType>::removeIf(Predicate& predicate)
+ {
+ MutexLocker lock(m_mutex);
+ // See bug 31657 for why this loop looks so weird
+ while (true) {
+ DequeConstIterator<DataType*> found = m_queue.findIf(predicate);
+ if (found == m_queue.end())
+ break;
+
+ DataType* message = *found;
+ m_queue.remove(found);
+ delete message;
+ }
}
template<typename DataType>
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PassRefPtr.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PassRefPtr.h
index ae398d3..36ba78e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PassRefPtr.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PassRefPtr.h
@@ -42,20 +42,10 @@ namespace WTF {
ptr->deref();
}
- template<typename T>
-#if !COMPILER(WINSCW)
- inline
-#endif
- void refIfNotNull(T* ptr)
- {
- if (UNLIKELY(ptr != 0))
- ptr->ref();
- }
-
template<typename T> class PassRefPtr {
public:
PassRefPtr() : m_ptr(0) {}
- PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
+ PassRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
// It somewhat breaks the type system to allow transfer of ownership out of
// a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
// temporaries, and we don't really have a need to use real const PassRefPtrs
@@ -63,14 +53,14 @@ namespace WTF {
PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {}
template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { }
- ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); }
+ ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull<T>(m_ptr); }
template <class U>
- PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { T* ptr = m_ptr; refIfNotNull(ptr); }
+ PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
T* get() const { return m_ptr; }
- void clear() { T* ptr = m_ptr; derefIfNotNull(ptr); m_ptr = 0; }
+ void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; }
T& operator*() const { return *m_ptr; }
@@ -79,7 +69,6 @@ namespace WTF {
bool operator!() const { return !m_ptr; }
// This conversion operator allows implicit conversion to bool but not to other integer types.
- // Parenthesis is needed for winscw compiler to resolve class qualifier in this case.
typedef T* (PassRefPtr::*UnspecifiedBoolType);
operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; }
@@ -95,22 +84,82 @@ namespace WTF {
mutable T* m_ptr;
};
+ // NonNullPassRefPtr: Optimized for passing non-null pointers. A NonNullPassRefPtr
+ // begins life non-null, and can only become null through a call to releaseRef()
+ // or clear().
+
+ // FIXME: NonNullPassRefPtr could just inherit from PassRefPtr. However,
+ // if we use inheritance, GCC's optimizer fails to realize that destruction
+ // of a released NonNullPassRefPtr is a no-op. So, for now, just copy the
+ // most important code from PassRefPtr.
+ template <typename T> class NonNullPassRefPtr {
+ public:
+ NonNullPassRefPtr(T* ptr)
+ : m_ptr(ptr)
+ {
+ ASSERT(m_ptr);
+ m_ptr->ref();
+ }
+
+ template <class U> NonNullPassRefPtr(const RefPtr<U>& o)
+ : m_ptr(o.get())
+ {
+ ASSERT(m_ptr);
+ m_ptr->ref();
+ }
+
+ NonNullPassRefPtr(const NonNullPassRefPtr& o)
+ : m_ptr(o.releaseRef())
+ {
+ ASSERT(m_ptr);
+ }
+
+ template <class U> NonNullPassRefPtr(const NonNullPassRefPtr<U>& o)
+ : m_ptr(o.releaseRef())
+ {
+ ASSERT(m_ptr);
+ }
+
+ template <class U> NonNullPassRefPtr(const PassRefPtr<U>& o)
+ : m_ptr(o.releaseRef())
+ {
+ ASSERT(m_ptr);
+ }
+
+ ALWAYS_INLINE ~NonNullPassRefPtr() { derefIfNotNull(m_ptr); }
+
+ T* get() const { return m_ptr; }
+
+ void clear() { derefIfNotNull(m_ptr); m_ptr = 0; }
+ T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; }
+
+ T& operator*() const { return *m_ptr; }
+ T* operator->() const { return m_ptr; }
+
+ private:
+ mutable T* m_ptr;
+ };
+
template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o)
{
T* optr = o.get();
- refIfNotNull(optr);
+ if (optr)
+ optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
- derefIfNotNull(ptr);
+ if (ptr)
+ ptr->deref();
return *this;
}
template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr)
{
- refIfNotNull(optr);
+ if (optr)
+ optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
- derefIfNotNull(ptr);
+ if (ptr)
+ ptr->deref();
return *this;
}
@@ -118,7 +167,8 @@ namespace WTF {
{
T* ptr = m_ptr;
m_ptr = ref.releaseRef();
- derefIfNotNull(ptr);
+ if (ptr)
+ ptr->deref();
return *this;
}
@@ -126,7 +176,8 @@ namespace WTF {
{
T* ptr = m_ptr;
m_ptr = ref.releaseRef();
- derefIfNotNull(ptr);
+ if (ptr)
+ ptr->deref();
return *this;
}
@@ -203,6 +254,7 @@ namespace WTF {
} // namespace WTF
using WTF::PassRefPtr;
+using WTF::NonNullPassRefPtr;
using WTF::adoptRef;
using WTF::static_pointer_cast;
using WTF::const_pointer_cast;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h
index be74e2a..ec9a1e3 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h
@@ -27,163 +27,451 @@
#ifndef WTF_Platform_h
#define WTF_Platform_h
-/* PLATFORM handles OS, operating environment, graphics API, and CPU */
+/* ==== PLATFORM handles OS, operating environment, graphics API, and
+ CPU. This macro will be phased out in favor of platform adaptation
+ macros, policy decision macros, and top-level port definitions. ==== */
#define PLATFORM(WTF_FEATURE) (defined WTF_PLATFORM_##WTF_FEATURE && WTF_PLATFORM_##WTF_FEATURE)
+
+
+/* ==== Platform adaptation macros: these describe properties of the target environment. ==== */
+
+/* COMPILER() - the compiler being used to build the project */
#define COMPILER(WTF_FEATURE) (defined WTF_COMPILER_##WTF_FEATURE && WTF_COMPILER_##WTF_FEATURE)
+/* CPU() - the target CPU architecture */
+#define CPU(WTF_FEATURE) (defined WTF_CPU_##WTF_FEATURE && WTF_CPU_##WTF_FEATURE)
+/* HAVE() - specific system features (headers, functions or similar) that are present or not */
#define HAVE(WTF_FEATURE) (defined HAVE_##WTF_FEATURE && HAVE_##WTF_FEATURE)
+/* OS() - underlying operating system; only to be used for mandated low-level services like
+ virtual memory, not to choose a GUI toolkit */
+#define OS(WTF_FEATURE) (defined WTF_OS_##WTF_FEATURE && WTF_OS_##WTF_FEATURE)
+
+
+/* ==== Policy decision macros: these define policy choices for a particular port. ==== */
+
+/* USE() - use a particular third-party library or optional OS service */
#define USE(WTF_FEATURE) (defined WTF_USE_##WTF_FEATURE && WTF_USE_##WTF_FEATURE)
+/* ENABLE() - turn on a specific feature of WebKit */
#define ENABLE(WTF_FEATURE) (defined ENABLE_##WTF_FEATURE && ENABLE_##WTF_FEATURE)
-/* Operating systems - low-level dependencies */
-/* PLATFORM(DARWIN) */
-/* Operating system level dependencies for Mac OS X / Darwin that should */
-/* be used regardless of operating environment */
-#ifdef __APPLE__
-#define WTF_PLATFORM_DARWIN 1
-#include <AvailabilityMacros.h>
-#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
-#define BUILDING_ON_TIGER 1
-#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
-#define BUILDING_ON_LEOPARD 1
+
+/* ==== COMPILER() - the compiler being used to build the project ==== */
+
+/* COMPILER(MSVC) Microsoft Visual C++ */
+/* COMPILER(MSVC7) Microsoft Visual C++ v7 or lower*/
+#if defined(_MSC_VER)
+#define WTF_COMPILER_MSVC 1
+#if _MSC_VER < 1400
+#define WTF_COMPILER_MSVC7 1
#endif
-#include <TargetConditionals.h>
#endif
-/* PLATFORM(WIN_OS) */
-/* Operating system level dependencies for Windows that should be used */
-/* regardless of operating environment */
-#if defined(WIN32) || defined(_WIN32)
-#define WTF_PLATFORM_WIN_OS 1
+/* COMPILER(RVCT) - ARM RealView Compilation Tools */
+#if defined(__CC_ARM) || defined(__ARMCC__)
+#define WTF_COMPILER_RVCT 1
#endif
-/* PLATFORM(WINCE) */
-/* Operating system level dependencies for Windows CE that should be used */
-/* regardless of operating environment */
-/* Note that for this platform PLATFORM(WIN_OS) is also defined. */
-#if defined(_WIN32_WCE)
-#define WTF_PLATFORM_WINCE 1
+/* COMPILER(GCC) - GNU Compiler Collection */
+/* --gnu option of the RVCT compiler also defines __GNUC__ */
+#if defined(__GNUC__) && !COMPILER(RVCT)
+#define WTF_COMPILER_GCC 1
+#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
-/* PLATFORM(LINUX) */
-/* Operating system level dependencies for Linux-like systems that */
-/* should be used regardless of operating environment */
-#ifdef __linux__
-#define WTF_PLATFORM_LINUX 1
+/* COMPILER(MINGW) - MinGW GCC */
+#if defined(MINGW) || defined(__MINGW32__)
+#define WTF_COMPILER_MINGW 1
#endif
-/* PLATFORM(FREEBSD) */
-/* Operating system level dependencies for FreeBSD-like systems that */
-/* should be used regardless of operating environment */
-#ifdef __FreeBSD__
-#define WTF_PLATFORM_FREEBSD 1
+/* COMPILER(SUNCC) - Sun CC compiler, also known as Sun Studio or Sun Pro */
+#if defined(__SUNPRO_CC) || defined(__SUNPRO_C)
+#define WTF_COMPILER_SUNCC 1
#endif
-/* PLATFORM(OPENBSD) */
-/* Operating system level dependencies for OpenBSD systems that */
-/* should be used regardless of operating environment */
-#ifdef __OpenBSD__
-#define WTF_PLATFORM_OPENBSD 1
+/* COMPILER(WINSCW) - CodeWarrior for Symbian emulator */
+#if defined(__WINSCW__)
+#define WTF_COMPILER_WINSCW 1
#endif
-/* PLATFORM(SOLARIS) */
-/* Operating system level dependencies for Solaris that should be used */
-/* regardless of operating environment */
-#if defined(sun) || defined(__sun)
-#define WTF_PLATFORM_SOLARIS 1
+/* COMPILER(ACC) - HP aCC */
+#if defined(__HP_aCC)
+#define WTF_COMPILER_ACC 1
+#endif
+
+/* COMPILER(XLC) - IBM XL */
+#if defined(__xlC__)
+#define WTF_COMPILER_XLC 1
+#endif
+
+
+/* ==== CPU() - the target CPU architecture ==== */
+
+/* This also defines CPU(BIG_ENDIAN) or CPU(MIDDLE_ENDIAN) or neither, as appropriate. */
+
+/* CPU(ALPHA) - DEC Alpha */
+#if defined(__alpha__)
+#define WTF_CPU_ALPHA 1
+#endif
+
+/* CPU(IA64) - Itanium / IA-64 */
+#if defined(__ia64__) || defined(__ia64) || defined(_M_IA64)
+#define WTF_CPU_IA64 1
+/* 32-bit mode on Itanium */
+#if !defined(__LP64__)
+#define WTF_CPU_IA64_32 1
+#endif
+/* Itanium can be both big- and little-endian;
+ we need to determine at compile time which one it is.
+ - HP's aCC compiler only compiles big-endian (so HP-UXi is always big-endian)
+ - GCC defines __BIG_ENDIAN__ for us (default on HP-UX)
+ - Linux is usually little-endian
+ - I've never seen AIX or Windows on IA-64, but they should be little-endian too
+*/
+#if defined(__BIG_ENDIAN__) || defined(__HP_aCC)
+# define WTF_CPU_BIG_ENDIAN 1
+#endif
+#endif
+
+/* CPU(HPPA) - a.k.a. PA-RISC */
+#if defined(__hppa) || defined(__hppa__)
+#define WTF_CPU_HPPA 1
+#define WTF_CPU_BIG_ENDIAN 1
+#endif
+
+/* CPU(PPC) - PowerPC 32-bit */
+#if defined(__ppc__) \
+ || defined(__PPC__) \
+ || defined(__powerpc__) \
+ || defined(__powerpc) \
+ || defined(__POWERPC__) \
+ || defined(_M_PPC) \
+ || defined(__PPC)
+#define WTF_CPU_PPC 1
+#define WTF_CPU_BIG_ENDIAN 1
+#endif
+
+/* CPU(PPC64) - PowerPC 64-bit */
+#if defined(__ppc64__) \
+ || defined(__PPC64__)
+#define WTF_CPU_PPC64 1
+#define WTF_CPU_BIG_ENDIAN 1
+#endif
+
+/* CPU(SH4) - SuperH SH-4 */
+#if defined(__SH4__)
+#define WTF_CPU_SH4 1
+#endif
+
+/* CPU(SPARC32) - SPARC 32-bit */
+#if defined(__sparc) && !defined(__arch64__) || defined(__sparcv8)
+#define WTF_CPU_SPARC32 1
+#define WTF_CPU_BIG_ENDIAN 1
+#endif
+
+/* CPU(SPARC64) - SPARC 64-bit */
+#if defined(__sparc__) && defined(__arch64__) || defined (__sparcv9)
+#define WTF_CPU_SPARC64 1
+#define WTF_CPU_BIG_ENDIAN 1
+#endif
+
+/* CPU(SPARC) - any SPARC, true for CPU(SPARC32) and CPU(SPARC64) */
+#if CPU(SPARC32) || CPU(SPARC64)
+#define WTF_CPU_SPARC
+#endif
+
+/* CPU(X86) - i386 / x86 32-bit */
+#if defined(__i386__) \
+ || defined(i386) \
+ || defined(_M_IX86) \
+ || defined(_X86_) \
+ || defined(__THW_INTEL)
+#define WTF_CPU_X86 1
+#endif
+
+/* CPU(X86_64) - AMD64 / Intel64 / x86_64 64-bit */
+#if defined(__x86_64__) \
+ || defined(_M_X64)
+#define WTF_CPU_X86_64 1
#endif
-/* PLATFORM(AIX) */
-/* Operating system level dependencies for AIX that should be used */
-/* regardless of operating environment */
-#if defined(_AIX)
-#define WTF_PLATFORM_AIX 1
/* 64-bit mode on AIX */
#ifdef __64BIT__
-#define WTF_PLATFORM_AIX64 1
+#define WTF_CPU_AIX64 1
+#endif
+
+/* CPU(ARM) - ARM, any version*/
+#if defined(arm) \
+ || defined(__arm__) \
+ || defined(__MARM__)
+#define WTF_CPU_ARM 1
+
+#if defined(__ARMEB__)
+#define WTF_CPU_BIG_ENDIAN 1
+
+#elif !defined(__ARM_EABI__) \
+ && !defined(__EABI__) \
+ && !defined(__VFP_FP__) \
+ && !defined(ANDROID)
+#define WTF_CPU_MIDDLE_ENDIAN 1
+
+#endif
+
+#define WTF_ARM_ARCH_AT_LEAST(N) (CPU(ARM) && WTF_ARM_ARCH_VERSION >= N)
+
+/* Set WTF_ARM_ARCH_VERSION */
+#if defined(__ARM_ARCH_4__) \
+ || defined(__ARM_ARCH_4T__) \
+ || defined(__MARM_ARMV4__) \
+ || defined(_ARMV4I_)
+#define WTF_ARM_ARCH_VERSION 4
+
+#elif defined(__ARM_ARCH_5__) \
+ || defined(__ARM_ARCH_5T__) \
+ || defined(__ARM_ARCH_5E__) \
+ || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__) \
+ || defined(__MARM_ARMV5__)
+#define WTF_ARM_ARCH_VERSION 5
+
+#elif defined(__ARM_ARCH_6__) \
+ || defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6K__) \
+ || defined(__ARM_ARCH_6Z__) \
+ || defined(__ARM_ARCH_6ZK__) \
+ || defined(__ARM_ARCH_6T2__) \
+ || defined(__ARMV6__)
+#define WTF_ARM_ARCH_VERSION 6
+
+#elif defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__)
+#define WTF_ARM_ARCH_VERSION 7
+
+/* RVCT sets _TARGET_ARCH_ARM */
+#elif defined(__TARGET_ARCH_ARM)
+#define WTF_ARM_ARCH_VERSION __TARGET_ARCH_ARM
+
+#else
+#define WTF_ARM_ARCH_VERSION 0
+
+#endif
+
+/* Set WTF_THUMB_ARCH_VERSION */
+#if defined(__ARM_ARCH_4T__)
+#define WTF_THUMB_ARCH_VERSION 1
+
+#elif defined(__ARM_ARCH_5T__) \
+ || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__)
+#define WTF_THUMB_ARCH_VERSION 2
+
+#elif defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6K__) \
+ || defined(__ARM_ARCH_6Z__) \
+ || defined(__ARM_ARCH_6ZK__) \
+ || defined(__ARM_ARCH_6M__)
+#define WTF_THUMB_ARCH_VERSION 3
+
+#elif defined(__ARM_ARCH_6T2__) \
+ || defined(__ARM_ARCH_7__) \
+ || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) \
+ || defined(__ARM_ARCH_7M__)
+#define WTF_THUMB_ARCH_VERSION 4
+
+/* RVCT sets __TARGET_ARCH_THUMB */
+#elif defined(__TARGET_ARCH_THUMB)
+#define WTF_THUMB_ARCH_VERSION __TARGET_ARCH_THUMB
+
+#else
+#define WTF_THUMB_ARCH_VERSION 0
+#endif
+
+
+/* CPU(ARMV5_OR_LOWER) - ARM instruction set v5 or earlier */
+/* On ARMv5 and below the natural alignment is required.
+ And there are some other differences for v5 or earlier. */
+#if !defined(ARMV5_OR_LOWER) && !WTF_ARM_ARCH_AT_LEAST(6)
+#define WTF_CPU_ARMV5_OR_LOWER 1
+#endif
+
+
+/* CPU(ARM_TRADITIONAL) - Thumb2 is not available, only traditional ARM (v4 or greater) */
+/* CPU(ARM_THUMB2) - Thumb2 instruction set is available */
+/* Only one of these will be defined. */
+#if !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2)
+# if defined(thumb2) || defined(__thumb2__) \
+ || ((defined(__thumb) || defined(__thumb__)) && WTF_THUMB_ARCH_VERSION == 4)
+# define WTF_CPU_ARM_TRADITIONAL 0
+# define WTF_CPU_ARM_THUMB2 1
+# elif WTF_ARM_ARCH_AT_LEAST(4)
+# define WTF_CPU_ARM_TRADITIONAL 1
+# define WTF_CPU_ARM_THUMB2 0
+# else
+# error "Not supported ARM architecture"
+# endif
+#elif CPU(ARM_TRADITIONAL) && CPU(ARM_THUMB2) /* Sanity Check */
+# error "Cannot use both of WTF_CPU_ARM_TRADITIONAL and WTF_CPU_ARM_THUMB2 platforms"
+#endif /* !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2) */
+
+#endif /* ARM */
+
+
+
+/* ==== OS() - underlying operating system; only to be used for mandated low-level services like
+ virtual memory, not to choose a GUI toolkit ==== */
+
+/* OS(ANDROID) - Android */
+#ifdef ANDROID
+#define WTF_OS_ANDROID 1
+#endif
+
+/* OS(AIX) - AIX */
+#ifdef _AIX
+#define WTF_OS_AIX 1
+#endif
+
+/* OS(DARWIN) - Any Darwin-based OS, including Mac OS X and iPhone OS */
+#ifdef __APPLE__
+#define WTF_OS_DARWIN 1
+
+/* FIXME: BUILDING_ON_.., and TARGETING... macros should be folded into the OS() system */
+#include <AvailabilityMacros.h>
+#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+#define BUILDING_ON_TIGER 1
+#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
+#define BUILDING_ON_LEOPARD 1
+#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
+#define BUILDING_ON_SNOW_LEOPARD 1
#endif
+#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+#define TARGETING_TIGER 1
+#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
+#define TARGETING_LEOPARD 1
+#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
+#define TARGETING_SNOW_LEOPARD 1
+#endif
+#include <TargetConditionals.h>
+
+#endif
+
+/* OS(IPHONE_OS) - iPhone OS */
+/* OS(MAC_OS_X) - Mac OS X (not including iPhone OS) */
+#if OS(DARWIN) && ((defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) \
+ || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) \
+ || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR))
+#define WTF_OS_IPHONE_OS 1
+#elif OS(DARWIN) && defined(TARGET_OS_MAC) && TARGET_OS_MAC
+#define WTF_OS_MAC_OS_X 1
+#endif
+
+/* OS(FREEBSD) - FreeBSD */
+#ifdef __FreeBSD__
+#define WTF_OS_FREEBSD 1
+#endif
+
+/* OS(HAIKU) - Haiku */
+#ifdef __HAIKU__
+#define WTF_OS_HAIKU 1
#endif
-/* PLATFORM(HPUX) */
-/* Operating system level dependencies for HP-UX that should be used */
-/* regardless of operating environment */
+/* OS(HPUX) - HP-UX */
#if defined(hpux) || defined(__hpux)
-#define WTF_PLATFORM_HPUX 1
+#define WTF_OS_HPUX 1
#ifndef MAP_ANON
#define MAP_ANON MAP_ANONYMOUS
#endif
#endif
-#if defined (__SYMBIAN32__)
-/* we are cross-compiling, it is not really windows */
-#undef WTF_PLATFORM_WIN_OS
-#undef WTF_PLATFORM_WIN
-#define WTF_PLATFORM_SYMBIAN 1
+/* OS(LINUX) - Linux */
+#ifdef __linux__
+#define WTF_OS_LINUX 1
#endif
-
-/* PLATFORM(NETBSD) */
-/* Operating system level dependencies for NetBSD that should be used */
-/* regardless of operating environment */
+/* OS(NETBSD) - NetBSD */
#if defined(__NetBSD__)
#define WTF_PLATFORM_NETBSD 1
#endif
-/* PLATFORM(QNX) */
-/* Operating system level dependencies for QNX that should be used */
-/* regardless of operating environment */
+/* OS(OPENBSD) - OpenBSD */
+#ifdef __OpenBSD__
+#define WTF_OS_OPENBSD 1
+#endif
+
+/* OS(QNX) - QNX */
#if defined(__QNXNTO__)
-#define WTF_PLATFORM_QNX 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(SYMBIAN) \
- || PLATFORM(NETBSD) \
- || PLATFORM(SOLARIS) \
- || PLATFORM(HPUX) \
- || defined(unix) \
- || defined(__unix) \
- || defined(__unix__) \
- || PLATFORM(AIX) \
- || defined(__HAIKU__) \
- || defined(__QNXNTO__)
-#define WTF_PLATFORM_UNIX 1
+#define WTF_OS_QNX 1
+#endif
+
+/* OS(SOLARIS) - Solaris */
+#if defined(sun) || defined(__sun)
+#define WTF_OS_SOLARIS 1
+#endif
+
+/* OS(WINCE) - Windows CE; note that for this platform OS(WINDOWS) is also defined */
+#if defined(_WIN32_WCE)
+#define WTF_OS_WINCE 1
+#endif
+
+/* OS(WINDOWS) - Any version of Windows */
+#if defined(WIN32) || defined(_WIN32)
+#define WTF_OS_WINDOWS 1
+#endif
+
+/* OS(SYMBIAN) - Symbian */
+#if defined (__SYMBIAN32__)
+/* we are cross-compiling, it is not really windows */
+#undef WTF_OS_WINDOWS
+#undef WTF_PLATFORM_WIN
+#define WTF_OS_SYMBIAN 1
+#endif
+
+/* OS(UNIX) - Any Unix-like system */
+#if OS(AIX) \
+ || OS(ANDROID) \
+ || OS(DARWIN) \
+ || OS(FREEBSD) \
+ || OS(HAIKU) \
+ || OS(HPUX) \
+ || OS(LINUX) \
+ || OS(NETBSD) \
+ || OS(OPENBSD) \
+ || OS(QNX) \
+ || OS(SOLARIS) \
+ || OS(SYMBIAN) \
+ || defined(unix) \
+ || defined(__unix) \
+ || defined(__unix__)
+#define WTF_OS_UNIX 1
#endif
/* Operating environments */
+/* FIXME: these are all mixes of OS, operating environment and policy choices. */
/* PLATFORM(CHROMIUM) */
/* PLATFORM(QT) */
+/* PLATFORM(WX) */
/* PLATFORM(GTK) */
+/* PLATFORM(HAIKU) */
/* PLATFORM(MAC) */
/* PLATFORM(WIN) */
#if defined(BUILDING_CHROMIUM__)
#define WTF_PLATFORM_CHROMIUM 1
#elif defined(BUILDING_QT__)
#define WTF_PLATFORM_QT 1
-
-/* PLATFORM(KDE) */
-#if defined(BUILDING_KDE__)
-#define WTF_PLATFORM_KDE 1
-#endif
-
#elif defined(BUILDING_WX__)
#define WTF_PLATFORM_WX 1
#elif defined(BUILDING_GTK__)
#define WTF_PLATFORM_GTK 1
#elif defined(BUILDING_HAIKU__)
#define WTF_PLATFORM_HAIKU 1
-#elif PLATFORM(DARWIN)
+#elif OS(DARWIN)
#define WTF_PLATFORM_MAC 1
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
#define WTF_PLATFORM_WIN 1
#endif
/* PLATFORM(IPHONE) */
+/* FIXME: this is sometimes used as an OS switch and sometimes for higher-level things */
#if (defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
#define WTF_PLATFORM_IPHONE 1
#endif
@@ -200,6 +488,13 @@
#define WTF_PLATFORM_IPHONE 0
#endif
+/* PLATFORM(ANDROID) */
+/* FIXME: this is sometimes used as an OS() switch, and other times to drive
+ policy choices */
+#if defined(ANDROID)
+#define WTF_PLATFORM_ANDROID 1
+#endif
+
/* Graphics engines */
/* PLATFORM(CG) and PLATFORM(CI) */
@@ -212,251 +507,48 @@
/* PLATFORM(SKIA) for Win/Linux, CG/CI for Mac */
#if PLATFORM(CHROMIUM)
-#if PLATFORM(DARWIN)
+#define ENABLE_HISTORY_ALWAYS_ASYNC 1
+#if OS(DARWIN)
#define WTF_PLATFORM_CG 1
#define WTF_PLATFORM_CI 1
#define WTF_USE_ATSUI 1
+#define WTF_USE_CORE_TEXT 1
#else
#define WTF_PLATFORM_SKIA 1
#endif
#endif
-/* Makes PLATFORM(WIN) default to PLATFORM(CAIRO) */
-/* FIXME: This should be changed from a blacklist to a whitelist */
-#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(WX) && !PLATFORM(CHROMIUM) && !PLATFORM(WINCE) && !PLATFORM(HAIKU)
+#if PLATFORM(GTK)
#define WTF_PLATFORM_CAIRO 1
#endif
-/* CPU */
-
-/* PLATFORM(PPC) */
-#if defined(__ppc__) \
- || defined(__PPC__) \
- || defined(__powerpc__) \
- || defined(__powerpc) \
- || defined(__POWERPC__) \
- || defined(_M_PPC) \
- || defined(__PPC)
-#define WTF_PLATFORM_PPC 1
-#define WTF_PLATFORM_BIG_ENDIAN 1
-#endif
-
-/* PLATFORM(PPC64) */
-#if defined(__ppc64__) \
- || defined(__PPC64__)
-#define WTF_PLATFORM_PPC64 1
-#define WTF_PLATFORM_BIG_ENDIAN 1
-#endif
-
-/* PLATFORM(ARM) */
-#define PLATFORM_ARM_ARCH(N) (PLATFORM(ARM) && ARM_ARCH_VERSION >= N)
-
-#if defined(arm) \
- || defined(__arm__) \
- || defined(__MARM__)
-#define WTF_PLATFORM_ARM 1
-#if defined(__ARMEB__)
-#define WTF_PLATFORM_BIG_ENDIAN 1
-#elif !defined(__ARM_EABI__) && !defined(__EABI__) && !defined(__VFP_FP__)
-#define WTF_PLATFORM_MIDDLE_ENDIAN 1
-#endif
-#define ARM_ARCH_VERSION 3
-#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || defined(ARMV4I) \
- || defined(_ARMV4I_) || defined(armv4i)
-#undef ARM_ARCH_VERSION
-#define ARM_ARCH_VERSION 4
-#endif
-#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
- || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
- || defined(__ARM_ARCH_5TEJ__) || defined(__MARM_ARMV5__)
-#undef ARM_ARCH_VERSION
-#define ARM_ARCH_VERSION 5
-#endif
-#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
- || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
- || defined(__ARM_ARCH_6ZK__) || defined(__ARMV6__)
-#undef ARM_ARCH_VERSION
-#define ARM_ARCH_VERSION 6
-#endif
-#if defined(__ARM_ARCH_7A__) || defined(__ARMV7__)
-#undef ARM_ARCH_VERSION
-#define ARM_ARCH_VERSION 7
-#endif
-/* On ARMv5 and below the natural alignment is required. */
-#if !defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_ARCH_VERSION <= 5
-#define ARM_REQUIRE_NATURAL_ALIGNMENT 1
-#endif
-/* Defines two pseudo-platforms for ARM and Thumb-2 instruction set. */
-#if !defined(WTF_PLATFORM_ARM_TRADITIONAL) && !defined(WTF_PLATFORM_ARM_THUMB2)
-# if defined(thumb2) || defined(__thumb2__)
-# define WTF_PLATFORM_ARM_TRADITIONAL 0
-# define WTF_PLATFORM_ARM_THUMB2 1
-# elif PLATFORM_ARM_ARCH(4) || PLATFORM_ARM_ARCH(5)
-# define WTF_PLATFORM_ARM_TRADITIONAL 1
-# define WTF_PLATFORM_ARM_THUMB2 0
-# else
-# error "Not supported ARM architecture"
-# endif
-#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(ARM_THUMB2) /* Sanity Check */
-# error "Cannot use both of WTF_PLATFORM_ARM_TRADITIONAL and WTF_PLATFORM_ARM_THUMB2 platforms"
-#endif // !defined(ARM_TRADITIONAL) && !defined(ARM_THUMB2)
-#endif /* ARM */
-
-/* PLATFORM(X86) */
-#if defined(__i386__) \
- || defined(i386) \
- || defined(_M_IX86) \
- || defined(_X86_) \
- || defined(__THW_INTEL)
-#define WTF_PLATFORM_X86 1
-#endif
-
-/* PLATFORM(X86_64) */
-#if defined(__x86_64__) \
- || defined(_M_X64)
-#define WTF_PLATFORM_X86_64 1
-#endif
-
-/* PLATFORM(SH4) */
-#if defined(__SH4__)
-#define WTF_PLATFORM_SH4 1
-#endif
-
-/* PLATFORM(SPARC64) */
-#if defined(__sparc__) && defined(__arch64__) || defined (__sparcv9)
-#define WTF_PLATFORM_SPARC64 1
-#define WTF_PLATFORM_BIG_ENDIAN 1
-#endif
-
-/* PLATFORM(SPARC32) */
-#if defined(__sparc) && !defined(__arch64__) || defined(__sparcv8)
-#define WTF_PLATFORM_SPARC32 1
-#define WTF_PLATFORM_BIG_ENDIAN 1
-#endif
-
-#if PLATFORM(SPARC32) || PLATFORM(SPARC64)
-#define WTF_PLATFORM_SPARC
-#endif
-/* PLATFORM(HPPA) */
-/* a.k.a. PA-RISC */
-#if defined(__hppa) || defined(__hppa__)
-#define WTF_PLATFORM_HPPA 1
-#define WTF_PLATFORM_BIG_ENDIAN 1
-#endif
-
-/* PLATFORM(IA64) */
-/* a.k.a. Itanium Processor Family, IPF */
-#if defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
-#define WTF_PLATFORM_IA64 1
-
-/* 32-bit mode on Itanium */
-#if !defined(__LP64__)
-#define WTF_PLATFORM_IA64_32 1
-#endif
-
-/* Itanium can be both big- and little-endian
- we need to determine at compile time which one it is.
- - HP's aCC compiler only compiles big-endian (so HP-UXi is always big-endian)
- - GCC defines __BIG_ENDIAN__ for us (default on HP-UX)
- - Linux is usually little-endian
- - I've never seen AIX or Windows on IA-64, but they should be little-endian too
-*/
-#if defined(__BIG_ENDIAN__) || defined(__HP_aCC)
-# define WTF_PLATFORM_BIG_ENDIAN 1
-#endif
-#endif
-
-/* PLATFORM(WINCE) && PLATFORM(QT)
+/* OS(WINCE) && PLATFORM(QT)
We can not determine the endianess at compile time. For
Qt for Windows CE the endianess is specified in the
device specific makespec
*/
-#if PLATFORM(WINCE) && PLATFORM(QT)
+#if OS(WINCE) && PLATFORM(QT)
# include <QtGlobal>
# undef WTF_PLATFORM_BIG_ENDIAN
# undef WTF_PLATFORM_MIDDLE_ENDIAN
# if Q_BYTE_ORDER == Q_BIG_EDIAN
# define WTF_PLATFORM_BIG_ENDIAN 1
# endif
-#endif
-#if PLATFORM(WINCE) && PLATFORM(QT)
# include <ce_time.h>
#endif
-/* Compiler */
-
-/* COMPILER(MSVC) */
-#if defined(_MSC_VER)
-#define WTF_COMPILER_MSVC 1
-#if _MSC_VER < 1400
-#define WTF_COMPILER_MSVC7 1
-#endif
-#endif
-
-/* COMPILER(RVCT) */
-#if defined(__CC_ARM) || defined(__ARMCC__)
-#define WTF_COMPILER_RVCT 1
-#endif
-
-/* COMPILER(GCC) */
-/* --gnu option of the RVCT compiler also defines __GNUC__ */
-#if defined(__GNUC__) && !COMPILER(RVCT)
-#define WTF_COMPILER_GCC 1
-#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-#endif
-
-/* COMPILER(MINGW) */
-#if defined(MINGW) || defined(__MINGW32__)
-#define WTF_COMPILER_MINGW 1
-#endif
-
-/* COMPILER(BORLAND) */
-/* not really fully supported - is this relevant any more? */
-#if defined(__BORLANDC__)
-#define WTF_COMPILER_BORLAND 1
-#endif
-
-/* COMPILER(CYGWIN) */
-/* not really fully supported - is this relevant any more? */
-#if defined(__CYGWIN__)
-#define WTF_COMPILER_CYGWIN 1
-#endif
-
-/* COMPILER(WINSCW) */
-#if defined(__WINSCW__)
-#define WTF_COMPILER_WINSCW 1
-#endif
-
-/* COMPILER(SUNCC) */
-/* This is the Sun CC compiler, also known as Sun Studio or Sun Pro */
-#if defined(__SUNPRO_CC) || defined(__SUNPRO_C)
-#define WTF_COMPILER_SUNCC 1
-#endif
-
-/* COMPILER(XLC) */
-/* IBM Visual Age C/C++ compiler, a.k.a. xlC */
-#if defined(__xlC__)
-#define WTF_COMPILER_XLC 1
-#endif
-
-/* COMPILER(ACC) */
-/* HP's aC++/ANSI C compiler, a.k.a. aCC */
-#if defined(__HP_aCC)
-#define WTF_COMPILER_ACC
-#endif
-
-#if (PLATFORM(IPHONE) || PLATFORM(MAC) || PLATFORM(WIN)) && !defined(ENABLE_JSC_MULTIPLE_THREADS)
+#if (PLATFORM(IPHONE) || PLATFORM(MAC) || PLATFORM(WIN) || (PLATFORM(QT) && OS(DARWIN) && !ENABLE(SINGLE_THREADED))) && !defined(ENABLE_JSC_MULTIPLE_THREADS)
#define ENABLE_JSC_MULTIPLE_THREADS 1
#endif
/* On Windows, use QueryPerformanceCounter by default */
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#define WTF_USE_QUERY_PERFORMANCE_COUNTER 1
#endif
-#if PLATFORM(WINCE) && !PLATFORM(QT)
+#if OS(WINCE) && !PLATFORM(QT)
#undef ENABLE_JSC_MULTIPLE_THREADS
#define ENABLE_JSC_MULTIPLE_THREADS 0
#define USE_SYSTEM_MALLOC 0
@@ -467,26 +559,25 @@
#define ENABLE_WML 1
#define HAVE_ACCESSIBILITY 0
-#define NOMINMAX // Windows min and max conflict with standard macros
-#define NOSHLWAPI // shlwapi.h not available on WinCe
+#define NOMINMAX /* Windows min and max conflict with standard macros */
+#define NOSHLWAPI /* shlwapi.h not available on WinCe */
-// MSDN documentation says these functions are provided with uspce.lib. But we cannot find this file.
-#define __usp10__ // disable "usp10.h"
+/* MSDN documentation says these functions are provided with uspce.lib. But we cannot find this file. */
+#define __usp10__ /* disable "usp10.h" */
-#define _INC_ASSERT // disable "assert.h"
+#define _INC_ASSERT /* disable "assert.h" */
#define assert(x)
-// _countof is only included in CE6; for CE5 we need to define it ourself
+/* _countof is only included in CE6; for CE5 we need to define it ourself */
#ifndef _countof
#define _countof(x) (sizeof(x) / sizeof((x)[0]))
#endif
-#endif /* PLATFORM(WINCE) && !PLATFORM(QT) */
+#endif /* OS(WINCE) && !PLATFORM(QT) */
-/* for Unicode, KDE uses Qt */
-#if PLATFORM(KDE) || PLATFORM(QT)
+#if PLATFORM(QT)
#define WTF_USE_QT4_UNICODE 1
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
#define WTF_USE_WINCE_UNICODE 1
#elif PLATFORM(GTK)
/* The GTK+ Unicode backend is configurable */
@@ -497,6 +588,10 @@
#if PLATFORM(MAC) && !PLATFORM(IPHONE)
#define WTF_PLATFORM_CF 1
#define WTF_USE_PTHREADS 1
+#define HAVE_PTHREAD_RWLOCK 1
+#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && CPU(X86_64)
+#define WTF_USE_PLUGIN_HOST_PROCESS 1
+#endif
#if !defined(ENABLE_MAC_JAVA_BRIDGE)
#define ENABLE_MAC_JAVA_BRIDGE 1
#endif
@@ -505,26 +600,45 @@
#endif
#define HAVE_READLINE 1
#define HAVE_RUNLOOP_TIMER 1
-#endif
+#endif /* PLATFORM(MAC) && !PLATFORM(IPHONE) */
-#if PLATFORM(CHROMIUM) && PLATFORM(DARWIN)
+#if PLATFORM(CHROMIUM) && OS(DARWIN)
#define WTF_PLATFORM_CF 1
#define WTF_USE_PTHREADS 1
+#define HAVE_PTHREAD_RWLOCK 1
#endif
-#if PLATFORM(IPHONE)
+#if PLATFORM(QT) && OS(DARWIN)
#define WTF_PLATFORM_CF 1
-#define WTF_USE_PTHREADS 1
+#endif
+
+#if PLATFORM(IPHONE)
#define ENABLE_CONTEXT_MENUS 0
#define ENABLE_DRAG_SUPPORT 0
#define ENABLE_FTPDIR 1
+#define ENABLE_GEOLOCATION 1
+#define ENABLE_ICONDATABASE 0
#define ENABLE_INSPECTOR 0
#define ENABLE_MAC_JAVA_BRIDGE 0
-#define ENABLE_ICONDATABASE 0
-#define ENABLE_GEOLOCATION 1
#define ENABLE_NETSCAPE_PLUGIN_API 0
-#define HAVE_READLINE 1
+#define ENABLE_ORIENTATION_EVENTS 1
#define ENABLE_REPAINT_THROTTLING 1
+#define HAVE_READLINE 1
+#define WTF_PLATFORM_CF 1
+#define WTF_USE_PTHREADS 1
+#define HAVE_PTHREAD_RWLOCK 1
+#endif
+
+#if PLATFORM(ANDROID)
+#define WTF_USE_PTHREADS 1
+#define WTF_PLATFORM_SGL 1
+#define USE_SYSTEM_MALLOC 1
+#define ENABLE_MAC_JAVA_BRIDGE 1
+#define LOG_DISABLED 1
+/* Prevents Webkit from drawing the caret in textfields and textareas
+ This prevents unnecessary invals. */
+#define ENABLE_TEXT_CARET 1
+#define ENABLE_JAVASCRIPT_DEBUGGER 0
#endif
#if PLATFORM(WIN)
@@ -533,11 +647,15 @@
#if PLATFORM(WX)
#define ENABLE_ASSEMBLER 1
+#if OS(DARWIN)
+#define WTF_PLATFORM_CF 1
+#endif
#endif
#if PLATFORM(GTK)
#if HAVE(PTHREAD_H)
#define WTF_USE_PTHREADS 1
+#define HAVE_PTHREAD_RWLOCK 1
#endif
#endif
@@ -545,6 +663,7 @@
#define HAVE_POSIX_MEMALIGN 1
#define WTF_USE_CURL 1
#define WTF_USE_PTHREADS 1
+#define HAVE_PTHREAD_RWLOCK 1
#define USE_SYSTEM_MALLOC 1
#define ENABLE_NETSCAPE_PLUGIN_API 0
#endif
@@ -555,19 +674,19 @@
#endif
#endif /* !defined(HAVE_ACCESSIBILITY) */
-#if PLATFORM(UNIX) && !PLATFORM(SYMBIAN)
+#if OS(UNIX) && !OS(SYMBIAN)
#define HAVE_SIGNAL_H 1
#endif
-#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !PLATFORM(QNX) \
- && !PLATFORM(SYMBIAN) && !PLATFORM(HAIKU) && !COMPILER(RVCT) && !PLATFORM(AIX) \
- && !PLATFORM(HPUX)
+#if !OS(WINDOWS) && !OS(SOLARIS) && !OS(QNX) \
+ && !OS(SYMBIAN) && !OS(HAIKU) && !OS(RVCT) \
+ && !OS(ANDROID) && !OS(AIX) && !OS(HPUX)
#define HAVE_TM_GMTOFF 1
#define HAVE_TM_ZONE 1
#define HAVE_TIMEGM 1
-#endif
+#endif
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
#define HAVE_ERRNO_H 1
#define HAVE_LANGINFO_H 1
@@ -579,27 +698,32 @@
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TIMEB_H 1
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE) && !PLATFORM(QT)
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+
+#define HAVE_DISPATCH_H 1
+
+#if !PLATFORM(IPHONE) && !PLATFORM(QT)
#define HAVE_MADV_FREE_REUSE 1
#define HAVE_MADV_FREE 1
#define HAVE_PTHREAD_SETNAME_NP 1
#endif
+#endif
+
#if PLATFORM(IPHONE)
#define HAVE_MADV_FREE 1
#endif
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
-#define HAVE_FLOAT_H 1
-#if PLATFORM(WINCE)
+#if OS(WINCE)
#define HAVE_ERRNO_H 0
#else
#define HAVE_SYS_TIMEB_H 1
#endif
#define HAVE_VIRTUALALLOC 1
-#elif PLATFORM(SYMBIAN)
+#elif OS(SYMBIAN)
#define HAVE_ERRNO_H 1
#define HAVE_MMAP 0
@@ -612,9 +736,19 @@
#define HAVE_SYS_PARAM_H 1
#endif
-#elif PLATFORM(QNX)
+#elif OS(QNX)
+
+#define HAVE_ERRNO_H 1
+#define HAVE_MMAP 1
+#define HAVE_SBRK 1
+#define HAVE_STRINGS_H 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_TIME_H 1
+
+#elif OS(ANDROID)
#define HAVE_ERRNO_H 1
+#define HAVE_LANGINFO_H 0
#define HAVE_MMAP 1
#define HAVE_SBRK 1
#define HAVE_STRINGS_H 1
@@ -627,7 +761,7 @@
#define HAVE_ERRNO_H 1
/* As long as Haiku doesn't have a complete support of locale this will be disabled. */
-#if !PLATFORM(HAIKU)
+#if !OS(HAIKU)
#define HAVE_LANGINFO_H 1
#endif
#define HAVE_MMAP 1
@@ -686,6 +820,14 @@
#define ENABLE_NETSCAPE_PLUGIN_API 1
#endif
+#if !defined(WTF_USE_PLUGIN_HOST_PROCESS)
+#define WTF_USE_PLUGIN_HOST_PROCESS 0
+#endif
+
+#if !defined(ENABLE_ORIENTATION_EVENTS)
+#define ENABLE_ORIENTATION_EVENTS 0
+#endif
+
#if !defined(ENABLE_OPCODE_STATS)
#define ENABLE_OPCODE_STATS 0
#endif
@@ -718,15 +860,11 @@
#endif
#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64)
-#if PLATFORM(X86_64) && (PLATFORM(DARWIN) || PLATFORM(LINUX) || PLATFORM(SOLARIS) || PLATFORM(HPUX))
-#define WTF_USE_JSVALUE64 1
-#elif (PLATFORM(IA64) && !PLATFORM(IA64_32)) || PLATFORM(SPARC64)
-#define WTF_USE_JSVALUE64 1
-#elif PLATFORM(AIX64)
+#if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS) || OS(SOLARIS) || OS(HPUX))) || (CPU(IA64) && !CPU(IA64_32)) || CPU(ALPHA) || CPU(AIX64) || CPU(SPARC64)
#define WTF_USE_JSVALUE64 1
-#elif PLATFORM(ARM) || PLATFORM(PPC64)
+#elif CPU(ARM) || CPU(PPC64)
#define WTF_USE_JSVALUE32 1
-#elif PLATFORM(WIN_OS) && COMPILER(MINGW)
+#elif OS(WINDOWS) && COMPILER(MINGW)
/* Using JSVALUE32_64 causes padding/alignement issues for JITStubArg
on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#define WTF_USE_JSVALUE32 1
@@ -742,36 +880,38 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#if !defined(ENABLE_JIT)
/* The JIT is tested & working on x86_64 Mac */
-#if PLATFORM(X86_64) && PLATFORM(MAC)
+#if CPU(X86_64) && PLATFORM(MAC)
#define ENABLE_JIT 1
/* The JIT is tested & working on x86 Mac */
-#elif PLATFORM(X86) && PLATFORM(MAC)
+#elif CPU(X86) && PLATFORM(MAC)
#define ENABLE_JIT 1
#define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1
-#elif PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE)
- /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */
- #define ENABLE_JIT 0
- #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0
+#elif CPU(ARM_THUMB2) && PLATFORM(IPHONE)
+ #define ENABLE_JIT 1
/* The JIT is tested & working on x86 Windows */
-#elif PLATFORM(X86) && PLATFORM(WIN)
+#elif CPU(X86) && PLATFORM(WIN)
#define ENABLE_JIT 1
#endif
#if PLATFORM(QT)
-#if PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100
+#if CPU(X86_64) && OS(DARWIN)
+ #define ENABLE_JIT 1
+#elif CPU(X86) && OS(DARWIN)
#define ENABLE_JIT 1
#define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1
-#elif PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MSVC)
+#elif CPU(X86) && OS(WINDOWS) && COMPILER(MINGW) && GCC_VERSION >= 40100
+ #define ENABLE_JIT 1
+ #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1
+#elif CPU(X86) && OS(WINDOWS) && COMPILER(MSVC)
#define ENABLE_JIT 1
#define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1
-#elif PLATFORM(X86) && PLATFORM(LINUX) && GCC_VERSION >= 40100
+#elif CPU(X86) && OS(LINUX) && GCC_VERSION >= 40100
#define ENABLE_JIT 1
#define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1
-#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX)
+#elif CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100
+ #define ENABLE_JIT 1
+#elif CPU(ARM_TRADITIONAL) && OS(LINUX)
#define ENABLE_JIT 1
- #if PLATFORM(ARM_THUMB2)
- #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0
- #endif
#endif
#endif /* PLATFORM(QT) */
@@ -792,9 +932,9 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#endif
#endif
-#if PLATFORM(X86) && COMPILER(MSVC)
+#if CPU(X86) && COMPILER(MSVC)
#define JSC_HOST_CALL __fastcall
-#elif PLATFORM(X86) && COMPILER(GCC)
+#elif CPU(X86) && COMPILER(GCC)
#define JSC_HOST_CALL __attribute__ ((fastcall))
#else
#define JSC_HOST_CALL
@@ -814,20 +954,20 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#if !defined(ENABLE_YARR_JIT)
/* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */
-#if (PLATFORM(X86) && PLATFORM(MAC)) \
- || (PLATFORM(X86_64) && PLATFORM(MAC)) \
- /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */ \
- || (PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) && 0) \
- || (PLATFORM(X86) && PLATFORM(WIN))
+#if (CPU(X86) && PLATFORM(MAC)) \
+ || (CPU(X86_64) && PLATFORM(MAC)) \
+ || (CPU(ARM_THUMB2) && PLATFORM(IPHONE)) \
+ || (CPU(X86) && PLATFORM(WIN))
#define ENABLE_YARR 1
#define ENABLE_YARR_JIT 1
#endif
#if PLATFORM(QT)
-#if (PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100) \
- || (PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MSVC)) \
- || (PLATFORM(X86) && PLATFORM(LINUX) && GCC_VERSION >= 40100) \
- || (PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX))
+#if (CPU(X86) && OS(WINDOWS) && COMPILER(MINGW) && GCC_VERSION >= 40100) \
+ || (CPU(X86) && OS(WINDOWS) && COMPILER(MSVC)) \
+ || (CPU(X86) && OS(LINUX) && GCC_VERSION >= 40100) \
+ || (CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100) \
+ || (CPU(ARM_TRADITIONAL) && OS(LINUX))
#define ENABLE_YARR 1
#define ENABLE_YARR_JIT 1
#endif
@@ -851,15 +991,15 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#define ENABLE_ASSEMBLER_WX_EXCLUSIVE 0
#endif
-#if !defined(ENABLE_PAN_SCROLLING) && PLATFORM(WIN_OS)
+#if !defined(ENABLE_PAN_SCROLLING) && OS(WINDOWS)
#define ENABLE_PAN_SCROLLING 1
#endif
-/* Use the QtXmlStreamReader implementation for XMLTokenizer */
+/* Use the QXmlStreamReader implementation for XMLTokenizer */
+/* Use the QXmlQuery implementation for XSLTProcessor */
#if PLATFORM(QT)
-#if !ENABLE(XSLT)
#define WTF_USE_QXMLSTREAM 1
-#endif
+#define WTF_USE_QXMLQUERY 1
#endif
#if !PLATFORM(QT)
@@ -877,13 +1017,30 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#define WTF_USE_ACCELERATED_COMPOSITING 1
#endif
+/* FIXME: Defining ENABLE_3D_RENDERING here isn't really right, but it's always used with
+ with WTF_USE_ACCELERATED_COMPOSITING, and it allows the feature to be turned on and
+ off in one place. */
+#if PLATFORM(WIN)
+#include "QuartzCorePresent.h"
+#if QUARTZCORE_PRESENT
+#define WTF_USE_ACCELERATED_COMPOSITING 1
+#define ENABLE_3D_RENDERING 1
+#endif
+#endif
+
#if COMPILER(GCC)
#define WARN_UNUSED_RETURN __attribute__ ((warn_unused_result))
#else
#define WARN_UNUSED_RETURN
#endif
+#if !ENABLE(NETSCAPE_PLUGIN_API) || (ENABLE(NETSCAPE_PLUGIN_API) && ((OS(UNIX) && (PLATFORM(QT) || PLATFORM(WX))) || PLATFORM(GTK)))
+#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1
+#endif
+
/* Set up a define for a common error that is intended to cause a build error -- thus the space after Error. */
#define WTF_PLATFORM_CFNETWORK Error USE_macro_should_be_used_with_CFNETWORK
+#define ENABLE_JSC_ZOMBIES 0
+
#endif /* WTF_Platform_h */
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PtrAndFlags.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PtrAndFlags.h
index 5d0bd2a..1e1bee0 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PtrAndFlags.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/PtrAndFlags.h
@@ -68,7 +68,7 @@ namespace WTF {
PtrAndFlags(T* ptr)
{
PtrAndFlagsBase<T, FlagEnum>::m_ptrAndFlags = 0;
- set(ptr);
+ PtrAndFlagsBase<T, FlagEnum>::set(ptr);
}
};
} // namespace WTF
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.cpp
index 52fb130..74bb45c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumber.cpp
@@ -34,7 +34,7 @@
#include <stdint.h>
#include <stdlib.h>
-#if PLATFORM(WINCE)
+#if OS(WINCE)
extern "C" {
#include "wince/mt19937ar.c"
}
@@ -66,10 +66,10 @@ double randomNumber()
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)
+#elif OS(DARWIN)
uint32_t bits = arc4random();
return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0);
-#elif PLATFORM(UNIX)
+#elif OS(UNIX)
uint32_t part1 = random() & (RAND_MAX - 1);
uint32_t part2 = random() & (RAND_MAX - 1);
// random only provides 31 bits
@@ -80,9 +80,9 @@ double randomNumber()
// Mask off the low 53bits
fullRandom &= (1LL << 53) - 1;
return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53);
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
return genrand_res53();
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
uint32_t part1 = rand() & (RAND_MAX - 1);
uint32_t part2 = rand() & (RAND_MAX - 1);
uint32_t part3 = rand() & (RAND_MAX - 1);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumberSeed.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumberSeed.h
index a66433e..ae414c0 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumberSeed.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RandomNumberSeed.h
@@ -33,12 +33,12 @@
#include <sys/time.h>
#endif
-#if PLATFORM(UNIX)
+#if OS(UNIX)
#include <sys/types.h>
#include <unistd.h>
#endif
-#if PLATFORM(WINCE)
+#if OS(WINCE)
extern "C" {
void init_by_array(unsigned long init_key[],int key_length);
}
@@ -49,9 +49,9 @@ namespace WTF {
inline void initializeRandomNumberGenerator()
{
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
// On Darwin we use arc4random which initialises itself.
-#elif PLATFORM(WINCE)
+#elif OS(WINCE)
// initialize rand()
srand(static_cast<unsigned>(time(0)));
@@ -64,7 +64,7 @@ inline void initializeRandomNumberGenerator()
init_by_array(initializationBuffer, 4);
#elif COMPILER(MSVC) && defined(_CRT_RAND_S)
// On Windows we use rand_s which initialises itself
-#elif PLATFORM(UNIX)
+#elif OS(UNIX)
// srandomdev is not guaranteed to exist on linux so we use this poor seed, this should be improved
timeval time;
gettimeofday(&time, 0);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtr.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtr.h
index 1a0b1fe..83c54bc 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtr.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/RefPtr.h
@@ -24,22 +24,27 @@
#include <algorithm>
#include "AlwaysInline.h"
#include "FastAllocBase.h"
+#if COMPILER(WINSCW)
+#include "PassRefPtr.h"
+#endif
namespace WTF {
enum PlacementNewAdoptType { PlacementNewAdopt };
template <typename T> class PassRefPtr;
+ template <typename T> class NonNullPassRefPtr;
enum HashTableDeletedValueType { HashTableDeletedValue };
template <typename T> class RefPtr : public FastAllocBase {
public:
RefPtr() : m_ptr(0) { }
- RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
- RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { T* ptr = m_ptr; refIfNotNull(ptr); }
+ RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
+ RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->ref(); }
// see comment in PassRefPtr.h for why this takes const reference
template <typename U> RefPtr(const PassRefPtr<U>&);
+ template <typename U> RefPtr(const NonNullPassRefPtr<U>&);
// Special constructor for cases where we overwrite an object in place.
RefPtr(PlacementNewAdoptType) { }
@@ -48,13 +53,21 @@ namespace WTF {
RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
- ~RefPtr() { T* ptr = m_ptr; derefIfNotNull(ptr); }
+#if COMPILER(WINSCW)
+ ~RefPtr() { if (T* ptr = m_ptr) derefIfNotNull<T>(ptr); }
+#else
+ ~RefPtr() { if (T* ptr = m_ptr) ptr->deref(); }
+#endif
- template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(static_cast<T*>(o.get())) { if (T* ptr = static_cast<T*>(m_ptr)) ptr->ref(); }
+ template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
T* get() const { return m_ptr; }
- void clear() { T* ptr = m_ptr; derefIfNotNull(ptr); m_ptr = 0; }
+#if COMPILER(WINSCW)
+ void clear() { if (T* ptr = m_ptr) derefIfNotNull<T>(ptr); m_ptr = 0; }
+#else
+ void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
+#endif
PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
T& operator*() const { return *m_ptr; }
@@ -73,8 +86,10 @@ namespace WTF {
RefPtr& operator=(const RefPtr&);
RefPtr& operator=(T*);
RefPtr& operator=(const PassRefPtr<T>&);
+ RefPtr& operator=(const NonNullPassRefPtr<T>&);
template <typename U> RefPtr& operator=(const RefPtr<U>&);
template <typename U> RefPtr& operator=(const PassRefPtr<U>&);
+ template <typename U> RefPtr& operator=(const NonNullPassRefPtr<U>&);
void swap(RefPtr&);
@@ -89,32 +104,43 @@ namespace WTF {
{
}
+ template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const NonNullPassRefPtr<U>& o)
+ : m_ptr(o.releaseRef())
+ {
+ }
+
template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
{
T* optr = o.get();
- refIfNotNull(optr);
+ if (optr)
+ optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
- derefIfNotNull(ptr);
+ if (ptr)
+ ptr->deref();
return *this;
}
template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o)
{
T* optr = o.get();
- refIfNotNull(optr);
+ if (optr)
+ optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
- derefIfNotNull(ptr);
+ if (ptr)
+ ptr->deref();
return *this;
}
template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr)
{
- refIfNotNull(optr);
+ if (optr)
+ optr->ref();
T* ptr = m_ptr;
m_ptr = optr;
- derefIfNotNull(ptr);
+ if (ptr)
+ ptr->deref();
return *this;
}
@@ -122,7 +148,17 @@ namespace WTF {
{
T* ptr = m_ptr;
m_ptr = o.releaseRef();
- derefIfNotNull(ptr);
+ if (ptr)
+ ptr->deref();
+ return *this;
+ }
+
+ template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const NonNullPassRefPtr<T>& o)
+ {
+ T* ptr = m_ptr;
+ m_ptr = o.releaseRef();
+ if (ptr)
+ ptr->deref();
return *this;
}
@@ -130,7 +166,17 @@ namespace WTF {
{
T* ptr = m_ptr;
m_ptr = o.releaseRef();
- derefIfNotNull(ptr);
+ if (ptr)
+ ptr->deref();
+ return *this;
+ }
+
+ template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const NonNullPassRefPtr<U>& o)
+ {
+ T* ptr = m_ptr;
+ m_ptr = o.releaseRef();
+ if (ptr)
+ ptr->deref();
return *this;
}
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StdLibExtras.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StdLibExtras.h
index d21d1ff..9dfb969 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StdLibExtras.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StdLibExtras.h
@@ -32,6 +32,7 @@
// 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.
+#ifndef DEFINE_STATIC_LOCAL
#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; \
@@ -40,12 +41,17 @@
#define DEFINE_STATIC_LOCAL(type, name, arguments) \
static type& name = *new type arguments
#endif
+#endif
// OBJECT_OFFSETOF: Like the C++ offsetof macro, but you can use it with classes.
// The magic number 0x4000 is insignificant. We use it to avoid using NULL, since
// NULL can cause compiler problems, especially in cases of multiple inheritance.
#define OBJECT_OFFSETOF(class, field) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->field)) - 0x4000)
+// STRINGIZE: Can convert any value to quoted string, even expandable macros
+#define STRINGIZE(exp) #exp
+#define STRINGIZE_VALUE_OF(exp) STRINGIZE(exp)
+
namespace WTF {
/*
@@ -63,6 +69,14 @@ namespace WTF {
return u.to;
}
+ // Returns a count of the number of bits set in 'bits'.
+ inline size_t bitCount(unsigned bits)
+ {
+ bits = bits - ((bits >> 1) & 0x55555555);
+ bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
+ return (((bits + (bits >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
+ }
+
} // namespace WTF
#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.cpp
new file mode 100644
index 0000000..1b96417
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 Company 100, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if COMPILER(RVCT) && __ARMCC_VERSION < 400000
+
+#include "StringExtras.h"
+
+#include "ASCIICType.h"
+
+int strcasecmp(const char* s1, const char* s2)
+{
+ while (toASCIIUpper(*s1) == toASCIIUpper(*s2)) {
+ if (*s1 == '\0')
+ return 0;
+ s1++;
+ s2++;
+ }
+
+ return toASCIIUpper(*s1) - toASCIIUpper(*s2);
+}
+
+int strncasecmp(const char* s1, const char* s2, size_t len)
+{
+ while (len > 0 && toASCIIUpper(*s1) == toASCIIUpper(*s2)) {
+ if (*s1 == '\0')
+ return 0;
+ s1++;
+ s2++;
+ len--;
+ }
+
+ if (!len)
+ return 0;
+
+ return toASCIIUpper(*s1) - toASCIIUpper(*s2);
+}
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.h
index 559e3f2..b1ec09f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringExtras.h
@@ -34,6 +34,7 @@
#endif
#if COMPILER(MSVC)
+// FIXME: why a COMPILER check instead of OS? also, these should be HAVE checks
inline int snprintf(char* buffer, size_t count, const char* format, ...)
{
@@ -45,7 +46,7 @@ inline int snprintf(char* buffer, size_t count, const char* format, ...)
return result;
}
-#if COMPILER(MSVC7) || PLATFORM(WINCE)
+#if COMPILER(MSVC7) || OS(WINCE)
inline int vsnprintf(char* buffer, size_t count, const char* format, va_list args)
{
@@ -54,7 +55,7 @@ inline int vsnprintf(char* buffer, size_t count, const char* format, va_list arg
#endif
-#if PLATFORM(WINCE)
+#if OS(WINCE)
inline int strnicmp(const char* string1, const char* string2, size_t count)
{
@@ -75,17 +76,18 @@ inline char* strdup(const char* strSource)
inline int strncasecmp(const char* s1, const char* s2, size_t len)
{
- return strnicmp(s1, s2, len);
+ return _strnicmp(s1, s2, len);
}
inline int strcasecmp(const char* s1, const char* s2)
{
- return stricmp(s1, s2);
+ return _stricmp(s1, s2);
}
#endif
-#if PLATFORM(WIN_OS) || PLATFORM(LINUX)
+#if OS(WINDOWS) || OS(LINUX) || OS(SOLARIS)
+// FIXME: should check HAVE_STRNSTR
inline char* strnstr(const char* buffer, const char* target, size_t bufferLength)
{
@@ -101,4 +103,11 @@ inline char* strnstr(const char* buffer, const char* target, size_t bufferLength
#endif
+#if COMPILER(RVCT) && __ARMCC_VERSION < 400000
+
+int strcasecmp(const char* s1, const char* s2);
+int strncasecmp(const char* s1, const char* s2, size_t len);
+
+#endif
+
#endif // WTF_StringExtras_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringHashFunctions.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringHashFunctions.h
new file mode 100644
index 0000000..07f117f
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/StringHashFunctions.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2005, 2006, 2008, 2010 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 WTF_StringHashFunctions_h
+#define WTF_StringHashFunctions_h
+
+#include <wtf/unicode/Unicode.h>
+
+namespace WTF {
+
+// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
+static const unsigned stringHashingStartValue = 0x9e3779b9U;
+
+// stringHash methods based on Paul Hsieh's SuperFastHash.
+// http://www.azillionmonkeys.com/qed/hash.html
+// char* data is interpreted as latin-encoded (zero extended to 16 bits).
+
+inline unsigned stringHash(const UChar* data, unsigned length)
+{
+ unsigned hash = WTF::stringHashingStartValue;
+ unsigned rem = length & 1;
+ length >>= 1;
+
+ // Main loop
+ for (; length > 0; length--) {
+ hash += data[0];
+ unsigned tmp = (data[1] << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ data += 2;
+ hash += hash >> 11;
+ }
+
+ // Handle end case
+ if (rem) {
+ hash += data[0];
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ }
+
+ // Force "avalanching" of final 127 bits
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 2;
+ hash += hash >> 15;
+ hash ^= hash << 10;
+
+ hash &= 0x7fffffff;
+
+ // this avoids ever returning a hash code of 0, since that is used to
+ // signal "hash not computed yet", using a value that is likely to be
+ // effectively the same as 0 when the low bits are masked
+ if (hash == 0)
+ hash = 0x40000000;
+
+ return hash;
+}
+
+inline unsigned stringHash(const char* data, unsigned length)
+{
+ unsigned hash = WTF::stringHashingStartValue;
+ unsigned rem = length & 1;
+ length >>= 1;
+
+ // Main loop
+ for (; length > 0; length--) {
+ hash += static_cast<unsigned char>(data[0]);
+ unsigned tmp = (static_cast<unsigned char>(data[1]) << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ data += 2;
+ hash += hash >> 11;
+ }
+
+ // Handle end case
+ if (rem) {
+ hash += static_cast<unsigned char>(data[0]);
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ }
+
+ // Force "avalanching" of final 127 bits
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 2;
+ hash += hash >> 15;
+ hash ^= hash << 10;
+
+ hash &= 0x7fffffff;
+
+ // this avoids ever returning a hash code of 0, since that is used to
+ // signal "hash not computed yet", using a value that is likely to be
+ // effectively the same as 0 when the low bits are masked
+ if (hash == 0)
+ hash = 0x40000000;
+
+ return hash;
+}
+
+inline unsigned stringHash(const char* data)
+{
+ unsigned hash = WTF::stringHashingStartValue;
+
+ // Main loop
+ for (;;) {
+ unsigned char b0 = data[0];
+ if (!b0)
+ break;
+ unsigned char b1 = data[1];
+ if (!b1) {
+ hash += b0;
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ break;
+ }
+ hash += b0;
+ unsigned tmp = (b1 << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ data += 2;
+ hash += hash >> 11;
+ }
+
+ // Force "avalanching" of final 127 bits.
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 2;
+ hash += hash >> 15;
+ hash ^= hash << 10;
+
+ hash &= 0x7fffffff;
+
+ // This avoids ever returning a hash code of 0, since that is used to
+ // signal "hash not computed yet", using a value that is likely to be
+ // effectively the same as 0 when the low bits are masked.
+ if (hash == 0)
+ hash = 0x40000000;
+
+ return hash;
+}
+
+} // namespace WTF
+
+#endif // WTF_StringHashFunctions_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h
index 4cf30c2..8a73e13 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSpinLock.h
@@ -33,7 +33,7 @@
#ifndef TCMALLOC_INTERNAL_SPINLOCK_H__
#define TCMALLOC_INTERNAL_SPINLOCK_H__
-#if (PLATFORM(X86) || PLATFORM(PPC)) && (COMPILER(GCC) || COMPILER(MSVC))
+#if (CPU(X86) || CPU(X86_64) || CPU(PPC)) && (COMPILER(GCC) || COMPILER(MSVC))
#include <time.h> /* For nanosleep() */
@@ -47,7 +47,7 @@
#include <sys/types.h>
#endif
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
@@ -62,7 +62,7 @@ struct TCMalloc_SpinLock {
inline void Lock() {
int r;
#if COMPILER(GCC)
-#if PLATFORM(X86)
+#if CPU(X86) || CPU(X86_64)
__asm__ __volatile__
("xchgl %0, %1"
: "=r"(r), "=m"(lockword_)
@@ -92,7 +92,7 @@ struct TCMalloc_SpinLock {
inline void Unlock() {
#if COMPILER(GCC)
-#if PLATFORM(X86)
+#if CPU(X86) || CPU(X86_64)
__asm__ __volatile__
("movl $0, %0"
: "=m"(lockword_)
@@ -103,7 +103,7 @@ struct TCMalloc_SpinLock {
("isync\n\t"
"eieio\n\t"
"stw %1, %0"
-#if PLATFORM(DARWIN) || PLATFORM(PPC)
+#if OS(DARWIN) || CPU(PPC)
: "=o" (lockword_)
#else
: "=m" (lockword_)
@@ -138,7 +138,7 @@ static void TCMalloc_SlowLock(volatile unsigned int* lockword) {
while (true) {
int r;
#if COMPILER(GCC)
-#if PLATFORM(X86)
+#if CPU(X86) || CPU(X86_64)
__asm__ __volatile__
("xchgl %0, %1"
: "=r"(r), "=m"(*lockword)
@@ -178,7 +178,7 @@ static void TCMalloc_SlowLock(volatile unsigned int* lockword) {
// from taking 30 seconds to 16 seconds.
// Sleep for a few milliseconds
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
Sleep(2);
#else
struct timespec tm;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.cpp
index a43baa8..909f14e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TCSystemAlloc.cpp
@@ -47,7 +47,7 @@
#include <sys/types.h>
#endif
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#include "windows.h"
#else
#include <errno.h>
@@ -324,10 +324,10 @@ static void* TryDevMem(size_t size, size_t *actual_size, size_t alignment) {
// Return the unused virtual memory to the system
if (adjust > 0) {
- munmap(reinterpret_cast<char*>(ptr), adjust);
+ munmap(reinterpret_cast<void*>(ptr), adjust);
}
if (adjust < extra) {
- munmap(reinterpret_cast<char*>(ptr + adjust + size), extra - adjust);
+ munmap(reinterpret_cast<void*>(ptr + adjust + size), extra - adjust);
}
ptr += adjust;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp
new file mode 100644
index 0000000..042d49e
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(PTHREADS)
+
+#include "ThreadIdentifierDataPthreads.h"
+
+#include "Threading.h"
+
+namespace WTF {
+
+pthread_key_t ThreadIdentifierData::m_key;
+
+void clearPthreadHandleForIdentifier(ThreadIdentifier);
+
+ThreadIdentifierData::~ThreadIdentifierData()
+{
+ clearPthreadHandleForIdentifier(m_identifier);
+}
+
+ThreadIdentifier ThreadIdentifierData::identifier()
+{
+ initializeKeyOnce();
+ ThreadIdentifierData* threadIdentifierData = static_cast<ThreadIdentifierData*>(pthread_getspecific(m_key));
+
+ return threadIdentifierData ? threadIdentifierData->m_identifier : 0;
+}
+
+void ThreadIdentifierData::initialize(ThreadIdentifier id)
+{
+ ASSERT(!identifier());
+
+ initializeKeyOnce();
+ pthread_setspecific(m_key, new ThreadIdentifierData(id));
+}
+
+void ThreadIdentifierData::destruct(void* data)
+{
+ ThreadIdentifierData* threadIdentifierData = static_cast<ThreadIdentifierData*>(data);
+ ASSERT(threadIdentifierData);
+
+ if (threadIdentifierData->m_isDestroyedOnce) {
+ delete threadIdentifierData;
+ return;
+ }
+
+ threadIdentifierData->m_isDestroyedOnce = true;
+ // Re-setting the value for key causes another destruct() call after all other thread-specific destructors were called.
+ pthread_setspecific(m_key, threadIdentifierData);
+}
+
+void ThreadIdentifierData::initializeKeyOnceHelper()
+{
+ if (pthread_key_create(&m_key, destruct))
+ CRASH();
+}
+
+void ThreadIdentifierData::initializeKeyOnce()
+{
+ static pthread_once_t onceControl = PTHREAD_ONCE_INIT;
+ if (pthread_once(&onceControl, initializeKeyOnceHelper))
+ CRASH();
+}
+
+} // namespace WTF
+
+#endif // USE(PTHREADS)
+
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h
new file mode 100644
index 0000000..3af87a8
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h
@@ -0,0 +1,77 @@
+/*
+ * 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 ThreadIdentifierDataPthreads_h
+#define ThreadIdentifierDataPthreads_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/Threading.h>
+
+namespace WTF {
+
+// Holds ThreadIdentifier in the thread-specific storage and employs pthreads-specific 2-pass destruction to reliably remove
+// ThreadIdentifier from threadMap. It assumes regular ThreadSpecific types don't use multiple-pass destruction.
+class ThreadIdentifierData : public Noncopyable {
+public:
+ ~ThreadIdentifierData();
+
+ // Creates and puts an instance of ThreadIdentifierData into thread-specific storage.
+ static void initialize(ThreadIdentifier identifier);
+
+ // Returns 0 if thread-specific storage was not initialized.
+ static ThreadIdentifier identifier();
+
+private:
+ ThreadIdentifierData(ThreadIdentifier identifier)
+ : m_identifier(identifier)
+ , m_isDestroyedOnce(false)
+ {
+ }
+
+ // This thread-specific destructor is called 2 times when thread terminates:
+ // - first, when all the other thread-specific destructors are called, it simply remembers it was 'destroyed once'
+ // and re-sets itself into the thread-specific slot to make Pthreads to call it again later.
+ // - second, after all thread-specific destructors were invoked, it gets called again - this time, we remove the
+ // ThreadIdentifier from the threadMap, completing the cleanup.
+ static void destruct(void* data);
+
+ static void initializeKeyOnceHelper();
+ static void initializeKeyOnce();
+
+ ThreadIdentifier m_identifier;
+ bool m_isDestroyedOnce;
+ static pthread_key_t m_key;
+};
+
+} // namespace WTF
+
+#endif // ThreadIdentifierDataPthreads_h
+
+
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadSpecific.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadSpecific.h
index b6f5fd3..3abbc58 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadSpecific.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadSpecific.h
@@ -47,13 +47,13 @@
#include <pthread.h>
#elif PLATFORM(QT)
#include <QThreadStorage>
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
#include <windows.h>
#endif
namespace WTF {
-#if !USE(PTHREADS) && !PLATFORM(QT) && PLATFORM(WIN_OS)
+#if !USE(PTHREADS) && !PLATFORM(QT) && OS(WINDOWS)
// ThreadSpecificThreadExit should be called each time when a thread is detached.
// This is done automatically for threads created with WTF::createThread.
void ThreadSpecificThreadExit();
@@ -68,7 +68,7 @@ public:
~ThreadSpecific();
private:
-#if !USE(PTHREADS) && !PLATFORM(QT) && PLATFORM(WIN_OS)
+#if !USE(PTHREADS) && !PLATFORM(QT) && OS(WINDOWS)
friend void ThreadSpecificThreadExit();
#endif
@@ -76,7 +76,7 @@ private:
void set(T*);
void static destroy(void* ptr);
-#if USE(PTHREADS) || PLATFORM(QT) || PLATFORM(WIN_OS)
+#if USE(PTHREADS) || PLATFORM(QT) || OS(WINDOWS)
struct Data : Noncopyable {
Data(T* value, ThreadSpecific<T>* owner) : value(value), owner(owner) {}
#if PLATFORM(QT)
@@ -91,15 +91,44 @@ private:
};
#endif
+#if ENABLE(SINGLE_THREADED)
+ T* m_value;
+#else
#if USE(PTHREADS)
pthread_key_t m_key;
#elif PLATFORM(QT)
QThreadStorage<Data*> m_key;
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
int m_index;
#endif
+#endif
};
+#if ENABLE(SINGLE_THREADED)
+template<typename T>
+inline ThreadSpecific<T>::ThreadSpecific()
+ : m_value(0)
+{
+}
+
+template<typename T>
+inline ThreadSpecific<T>::~ThreadSpecific()
+{
+}
+
+template<typename T>
+inline T* ThreadSpecific<T>::get()
+{
+ return m_value;
+}
+
+template<typename T>
+inline void ThreadSpecific<T>::set(T* ptr)
+{
+ ASSERT(!get());
+ m_value = ptr;
+}
+#else
#if USE(PTHREADS)
template<typename T>
inline ThreadSpecific<T>::ThreadSpecific()
@@ -157,7 +186,7 @@ inline void ThreadSpecific<T>::set(T* ptr)
m_key.setLocalData(data);
}
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
// 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.
@@ -207,10 +236,12 @@ inline void ThreadSpecific<T>::set(T* ptr)
#else
#error ThreadSpecific is not implemented for this platform.
#endif
+#endif
template<typename T>
inline void ThreadSpecific<T>::destroy(void* ptr)
{
+#if !ENABLE(SINGLE_THREADED)
Data* data = static_cast<Data*>(ptr);
#if USE(PTHREADS)
@@ -230,7 +261,7 @@ inline void ThreadSpecific<T>::destroy(void* ptr)
pthread_setspecific(data->owner->m_key, 0);
#elif PLATFORM(QT)
// Do nothing here
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
TlsSetValue(tlsKeys()[data->owner->m_index], 0);
#else
#error ThreadSpecific is not implemented for this platform.
@@ -239,6 +270,7 @@ inline void ThreadSpecific<T>::destroy(void* ptr)
#if !PLATFORM(QT)
delete data;
#endif
+#endif
}
template<typename T>
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.cpp
index 56bf438..49de59e 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.cpp
@@ -49,13 +49,14 @@ static void* threadEntryPoint(void* contextData)
{
NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData);
- setThreadNameInternal(context->name);
-
- // Block until our creating thread has completed any extra setup work
+ // Block until our creating thread has completed any extra setup work, including
+ // establishing ThreadIdentifier.
{
MutexLocker locker(context->creationMutex);
}
+ initializeCurrentThreadInternal(context->name);
+
// Grab the info that we need out of the context, then deallocate it.
ThreadFunction entryPoint = context->entryPoint;
void* data = context->data;
@@ -75,7 +76,7 @@ ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*
NewThreadContext* context = new NewThreadContext(entryPoint, data, name);
- // Prevent the thread body from executing until we've established the thread identifier
+ // Prevent the thread body from executing until we've established the thread identifier.
MutexLocker locker(context->creationMutex);
return createThreadInternal(threadEntryPoint, context, name);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h
index 5154545..1599562 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h
@@ -61,7 +61,7 @@
#include "Platform.h"
-#if PLATFORM(WINCE)
+#if OS(WINCE)
#include <windows.h>
#endif
@@ -69,10 +69,12 @@
#include <wtf/Locker.h>
#include <wtf/Noncopyable.h>
-#if PLATFORM(WIN_OS) && !PLATFORM(WINCE)
+#if OS(WINDOWS) && !OS(WINCE)
#include <windows.h>
-#elif PLATFORM(DARWIN)
+#elif OS(DARWIN)
#include <libkern/OSAtomic.h>
+#elif OS(ANDROID)
+#include <cutils/atomic.h>
#elif COMPILER(GCC)
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
#include <ext/atomicity.h>
@@ -84,7 +86,7 @@
#if USE(PTHREADS)
#include <pthread.h>
#elif PLATFORM(GTK)
-#include <wtf/GOwnPtr.h>
+#include <wtf/gtk/GOwnPtr.h>
typedef struct _GMutex GMutex;
typedef struct _GCond GCond;
#endif
@@ -119,7 +121,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadN
// Called in the thread during initialization.
// Helpful for platforms where the thread name must be set from within the thread.
-void setThreadNameInternal(const char* threadName);
+void initializeCurrentThreadInternal(const char* threadName);
ThreadIdentifier currentThread();
bool isMainThread();
@@ -128,7 +130,11 @@ void detachThread(ThreadIdentifier);
#if USE(PTHREADS)
typedef pthread_mutex_t PlatformMutex;
+#if HAVE(PTHREAD_RWLOCK)
typedef pthread_rwlock_t PlatformReadWriteLock;
+#else
+typedef void* PlatformReadWriteLock;
+#endif
typedef pthread_cond_t PlatformCondition;
#elif PLATFORM(GTK)
typedef GOwnPtr<GMutex> PlatformMutex;
@@ -138,7 +144,7 @@ typedef GOwnPtr<GCond> PlatformCondition;
typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex;
typedef void* PlatformReadWriteLock; // FIXME: Implement.
typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition;
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
struct PlatformMutex {
CRITICAL_SECTION m_internalMutex;
size_t m_recursionCount;
@@ -211,10 +217,10 @@ private:
PlatformCondition m_condition;
};
-#if PLATFORM(WIN_OS)
+#if OS(WINDOWS)
#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
-#if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WINCE)
+#if COMPILER(MINGW) || COMPILER(MSVC7) || OS(WINCE)
inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); }
inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }
#else
@@ -222,13 +228,18 @@ inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(r
inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); }
#endif
-#elif PLATFORM(DARWIN)
+#elif OS(DARWIN)
#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); }
inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); }
-#elif COMPILER(GCC) && !PLATFORM(SPARC64) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc
+#elif OS(ANDROID)
+
+inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(addend); }
+inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); }
+
+#elif COMPILER(GCC) && !CPU(SPARC64) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc
#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; }
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingNone.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingNone.cpp
index 46f23d2..2e8a259 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingNone.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingNone.cpp
@@ -30,11 +30,13 @@
#include "config.h"
#include "Threading.h"
+#if ENABLE(SINGLE_THREADED)
+
namespace WTF {
void initializeThreading() { }
ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char*) { return ThreadIdentifier(); }
-void setThreadNameInternal(const char*) { }
+void initializeCurrentThreadInternal(const char*) { }
int waitForThreadCompletion(ThreadIdentifier, void**) { return 0; }
void detachThread(ThreadIdentifier) { }
ThreadIdentifier currentThread() { return ThreadIdentifier(); }
@@ -57,3 +59,5 @@ void lockAtomicallyInitializedStaticMutex() { }
void unlockAtomicallyInitializedStaticMutex() { }
} // namespace WebCore
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp
index e4fb419..2feb808 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingPthreads.cpp
@@ -37,6 +37,8 @@
#include "MainThread.h"
#include "RandomNumberSeed.h"
#include "StdLibExtras.h"
+#include "ThreadIdentifierDataPthreads.h"
+#include "ThreadSpecific.h"
#include "UnusedParam.h"
#include <errno.h>
@@ -45,7 +47,7 @@
#include <sys/time.h>
#endif
-#if PLATFORM(ANDROID)
+#if OS(ANDROID)
#include "jni_utility.h"
#endif
@@ -55,10 +57,12 @@ typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap;
static Mutex* atomicallyInitializedStaticMutex;
-#if !PLATFORM(DARWIN) || PLATFORM(CHROMIUM)
-static ThreadIdentifier mainThreadIdentifier; // The thread that was the first to call initializeThreading(), which must be the main thread.
+#if !OS(DARWIN) || PLATFORM(CHROMIUM) || USE(WEB_THREAD)
+static pthread_t mainThread; // The thread that was the first to call initializeThreading(), which must be the main thread.
#endif
+void clearPthreadHandleForIdentifier(ThreadIdentifier);
+
static Mutex& threadMapMutex()
{
DEFINE_STATIC_LOCAL(Mutex, mutex, ());
@@ -71,8 +75,8 @@ void initializeThreading()
atomicallyInitializedStaticMutex = new Mutex;
threadMapMutex();
initializeRandomNumberGenerator();
-#if !PLATFORM(DARWIN) || PLATFORM(CHROMIUM)
- mainThreadIdentifier = currentThread();
+#if !OS(DARWIN) || PLATFORM(CHROMIUM) || USE(WEB_THREAD)
+ mainThread = pthread_self();
#endif
initializeMainThread();
}
@@ -108,7 +112,7 @@ static ThreadIdentifier identifierByPthreadHandle(const pthread_t& pthreadHandle
return 0;
}
-static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHandle)
+static ThreadIdentifier establishIdentifierForPthreadHandle(const pthread_t& pthreadHandle)
{
ASSERT(!identifierByPthreadHandle(pthreadHandle));
@@ -128,7 +132,7 @@ static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id)
return threadMap().get(id);
}
-static void clearPthreadHandleForIdentifier(ThreadIdentifier id)
+void clearPthreadHandleForIdentifier(ThreadIdentifier id)
{
MutexLocker locker(threadMapMutex());
@@ -137,7 +141,7 @@ static void clearPthreadHandleForIdentifier(ThreadIdentifier id)
threadMap().remove(id);
}
-#if PLATFORM(ANDROID)
+#if OS(ANDROID)
// On the Android platform, threads must be registered with the VM before they run.
struct ThreadData {
ThreadFunction entryPoint;
@@ -167,6 +171,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
if (pthread_create(&threadHandle, 0, runThreadWithRegistration, static_cast<void*>(threadData))) {
LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
+ delete threadData;
return 0;
}
return establishIdentifierForPthreadHandle(threadHandle);
@@ -184,13 +189,17 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
}
#endif
-void setThreadNameInternal(const char* threadName)
+void initializeCurrentThreadInternal(const char* threadName)
{
#if HAVE(PTHREAD_SETNAME_NP)
pthread_setname_np(threadName);
#else
UNUSED_PARAM(threadName);
#endif
+
+ ThreadIdentifier id = identifierByPthreadHandle(pthread_self());
+ ASSERT(id);
+ ThreadIdentifierData::initialize(id);
}
int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
@@ -198,12 +207,13 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
ASSERT(threadID);
pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
+ if (!pthreadHandle)
+ return 0;
int joinResult = pthread_join(pthreadHandle, result);
if (joinResult == EDEADLK)
LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
- clearPthreadHandleForIdentifier(threadID);
return joinResult;
}
@@ -212,26 +222,30 @@ void detachThread(ThreadIdentifier threadID)
ASSERT(threadID);
pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
+ if (!pthreadHandle)
+ return;
pthread_detach(pthreadHandle);
-
- clearPthreadHandleForIdentifier(threadID);
}
ThreadIdentifier currentThread()
{
- pthread_t currentThread = pthread_self();
- if (ThreadIdentifier id = identifierByPthreadHandle(currentThread))
+ ThreadIdentifier id = ThreadIdentifierData::identifier();
+ if (id)
return id;
- return establishIdentifierForPthreadHandle(currentThread);
+
+ // Not a WTF-created thread, ThreadIdentifier is not established yet.
+ id = establishIdentifierForPthreadHandle(pthread_self());
+ ThreadIdentifierData::initialize(id);
+ return id;
}
bool isMainThread()
{
-#if PLATFORM(DARWIN) && !PLATFORM(CHROMIUM)
+#if OS(DARWIN) && !PLATFORM(CHROMIUM) && !USE(WEB_THREAD)
return pthread_main_np();
#else
- return currentThread() == mainThreadIdentifier;
+ return pthread_equal(pthread_self(), mainThread);
#endif
}
@@ -270,7 +284,7 @@ void Mutex::unlock()
ASSERT_UNUSED(result, !result);
}
-
+#if HAVE(PTHREAD_RWLOCK)
ReadWriteLock::ReadWriteLock()
{
pthread_rwlock_init(&m_readWriteLock, NULL);
@@ -324,6 +338,7 @@ void ReadWriteLock::unlock()
int result = pthread_rwlock_unlock(&m_readWriteLock);
ASSERT_UNUSED(result, !result);
}
+#endif // HAVE(PTHREAD_RWLOCK)
ThreadCondition::ThreadCondition()
{
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingWin.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingWin.cpp
index cccbda1..73c3f0c 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingWin.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/ThreadingWin.cpp
@@ -87,10 +87,10 @@
#include "Threading.h"
#include "MainThread.h"
-#if !USE(PTHREADS) && PLATFORM(WIN_OS)
+#if !USE(PTHREADS) && OS(WINDOWS)
#include "ThreadSpecific.h"
#endif
-#if !PLATFORM(WINCE)
+#if !OS(WINCE)
#include <process.h>
#endif
#if HAVE(ERRNO_H)
@@ -118,7 +118,7 @@ typedef struct tagTHREADNAME_INFO {
} THREADNAME_INFO;
#pragma pack(pop)
-void setThreadNameInternal(const char* szThreadName)
+void initializeCurrentThreadInternal(const char* szThreadName)
{
THREADNAME_INFO info;
info.dwType = 0x1000;
@@ -161,7 +161,7 @@ void initializeThreading()
initializeRandomNumberGenerator();
initializeMainThread();
mainThreadIdentifier = currentThread();
- setThreadNameInternal("Main Thread");
+ initializeCurrentThreadInternal("Main Thread");
}
}
@@ -205,7 +205,7 @@ static unsigned __stdcall wtfThreadEntryPoint(void* param)
void* result = invocation.function(invocation.data);
-#if !USE(PTHREADS) && PLATFORM(WIN_OS)
+#if !USE(PTHREADS) && OS(WINDOWS)
// Do the TLS cleanup.
ThreadSpecificThreadExit();
#endif
@@ -218,7 +218,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
unsigned threadIdentifier = 0;
ThreadIdentifier threadID = 0;
ThreadFunctionInvocation* invocation = new ThreadFunctionInvocation(entryPoint, data);
-#if PLATFORM(WINCE)
+#if OS(WINCE)
// This is safe on WINCE, since CRT is in the core and innately multithreaded.
// On desktop Windows, need to use _beginthreadex (not available on WinCE) if using any CRT functions
HANDLE threadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)wtfThreadEntryPoint, invocation, 0, (LPDWORD)&threadIdentifier);
@@ -226,7 +226,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
HANDLE threadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, wtfThreadEntryPoint, invocation, 0, &threadIdentifier));
#endif
if (!threadHandle) {
-#if PLATFORM(WINCE)
+#if OS(WINCE)
LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, ::GetLastError());
#elif defined(NO_ERRNO)
LOG_ERROR("Failed to create thread at entry point %p with data %p.", entryPoint, data);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.cpp
index 36fc6c6..9e51ad0 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 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
@@ -101,6 +101,20 @@ COMPILE_ASSERT((!IsSameType<int, int*>::value), WTF_IsSameType_int_int_pointer_f
COMPILE_ASSERT((!IsSameType<bool, const bool>::value), WTF_IsSameType_const_change_false);
COMPILE_ASSERT((!IsSameType<bool, volatile bool>::value), WTF_IsSameType_volatile_change_false);
+template <typename T>
+class TestBaseClass {
+};
+
+class TestDerivedClass : public TestBaseClass<int> {
+};
+
+COMPILE_ASSERT((IsSubclass<TestDerivedClass, TestBaseClass<int> >::value), WTF_Test_IsSubclass_Derived_From_Base);
+COMPILE_ASSERT((!IsSubclass<TestBaseClass<int>, TestDerivedClass>::value), WTF_Test_IsSubclass_Base_From_Derived);
+COMPILE_ASSERT((IsSubclassOfTemplate<TestDerivedClass, TestBaseClass>::value), WTF_Test_IsSubclassOfTemplate_Base_From_Derived);
+COMPILE_ASSERT((IsSameType<RemoveTemplate<TestBaseClass<int>, TestBaseClass>::Type, int>::value), WTF_Test_RemoveTemplate);
+COMPILE_ASSERT((IsSameType<RemoveTemplate<int, TestBaseClass>::Type, int>::value), WTF_Test_RemoveTemplate_WithoutTemplate);
+
+
COMPILE_ASSERT((IsSameType<bool, RemoveConst<const bool>::Type>::value), WTF_test_RemoveConst_const_bool);
COMPILE_ASSERT((!IsSameType<bool, RemoveConst<volatile bool>::Type>::value), WTF_test_RemoveConst_volatile_bool);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h
index c03e8a7..7ba487f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 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
@@ -104,6 +104,40 @@ namespace WTF {
static const bool value = true;
};
+ template <typename T, typename U> class IsSubclass {
+ typedef char YesType;
+ struct NoType {
+ char padding[8];
+ };
+
+ static YesType subclassCheck(U*);
+ static NoType subclassCheck(...);
+ static T* t;
+ public:
+ static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
+ };
+
+ template <typename T, template<class V> class U> class IsSubclassOfTemplate {
+ typedef char YesType;
+ struct NoType {
+ char padding[8];
+ };
+
+ template<typename W> static YesType subclassCheck(U<W>*);
+ static NoType subclassCheck(...);
+ static T* t;
+ public:
+ static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
+ };
+
+ template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate {
+ typedef T Type;
+ };
+
+ template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> {
+ typedef T Type;
+ };
+
template <typename T> struct RemoveConst {
typedef T Type;
};
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VMTags.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VMTags.h
index 519f518..1ec79d9 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VMTags.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VMTags.h
@@ -30,7 +30,7 @@
// On Mac OS X, the VM subsystem allows tagging memory requested from mmap and vm_map
// in order to aid tools that inspect system memory use.
-#if PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER)
+#if OS(DARWIN) && !defined(BUILDING_ON_TIGER)
#include <mach/vm_statistics.h>
@@ -44,12 +44,12 @@
#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(65)
#endif // defined(VM_MEMORY_JAVASCRIPT_CORE) && defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) && defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) && defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR)
-#else // PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER)
+#else // OS(DARWIN) && !defined(BUILDING_ON_TIGER)
#define VM_TAG_FOR_COLLECTOR_MEMORY -1
#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1
#define VM_TAG_FOR_REGISTERFILE_MEMORY -1
-#endif // PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER)
+#endif // OS(DARWIN) && !defined(BUILDING_ON_TIGER)
#endif // VMTags_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Vector.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Vector.h
index 7decc4a..8a4ffba 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Vector.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/Vector.h
@@ -76,8 +76,15 @@ namespace WTF {
};
#endif
+ template <size_t size, size_t alignment>
+ void swap(AlignedBuffer<size, alignment>& a, AlignedBuffer<size, alignment>& b)
+ {
+ for (size_t i = 0; i < size; ++i)
+ std::swap(a.buffer[i], b.buffer[i]);
+ }
+
template <bool needsDestruction, typename T>
- class VectorDestructor;
+ struct VectorDestructor;
template<typename T>
struct VectorDestructor<false, T>
@@ -96,7 +103,7 @@ namespace WTF {
};
template <bool needsInitialization, bool canInitializeWithMemset, typename T>
- class VectorInitializer;
+ struct VectorInitializer;
template<bool ignore, typename T>
struct VectorInitializer<false, ignore, T>
@@ -124,7 +131,7 @@ namespace WTF {
};
template <bool canMoveWithMemcpy, typename T>
- class VectorMover;
+ struct VectorMover;
template<typename T>
struct VectorMover<false, T>
@@ -168,7 +175,7 @@ namespace WTF {
};
template <bool canCopyWithMemcpy, typename T>
- class VectorCopier;
+ struct VectorCopier;
template<typename T>
struct VectorCopier<false, T>
@@ -193,7 +200,7 @@ namespace WTF {
};
template <bool canFillWithMemset, typename T>
- class VectorFiller;
+ struct VectorFiller;
template<typename T>
struct VectorFiller<false, T>
@@ -218,7 +225,7 @@ namespace WTF {
};
template<bool canCompareWithMemcmp, typename T>
- class VectorComparer;
+ struct VectorComparer;
template<typename T>
struct VectorComparer<false, T>
@@ -417,6 +424,27 @@ namespace WTF {
Base::deallocateBuffer(bufferToDeallocate);
}
+ void swap(VectorBuffer<T, inlineCapacity>& other)
+ {
+ if (buffer() == inlineBuffer() && other.buffer() == other.inlineBuffer()) {
+ WTF::swap(m_inlineBuffer, other.m_inlineBuffer);
+ std::swap(m_capacity, other.m_capacity);
+ } else if (buffer() == inlineBuffer()) {
+ m_buffer = other.m_buffer;
+ other.m_buffer = other.inlineBuffer();
+ WTF::swap(m_inlineBuffer, other.m_inlineBuffer);
+ std::swap(m_capacity, other.m_capacity);
+ } else if (other.buffer() == other.inlineBuffer()) {
+ other.m_buffer = m_buffer;
+ m_buffer = inlineBuffer();
+ WTF::swap(m_inlineBuffer, other.m_inlineBuffer);
+ std::swap(m_capacity, other.m_capacity);
+ } else {
+ std::swap(m_buffer, other.m_buffer);
+ std::swap(m_capacity, other.m_capacity);
+ }
+ }
+
void restoreInlineBufferIfNeeded()
{
if (m_buffer)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VectorTraits.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VectorTraits.h
index eb4c279..bf77878 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VectorTraits.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/VectorTraits.h
@@ -32,7 +32,7 @@ using std::pair;
namespace WTF {
template<bool isPod, typename T>
- class VectorTraitsBase;
+ struct VectorTraitsBase;
template<typename T>
struct VectorTraitsBase<false, T>
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/android/AndroidThreading.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/android/AndroidThreading.h
new file mode 100644
index 0000000..27f548c
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/android/AndroidThreading.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 AndroidThreading_h
+#define AndroidThreading_h
+
+namespace WTF {
+
+// An interface to the embedding layer, which provides threading support.
+class AndroidThreading {
+public:
+ static void scheduleDispatchFunctionsOnMainThread();
+};
+
+} // namespace WTF
+
+#endif // AndroidThreading_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/android/MainThreadAndroid.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/android/MainThreadAndroid.cpp
new file mode 100644
index 0000000..5e5f7b1
--- /dev/null
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/android/MainThreadAndroid.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MainThread.h"
+
+#include "AndroidThreading.h"
+
+namespace WTF {
+
+void initializeMainThreadPlatform()
+{
+}
+
+void scheduleDispatchFunctionsOnMainThread()
+{
+ AndroidThreading::scheduleDispatchFunctionsOnMainThread();
+}
+
+} // namespace WTF
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/dtoa.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/dtoa.cpp
index d75c17a..6289d04 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/dtoa.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/dtoa.cpp
@@ -140,7 +140,6 @@
#else
#define NO_ERRNO
#endif
-#include <float.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
@@ -148,6 +147,7 @@
#include <wtf/AlwaysInline.h>
#include <wtf/Assertions.h>
#include <wtf/FastMalloc.h>
+#include <wtf/MathExtras.h>
#include <wtf/Vector.h>
#include <wtf/Threading.h>
@@ -159,9 +159,9 @@
#pragma warning(disable: 4554)
#endif
-#if PLATFORM(BIG_ENDIAN)
+#if CPU(BIG_ENDIAN)
#define IEEE_MC68k
-#elif PLATFORM(MIDDLE_ENDIAN)
+#elif CPU(MIDDLE_ENDIAN)
#define IEEE_ARM
#else
#define IEEE_8087
@@ -262,7 +262,8 @@ typedef union { double d; uint32_t L[2]; } U;
#define Pack_32
#endif
-#if PLATFORM(PPC64) || PLATFORM(X86_64)
+#if CPU(PPC64) || CPU(X86_64)
+// FIXME: should we enable this on all 64-bit CPUs?
// 64-bit emulation provided by the compiler is likely to be slower than dtoa own code on 32-bit hardware.
#define USE_LONG_LONG
#endif
@@ -560,7 +561,7 @@ static void mult(BigInt& aRef, const BigInt& bRef)
aRef = c;
}
-struct P5Node {
+struct P5Node : Noncopyable {
BigInt val;
P5Node* next;
};
@@ -1869,7 +1870,7 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S)
* calculation.
*/
-void dtoa(char* result, double dd, int ndigits, int* decpt, int* sign, char** rve)
+void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char** rve)
{
/*
Arguments ndigits, decpt, sign are similar to those
@@ -1908,16 +1909,23 @@ void dtoa(char* result, double dd, int ndigits, int* decpt, int* sign, char** rv
{
/* Infinity or NaN */
*decpt = 9999;
- if (!word1(&u) && !(word0(&u) & 0xfffff))
+ if (!word1(&u) && !(word0(&u) & 0xfffff)) {
strcpy(result, "Infinity");
- else
+ if (rve)
+ *rve = result + 8;
+ } else {
strcpy(result, "NaN");
+ if (rve)
+ *rve = result + 3;
+ }
return;
}
if (!dval(&u)) {
*decpt = 1;
result[0] = '0';
result[1] = '\0';
+ if (rve)
+ *rve = result + 1;
return;
}
@@ -2376,4 +2384,83 @@ ret:
*rve = s;
}
+static ALWAYS_INLINE void append(char*& next, const char* src, unsigned size)
+{
+ for (unsigned i = 0; i < size; ++i)
+ *next++ = *src++;
+}
+
+void doubleToStringInJavaScriptFormat(double d, DtoaBuffer buffer, unsigned* resultLength)
+{
+ ASSERT(buffer);
+
+ // avoid ever printing -NaN, in JS conceptually there is only one NaN value
+ if (isnan(d)) {
+ append(buffer, "NaN", 3);
+ if (resultLength)
+ *resultLength = 3;
+ return;
+ }
+ // -0 -> "0"
+ if (!d) {
+ buffer[0] = '0';
+ if (resultLength)
+ *resultLength = 1;
+ return;
+ }
+
+ int decimalPoint;
+ int sign;
+
+ DtoaBuffer result;
+ char* resultEnd = 0;
+ WTF::dtoa(result, d, 0, &decimalPoint, &sign, &resultEnd);
+ int length = resultEnd - result;
+
+ char* next = buffer;
+ if (sign)
+ *next++ = '-';
+
+ if (decimalPoint <= 0 && decimalPoint > -6) {
+ *next++ = '0';
+ *next++ = '.';
+ for (int j = decimalPoint; j < 0; j++)
+ *next++ = '0';
+ append(next, result, length);
+ } else if (decimalPoint <= 21 && decimalPoint > 0) {
+ if (length <= decimalPoint) {
+ append(next, result, length);
+ for (int j = 0; j < decimalPoint - length; j++)
+ *next++ = '0';
+ } else {
+ append(next, result, decimalPoint);
+ *next++ = '.';
+ append(next, result + decimalPoint, length - decimalPoint);
+ }
+ } else if (result[0] < '0' || result[0] > '9')
+ append(next, result, length);
+ else {
+ *next++ = result[0];
+ if (length > 1) {
+ *next++ = '.';
+ append(next, result + 1, length - 1);
+ }
+
+ *next++ = 'e';
+ *next++ = (decimalPoint >= 0) ? '+' : '-';
+ // decimalPoint can't be more than 3 digits decimal given the
+ // nature of float representation
+ int exponential = decimalPoint - 1;
+ if (exponential < 0)
+ exponential = -exponential;
+ if (exponential >= 100)
+ *next++ = static_cast<char>('0' + exponential / 100);
+ if (exponential >= 10)
+ *next++ = static_cast<char>('0' + (exponential % 100) / 10);
+ *next++ = static_cast<char>('0' + exponential % 10);
+ }
+ if (resultLength)
+ *resultLength = next - buffer;
+}
+
} // namespace WTF
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/dtoa.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/dtoa.h
index cbec7c7..6127f53 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/dtoa.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/dtoa.h
@@ -30,8 +30,18 @@ namespace WTF {
extern WTF::Mutex* s_dtoaP5Mutex;
double strtod(const char* s00, char** se);
- void dtoa(char* result, double d, int ndigits, int* decpt, int* sign, char** rve);
+
+ typedef char DtoaBuffer[80];
+ void dtoa(DtoaBuffer result, double d, int ndigits, int* decpt, int* sign, char** rve);
+
+ // dtoa() for ECMA-262 'ToString Applied to the Number Type.'
+ // The *resultLength will have the length of the resultant string in bufer.
+ // The resultant string isn't terminated by 0.
+ void doubleToStringInJavaScriptFormat(double, DtoaBuffer, unsigned* resultLength);
} // namespace WTF
+using WTF::DtoaBuffer;
+using WTF::doubleToStringInJavaScriptFormat;
+
#endif // WTF_dtoa_h
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/qt/ThreadingQt.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/qt/ThreadingQt.cpp
index 5a84764..3e5aa59 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/qt/ThreadingQt.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/qt/ThreadingQt.cpp
@@ -29,6 +29,8 @@
#include "config.h"
#include "Threading.h"
+#if !ENABLE(SINGLE_THREADED)
+
#include "CurrentTime.h"
#include "HashMap.h"
#include "MainThread.h"
@@ -66,6 +68,21 @@ void ThreadPrivate::run()
m_returnValue = m_entryPoint(m_data);
}
+class ThreadMonitor : public QObject {
+ Q_OBJECT
+public:
+ static ThreadMonitor * instance()
+ {
+ static ThreadMonitor *instance = new ThreadMonitor();
+ return instance;
+ }
+
+public Q_SLOTS:
+ void threadFinished()
+ {
+ sender()->deleteLater();
+ }
+};
static Mutex* atomicallyInitializedStaticMutex;
@@ -157,6 +174,9 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data);
return 0;
}
+
+ QObject::connect(thread, SIGNAL(finished()), ThreadMonitor::instance(), SLOT(threadFinished()));
+
thread->start();
QThread* threadRef = static_cast<QThread*>(thread);
@@ -164,7 +184,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
return establishIdentifierForThread(threadRef);
}
-void setThreadNameInternal(const char*)
+void initializeCurrentThreadInternal(const char*)
{
}
@@ -183,8 +203,10 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
return !res;
}
-void detachThread(ThreadIdentifier)
+void detachThread(ThreadIdentifier threadID)
{
+ ASSERT(threadID);
+ clearThreadForIdentifier(threadID);
}
ThreadIdentifier currentThread()
@@ -269,3 +291,7 @@ void ThreadCondition::broadcast()
}
} // namespace WebCore
+
+#include "ThreadingQt.moc"
+
+#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/UTF8.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/UTF8.cpp
index 9e713fe..21d5856 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/UTF8.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/UTF8.cpp
@@ -23,6 +23,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "config.h"
#include "UTF8.h"
namespace WTF {
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/Unicode.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/Unicode.h
index 7016a03..d59439d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/Unicode.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/Unicode.h
@@ -26,11 +26,7 @@
#include <wtf/Assertions.h>
#if USE(QT4_UNICODE)
-#if COMPILER(WINSCW) || COMPILER(RVCT)
-#include "wtf/unicode/qt4/UnicodeQt4.h"
-#else
#include "qt4/UnicodeQt4.h"
-#endif
#elif USE(ICU_UNICODE)
#include <wtf/unicode/icu/UnicodeIcu.h>
#elif USE(GLIB_UNICODE)
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp
index a779b36..e20c376 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp
@@ -19,6 +19,7 @@
*
*/
+#include "config.h"
#include "UnicodeGLib.h"
namespace WTF {
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h
index c03d3ec..d72e707 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h
@@ -26,7 +26,7 @@
#define UnicodeGLib_h
#include "UnicodeMacrosFromICU.h"
-#include <wtf/GOwnPtr.h>
+#include <wtf/gtk/GOwnPtr.h>
#include <glib.h>
#include <pango/pango.h>
@@ -152,6 +152,11 @@ inline bool isArabicChar(UChar32 c)
return c >= 0x0600 && c <= 0x06FF;
}
+inline bool isAlphanumeric(UChar32 c)
+{
+ return g_unichar_isalnum(c);
+}
+
inline bool isFormatChar(UChar32 c)
{
return g_unichar_type(c) == G_UNICODE_FORMAT;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
index 6376bb3..a1753a4 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
@@ -36,7 +36,7 @@
#include <unicode/ucol.h>
#include <string.h>
-#if PLATFORM(DARWIN)
+#if OS(DARWIN)
#include "RetainPtr.h"
#include <CoreFoundation/CoreFoundation.h>
#endif
@@ -59,9 +59,9 @@ Collator::Collator(const char* locale)
std::auto_ptr<Collator> Collator::userDefault()
{
-#if PLATFORM(DARWIN) && PLATFORM(CF)
+#if OS(DARWIN) && PLATFORM(CF)
// Mac OS X doesn't set UNIX locale to match user-selected one, so ICU default doesn't work.
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE)
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !OS(IPHONE_OS)
RetainPtr<CFLocaleRef> currentLocale(AdoptCF, CFLocaleCopyCurrent());
CFStringRef collationOrder = (CFStringRef)CFLocaleGetValue(currentLocale.get(), kCFLocaleCollatorIdentifier);
#else
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
index 35c6fbf..a2a5c0a 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
@@ -164,6 +164,11 @@ inline bool isArabicChar(UChar32 c)
return ublock_getCode(c) == UBLOCK_ARABIC;
}
+inline bool isAlphanumeric(UChar32 c)
+{
+ return u_isalnum(c);
+}
+
inline bool isSeparatorSpace(UChar32 c)
{
return u_charType(c) == U_SPACE_SEPARATOR;
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
index e01f825..1c7a692f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
@@ -30,7 +30,6 @@
#include <stdint.h>
-#if QT_VERSION >= 0x040300
QT_BEGIN_NAMESPACE
namespace QUnicodeTables {
struct Properties {
@@ -55,7 +54,6 @@ namespace QUnicodeTables {
Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2);
}
QT_END_NAMESPACE
-#endif
// ugly hack to make UChar compatible with JSChar in API/JSStringRef.h
#if defined(Q_OS_WIN) || COMPILER(WINSCW)
@@ -188,8 +186,6 @@ enum CharCategory {
};
-#if QT_VERSION >= 0x040300
-
// FIXME: handle surrogates correctly in all methods
inline UChar32 toLower(UChar32 ch)
@@ -408,138 +404,6 @@ inline CharCategory category(UChar32 c)
return (CharCategory) U_MASK(QChar::category(c));
}
-#else
-
-inline UChar32 toLower(UChar32 ch)
-{
- if (ch > 0xffff)
- return ch;
- return QChar((unsigned short)ch).toLower().unicode();
-}
-
-inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
-{
- *error = false;
- if (resultLength < srcLength) {
- *error = true;
- return srcLength;
- }
- for (int i = 0; i < srcLength; ++i)
- result[i] = QChar(src[i]).toLower().unicode();
- return srcLength;
-}
-
-inline UChar32 toUpper(UChar32 ch)
-{
- if (ch > 0xffff)
- return ch;
- return QChar((unsigned short)ch).toUpper().unicode();
-}
-
-inline int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
-{
- *error = false;
- if (resultLength < srcLength) {
- *error = true;
- return srcLength;
- }
- for (int i = 0; i < srcLength; ++i)
- result[i] = QChar(src[i]).toUpper().unicode();
- return srcLength;
-}
-
-inline int toTitleCase(UChar32 c)
-{
- if (c > 0xffff)
- return c;
- return QChar((unsigned short)c).toUpper().unicode();
-}
-
-inline UChar32 foldCase(UChar32 c)
-{
- if (c > 0xffff)
- return c;
- return QChar((unsigned short)c).toLower().unicode();
-}
-
-inline int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
-{
- return toLower(result, resultLength, src, srcLength, error);
-}
-
-inline bool isPrintableChar(UChar32 c)
-{
- return (c & 0xffff0000) == 0 && QChar((unsigned short)c).isPrint();
-}
-
-inline bool isArabicChar(UChar32 c)
-{
- return c >= 0x0600 && c <= 0x06FF;
-}
-
-inline bool isSeparatorSpace(UChar32 c)
-{
- return (c & 0xffff0000) == 0 && QChar((unsigned short)c).category() == QChar::Separator_Space;
-}
-
-inline bool isPunct(UChar32 c)
-{
- return (c & 0xffff0000) == 0 && QChar((unsigned short)c).isPunct();
-}
-
-inline bool isLower(UChar32 c)
-{
- return (c & 0xffff0000) == 0 && QChar((unsigned short)c).category() == QChar::Letter_Lowercase;
-}
-
-inline UChar32 mirroredChar(UChar32 c)
-{
- if (c > 0xffff)
- return c;
- return QChar(c).mirroredChar().unicode();
-}
-
-inline uint8_t combiningClass(UChar32 c)
-{
- if (c > 0xffff)
- return 0;
- return QChar((unsigned short)c).combiningClass();
-}
-
-inline DecompositionType decompositionType(UChar32 c)
-{
- if (c > 0xffff)
- return DecompositionNone;
- return (DecompositionType)QChar(c).decompositionTag();
-}
-
-inline int umemcasecmp(const UChar* a, const UChar* b, int len)
-{
- for (int i = 0; i < len; ++i) {
- QChar c1 = QChar(a[i]).toLower();
- QChar c2 = QChar(b[i]).toLower();
- if (c1 != c2)
- return c1.unicode() - c2.unicode();
- }
- return 0;
-}
-
-inline Direction direction(UChar32 c)
-{
- if (c > 0xffff)
- return LeftToRight;
- return (Direction)QChar(c).direction();
-}
-
-inline CharCategory category(UChar32 c)
-{
- if (c > 0xffff)
- return NoCategory;
- return (CharCategory) U_MASK(QChar(c).category());
-}
-
-#endif
-
} }
#endif // WTF_UNICODE_QT4_H
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp
index 966f2a1..2df44f8 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/unicode/wince/UnicodeWince.cpp
@@ -19,6 +19,7 @@
* Boston, MA 02110-1301, USA.
*/
+#include "config.h"
#include "UnicodeWince.h"
#include <wchar.h>
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/wince/FastMallocWince.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/wince/FastMallocWince.h
index 93d9f75..37174f0 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/wince/FastMallocWince.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/wince/FastMallocWince.h
@@ -1,5 +1,4 @@
/*
- * This file is part of the KDE libraries
* Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved
*
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/wince/MemoryManager.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/wince/MemoryManager.cpp
index b65b368..81d4f80 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/wince/MemoryManager.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/wince/MemoryManager.cpp
@@ -139,25 +139,25 @@ void* fastZeroedMalloc(size_t n)
return p;
}
-void* tryFastMalloc(size_t n)
+TryMallocReturnValue tryFastMalloc(size_t n)
{
MemoryAllocationCanFail canFail;
return fastMalloc(n);
}
-void* tryFastZeroedMalloc(size_t n)
+TryMallocReturnValue tryFastZeroedMalloc(size_t n)
{
MemoryAllocationCanFail canFail;
return fastZeroedMalloc(n);
}
-void* tryFastCalloc(size_t n_elements, size_t element_size)
+TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size)
{
MemoryAllocationCanFail canFail;
return fastCalloc(n_elements, element_size);
}
-void* tryFastRealloc(void* p, size_t n)
+TryMallocReturnValue tryFastRealloc(void* p, size_t n)
{
MemoryAllocationCanFail canFail;
return fastRealloc(p, n);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexCompiler.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexCompiler.cpp
index c7b3c81..9cd3d12 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexCompiler.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexCompiler.cpp
@@ -708,7 +708,7 @@ const char* compileRegex(const UString& patternString, RegexPattern& pattern)
unsigned numSubpatterns = pattern.m_numSubpatterns;
constructor.reset();
-#ifndef NDEBUG
+#if !ASSERT_DISABLED
const char* error =
#endif
parse(constructor, patternString, numSubpatterns);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.cpp
index aafea3c..d088086 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexInterpreter.cpp
@@ -1490,7 +1490,7 @@ public:
closeBodyAlternative();
}
- void alterantiveBodyDisjunction()
+ void alternativeBodyDisjunction()
{
int newAlternativeIndex = m_bodyDisjunction->terms.size();
m_bodyDisjunction->terms[m_currentAlternativeIndex].alternative.next = newAlternativeIndex - m_currentAlternativeIndex;
@@ -1499,7 +1499,7 @@ public:
m_currentAlternativeIndex = newAlternativeIndex;
}
- void alterantiveDisjunction()
+ void alternativeDisjunction()
{
int newAlternativeIndex = m_bodyDisjunction->terms.size();
m_bodyDisjunction->terms[m_currentAlternativeIndex].alternative.next = newAlternativeIndex - m_currentAlternativeIndex;
@@ -1515,9 +1515,9 @@ public:
if (alt) {
if (disjunction == m_pattern.m_body)
- alterantiveBodyDisjunction();
+ alternativeBodyDisjunction();
else
- alterantiveDisjunction();
+ alternativeDisjunction();
}
PatternAlternative* alternative = disjunction->m_alternatives[alt];
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp
index d777424..fcb8d86 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp
@@ -44,7 +44,7 @@ namespace JSC { namespace Yarr {
class RegexGenerator : private MacroAssembler {
friend void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline);
-#if PLATFORM(ARM)
+#if CPU(ARM)
static const RegisterID input = ARMRegisters::r0;
static const RegisterID index = ARMRegisters::r1;
static const RegisterID length = ARMRegisters::r2;
@@ -54,7 +54,7 @@ class RegexGenerator : private MacroAssembler {
static const RegisterID regT1 = ARMRegisters::r6;
static const RegisterID returnRegister = ARMRegisters::r0;
-#elif PLATFORM(X86)
+#elif CPU(X86)
static const RegisterID input = X86Registers::eax;
static const RegisterID index = X86Registers::edx;
static const RegisterID length = X86Registers::ecx;
@@ -64,7 +64,7 @@ class RegexGenerator : private MacroAssembler {
static const RegisterID regT1 = X86Registers::esi;
static const RegisterID returnRegister = X86Registers::eax;
-#elif PLATFORM(X86_64)
+#elif CPU(X86_64)
static const RegisterID input = X86Registers::edi;
static const RegisterID index = X86Registers::esi;
static const RegisterID length = X86Registers::edx;
@@ -1264,7 +1264,7 @@ class RegexGenerator : private MacroAssembler {
// complex here in compilation, and in the common case we should end up coallescing the checks.
//
// FIXME: a nice improvement here may be to stop trying to match sooner, based on the least
- // of the minimum-alterantive-lengths. E.g. if I have two alternatives of length 200 and 150,
+ // of the minimum-alternative-lengths. E.g. if I have two alternatives of length 200 and 150,
// and a string of length 100, we'll end up looping index from 0 to 100, checking whether there
// is sufficient input to run either alternative (constantly failing). If there had been only
// one alternative, or if the shorter alternative had come first, we would have terminated
@@ -1288,11 +1288,11 @@ class RegexGenerator : private MacroAssembler {
void generateEnter()
{
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
push(X86Registers::ebp);
move(stackPointerRegister, X86Registers::ebp);
push(X86Registers::ebx);
-#elif PLATFORM(X86)
+#elif CPU(X86)
push(X86Registers::ebp);
move(stackPointerRegister, X86Registers::ebp);
// TODO: do we need spill registers to fill the output pointer if there are no sub captures?
@@ -1308,10 +1308,7 @@ class RegexGenerator : private MacroAssembler {
#else
loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output);
#endif
-#elif PLATFORM(ARM)
-#if PLATFORM(ARM_TRADITIONAL)
- push(ARMRegisters::lr);
-#endif
+#elif CPU(ARM)
push(ARMRegisters::r4);
push(ARMRegisters::r5);
push(ARMRegisters::r6);
@@ -1321,15 +1318,15 @@ class RegexGenerator : private MacroAssembler {
void generateReturn()
{
-#if PLATFORM(X86_64)
+#if CPU(X86_64)
pop(X86Registers::ebx);
pop(X86Registers::ebp);
-#elif PLATFORM(X86)
+#elif CPU(X86)
pop(X86Registers::esi);
pop(X86Registers::edi);
pop(X86Registers::ebx);
pop(X86Registers::ebp);
-#elif PLATFORM(ARM)
+#elif CPU(ARM)
pop(ARMRegisters::r6);
pop(ARMRegisters::r5);
pop(ARMRegisters::r4);
@@ -1400,14 +1397,6 @@ void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const
}
}
-int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize)
-{
- if (JSRegExp* fallback = jitObject.getFallback())
- return (jsRegExpExecute(fallback, input, length, start, output, outputArraySize) < 0) ? -1 : output[0];
-
- return jitObject.execute(input, start, length, output);
-}
-
}}
#endif
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.h b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.h
index 5b0df9d..5ead00f 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.h
@@ -37,7 +37,7 @@
#include <pcre.h>
struct JSRegExp; // temporary, remove when fallback is removed.
-#if PLATFORM(X86) && !COMPILER(MSVC)
+#if CPU(X86) && !COMPILER(MSVC)
#define YARR_CALL __attribute__ ((regparm (3)))
#else
#define YARR_CALL
@@ -73,7 +73,7 @@ public:
int execute(const UChar* input, unsigned start, unsigned length, int* output)
{
- return reinterpret_cast<RegexJITCode>(m_ref.m_code.executableAddress())(input, start, length, output);
+ return ((RegexJITCode)(m_ref.m_code.executableAddress()))(input, start, length, output);
}
private:
@@ -82,7 +82,14 @@ private:
};
void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase = false, bool multiline = false);
-int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize);
+
+inline int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize)
+{
+ if (JSRegExp* fallback = jitObject.getFallback())
+ return (jsRegExpExecute(fallback, input, length, start, output, outputArraySize) < 0) ? -1 : output[0];
+
+ return jitObject.execute(input, start, length, output);
+}
} } // namespace JSC::Yarr
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexPattern.h b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexPattern.h
index a451131..dd7512d 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexPattern.h
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexPattern.h
@@ -137,7 +137,7 @@ struct PatternTerm {
PatternTerm(unsigned spatternId)
: type(TypeBackReference)
- , invertOrCapture(invertOrCapture)
+ , invertOrCapture(false)
{
subpatternId = spatternId;
quantityType = QuantifierFixedCount;
diff --git a/src/3rdparty/javascriptcore/VERSION b/src/3rdparty/javascriptcore/VERSION
index d75862d..6351105 100644
--- a/src/3rdparty/javascriptcore/VERSION
+++ b/src/3rdparty/javascriptcore/VERSION
@@ -4,8 +4,8 @@ This is a snapshot of JavaScriptCore from
The commit imported was from the
- jsc-for-qtscript-4.6-staging-06102009 branch/tag
+ javascriptcore-snapshot-23022010 branch/tag
and has the sha1 checksum
- 32d226eb14d44f80e9ec96d4ca2c595181eeeca3
+ 8a21225144f7c1e10ffcb9aa7a545164d9495bf2
diff --git a/src/3rdparty/javascriptcore/WebKit.pri b/src/3rdparty/javascriptcore/WebKit.pri
index 16f89bf..0dd0799 100644
--- a/src/3rdparty/javascriptcore/WebKit.pri
+++ b/src/3rdparty/javascriptcore/WebKit.pri
@@ -1,5 +1,16 @@
# Include file to make it easy to include WebKit into Qt projects
+# Detect that we are building as a standalone package by the presence of
+# either the generated files directory or as part of the Qt package through
+# QTDIR_build
+CONFIG(QTDIR_build): CONFIG += standalone_package
+else:exists($$PWD/WebCore/generated): CONFIG += standalone_package
+
+CONFIG(standalone_package) {
+ OUTPUT_DIR=$$PWD
+}
+
+CONFIG += depend_includepath
isEmpty(OUTPUT_DIR) {
CONFIG(debug, debug|release) {
@@ -17,19 +28,28 @@ building-libs {
QT += webkit
} else {
QMAKE_LIBDIR = $$OUTPUT_DIR/lib $$QMAKE_LIBDIR
+ QTWEBKITLIBNAME = QtWebKit
mac:!static:contains(QT_CONFIG, qt_framework):!CONFIG(webkit_no_framework) {
- LIBS += -framework QtWebKit
+ LIBS += -framework $$QTWEBKITLIBNAME
QMAKE_FRAMEWORKPATH = $$OUTPUT_DIR/lib $$QMAKE_FRAMEWORKPATH
} else {
win32-*|wince* {
- LIBS += -lQtWebKit$${QT_MAJOR_VERSION}
+ CONFIG(debug, debug|release):build_pass: QTWEBKITLIBNAME = $${QTWEBKITLIBNAME}d
+ QTWEBKITLIBNAME = $${QTWEBKITLIBNAME}$${QT_MAJOR_VERSION}
+ win32-g++: LIBS += -l$$QTWEBKITLIBNAME
+ else: LIBS += $${QTWEBKITLIBNAME}.lib
} else {
LIBS += -lQtWebKit
+ symbian {
+ TARGET.EPOCSTACKSIZE = 0x14000 // 80 kB
+ TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 // Min 128kB, Max 32MB
+ }
}
}
}
DEPENDPATH += $$PWD/WebKit/qt/Api
}
+greaterThan(QT_MINOR_VERSION, 5):DEFINES += WTF_USE_ACCELERATED_COMPOSITING
!mac:!unix|symbian {
DEFINES += USE_SYSTEM_MALLOC
@@ -43,15 +63,13 @@ BASE_DIR = $$PWD
INCLUDEPATH += $$PWD/WebKit/qt/Api
CONFIG -= warn_on
-*-g++*:QMAKE_CXXFLAGS += -Wreturn-type -fno-strict-aliasing
-#QMAKE_CXXFLAGS += -Wall -Wno-undef -Wno-unused-parameter
+*-g++*:QMAKE_CXXFLAGS += -Wall -Wreturn-type -fno-strict-aliasing -Wcast-align -Wchar-subscripts -Wformat-security -Wreturn-type -Wno-unused-parameter -Wno-sign-compare -Wno-switch -Wno-switch-enum -Wundef -Wmissing-noreturn -Winit-self
# Enable GNU compiler extensions to the ARM compiler for all Qt ports using RVCT
symbian|*-armcc {
RVCT_COMMON_CFLAGS = --gnu --diag_suppress 68,111,177,368,830,1293
RVCT_COMMON_CXXFLAGS = $$RVCT_COMMON_CFLAGS --no_parse_templates
- DEFINES *= QT_NO_UITOOLS
-}
+}
*-armcc {
QMAKE_CFLAGS += $$RVCT_COMMON_CFLAGS
@@ -62,75 +80,11 @@ symbian {
QMAKE_CXXFLAGS.ARMCC += $$RVCT_COMMON_CXXFLAGS
}
+symbian|maemo5: DEFINES *= QT_NO_UITOOLS
+
contains(DEFINES, QT_NO_UITOOLS): CONFIG -= uitools
# Disable a few warnings on Windows. The warnings are also
# disabled in WebKitLibraries/win/tools/vsprops/common.vsprops
-win32-msvc*: QMAKE_CXXFLAGS += -wd4291 -wd4344 -wd4503 -wd4800 -wd4819 -wd4996
-
-#
-# For builds inside Qt we interpret the output rule and the input of each extra compiler manually
-# and add the resulting sources to the SOURCES variable, because the build inside Qt contains already
-# all the generated files. We do not need to generate any extra compiler rules in that case.
-#
-# In addition this function adds a new target called 'generated_files' that allows manually calling
-# all the extra compilers to generate all the necessary files for the build using 'make generated_files'
-#
-defineTest(addExtraCompiler) {
- CONFIG(QTDIR_build) {
- outputRule = $$eval($${1}.output)
- outVariable = $$eval($${1}.variable_out)
- !isEqual(outVariable,GENERATED_SOURCES):return(true)
-
- input = $$eval($${1}.input)
- input = $$eval($$input)
-
- for(file,input) {
- base = $$basename(file)
- base ~= s/\..+//
- newfile=$$replace(outputRule,\\$\\{QMAKE_FILE_BASE\\},$$base)
- SOURCES += $$newfile
- }
-
- export(SOURCES)
- } else {
- QMAKE_EXTRA_COMPILERS += $$1
- generated_files.depends += compiler_$${1}_make_all
- export(QMAKE_EXTRA_COMPILERS)
- export(generated_files.depends)
- }
- return(true)
-}
-
-defineTest(addExtraCompilerWithHeader) {
- addExtraCompiler($$1)
-
- eval(headerFile = $${2})
- isEmpty(headerFile) {
- eval($${1}_header.output = $$eval($${1}.output))
- eval($${1}_header.output ~= s/\.cpp/.h/)
- eval($${1}_header.output ~= s/\.c/.h/)
- } else {
- eval($${1}_header.output = $$headerFile)
- }
-
- eval($${1}_header.input = $$eval($${1}.input))
- eval($${1}_header.commands = @echo -n '')
- eval($${1}_header.depends = compiler_$${1}_make_all)
- eval($${1}_header.variable_out = GENERATED_FILES)
-
- export($${1}_header.output)
- export($${1}_header.input)
- export($${1}_header.commands)
- export($${1}_header.depends)
- export($${1}_header.variable_out)
-
- !CONFIG(QTDIR_build): QMAKE_EXTRA_COMPILERS += $${1}_header
-
- export(QMAKE_EXTRA_COMPILERS)
- export(generated_files.depends)
- export(SOURCES)
-
- return(true)
-}
+win32-msvc*: QMAKE_CXXFLAGS += -wd4291 -wd4344 -wd4396 -wd4503 -wd4800 -wd4819 -wd4996
diff --git a/src/corelib/arch/qatomic_arm.h b/src/corelib/arch/qatomic_arm.h
index 9d7e9c6..9df02a2 100644
--- a/src/corelib/arch/qatomic_arm.h
+++ b/src/corelib/arch/qatomic_arm.h
@@ -108,8 +108,8 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
// kernel places a restartable cmpxchg implementation at a fixed address
extern "C" typedef int (qt_atomic_eabi_cmpxchg_int_t)(int oldval, int newval, volatile int *ptr);
extern "C" typedef int (qt_atomic_eabi_cmpxchg_ptr_t)(void *oldval, void *newval, volatile void *ptr);
-#define qt_atomic_eabi_cmpxchg_int (*(qt_atomic_eabi_cmpxchg_int_t *)0xffff0fc0)
-#define qt_atomic_eabi_cmpxchg_ptr (*(qt_atomic_eabi_cmpxchg_ptr_t *)0xffff0fc0)
+#define qt_atomic_eabi_cmpxchg_int (*reinterpret_cast<qt_atomic_eabi_cmpxchg_int_t *>(0xffff0fc0))
+#define qt_atomic_eabi_cmpxchg_ptr (*reinterpret_cast<qt_atomic_eabi_cmpxchg_ptr_t *>(0xffff0fc0))
#else
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index 4034218..72b0128 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -399,9 +399,35 @@ QString QWindowsLocalCodec::convertToUnicodeCharByChar(const char *chars, int le
return s;
}
-QByteArray QWindowsLocalCodec::convertFromUnicode(const QChar *uc, int len, ConverterState *) const
+QByteArray QWindowsLocalCodec::convertFromUnicode(const QChar *ch, int uclen, ConverterState *) const
{
- return qt_winQString2MB(uc, len);
+ if (!ch)
+ return QByteArray();
+ if (uclen == 0)
+ return QByteArray("");
+ BOOL used_def;
+ QByteArray mb(4096, 0);
+ int len;
+ while (!(len=WideCharToMultiByte(CP_ACP, 0, (const wchar_t*)ch, uclen,
+ mb.data(), mb.size()-1, 0, &used_def)))
+ {
+ int r = GetLastError();
+ if (r == ERROR_INSUFFICIENT_BUFFER) {
+ mb.resize(1+WideCharToMultiByte(CP_ACP, 0,
+ (const wchar_t*)ch, uclen,
+ 0, 0, 0, &used_def));
+ // and try again...
+ } else {
+#ifndef QT_NO_DEBUG
+ // Fail.
+ qWarning("WideCharToMultiByte: Cannot convert multibyte text (error %d): %s (UTF-8)",
+ r, QString(ch, uclen).toLocal8Bit().data());
+#endif
+ break;
+ }
+ }
+ mb.resize(len);
+ return mb;
}
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 625098e..37591c5 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -41,7 +41,6 @@
#include "qplatformdefs.h"
#include "qfileinfo.h"
-#include "qfsfileengine_p.h"
#include "qglobal.h"
#include "qdir.h"
#include "qfileinfo_p.h"
@@ -75,50 +74,6 @@ void QFileInfoPrivate::initFileEngine(const QString &file)
data->fileName = file;
}
-bool QFileInfoPrivate::hasAccess(Access access) const
-{
- if (!(getFileFlags(QAbstractFileEngine::PermsMask
- | QAbstractFileEngine::LocalDiskFlag) & QAbstractFileEngine::LocalDiskFlag)) {
- switch (access) {
- case ReadAccess:
- return getFileFlags(QAbstractFileEngine::ReadUserPerm);
- case WriteAccess:
- return getFileFlags(QAbstractFileEngine::WriteUserPerm);
- case ExecuteAccess:
- return getFileFlags(QAbstractFileEngine::ExeUserPerm);
- default:
- return false;
- }
- }
-
- int mode = 0;
- switch (access) {
- case ReadAccess:
- mode = R_OK;
- break;
- case WriteAccess:
- mode = W_OK;
- break;
- case ExecuteAccess:
- mode = X_OK;
- break;
- };
-#ifdef Q_OS_UNIX
- return QT_ACCESS(QFile::encodeName(data->fileName).data(), mode) == 0;
-#endif
-#ifdef Q_OS_WIN
- if ((access == ReadAccess && !getFileFlags(QAbstractFileEngine::ReadUserPerm))
- || (access == WriteAccess && !getFileFlags(QAbstractFileEngine::WriteUserPerm))) {
- return false;
- }
- if (access == ExecuteAccess)
- return getFileFlags(QAbstractFileEngine::ExeUserPerm);
-
- return ::_waccess((wchar_t*)QFSFileEnginePrivate::longFileName(data->fileName).utf16(), mode) == 0;
-#endif
- return false;
-}
-
void QFileInfoPrivate::detach()
{
qAtomicDetach(data);
@@ -893,7 +848,7 @@ bool QFileInfo::isReadable() const
Q_D(const QFileInfo);
if (!d->data->fileEngine)
return false;
- return d->hasAccess(QFileInfoPrivate::ReadAccess);
+ return d->getFileFlags(QAbstractFileEngine::ReadUserPerm);
}
/*!
@@ -906,7 +861,7 @@ bool QFileInfo::isWritable() const
Q_D(const QFileInfo);
if (!d->data->fileEngine)
return false;
- return d->hasAccess(QFileInfoPrivate::WriteAccess);
+ return d->getFileFlags(QAbstractFileEngine::WriteUserPerm);
}
/*!
@@ -919,7 +874,7 @@ bool QFileInfo::isExecutable() const
Q_D(const QFileInfo);
if (!d->data->fileEngine)
return false;
- return d->hasAccess(QFileInfoPrivate::ExecuteAccess);
+ return d->getFileFlags(QAbstractFileEngine::ExeUserPerm);
}
/*!
diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h
index d97a0cf..306ffe1 100644
--- a/src/corelib/io/qfileinfo_p.h
+++ b/src/corelib/io/qfileinfo_p.h
@@ -68,13 +68,6 @@ public:
void initFileEngine(const QString &);
- enum Access {
- ReadAccess,
- WriteAccess,
- ExecuteAccess
- };
- bool hasAccess(Access access) const;
-
uint getFileFlags(QAbstractFileEngine::FileFlags) const;
QDateTime &getFileTime(QAbstractFileEngine::FileTime) const;
QString getFileName(QAbstractFileEngine::FileName) const;
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 070edb4..5e14804 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -1033,6 +1033,10 @@ bool QFSFileEngine::supportsExtension(Extension extension) const
to store temporary files).
*/
+/*! \fn QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFileEngine::FileFlags type) const
+ \internal
+*/
+
QT_END_NAMESPACE
#endif // QT_NO_FSFILEENGINE
diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h
index 0f63eb8..d07c3a0 100644
--- a/src/corelib/io/qfsfileengine_p.h
+++ b/src/corelib/io/qfsfileengine_p.h
@@ -156,9 +156,7 @@ protected:
void init();
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
- QAbstractFileEngine::FileFlags getPermissions() const;
-#endif
+ QAbstractFileEngine::FileFlags getPermissions(QAbstractFileEngine::FileFlags type) const;
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 1331f54..6df00d6 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -736,6 +736,46 @@ static bool _q_isMacHidden(const QString &path)
}
#endif
+QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFileEngine::FileFlags type) const
+{
+ QAbstractFileEngine::FileFlags ret = 0;
+
+ if (st.st_mode & S_IRUSR)
+ ret |= QAbstractFileEngine::ReadOwnerPerm;
+ if (st.st_mode & S_IWUSR)
+ ret |= QAbstractFileEngine::WriteOwnerPerm;
+ if (st.st_mode & S_IXUSR)
+ ret |= QAbstractFileEngine::ExeOwnerPerm;
+ if (st.st_mode & S_IRGRP)
+ ret |= QAbstractFileEngine::ReadGroupPerm;
+ if (st.st_mode & S_IWGRP)
+ ret |= QAbstractFileEngine::WriteGroupPerm;
+ if (st.st_mode & S_IXGRP)
+ ret |= QAbstractFileEngine::ExeGroupPerm;
+ if (st.st_mode & S_IROTH)
+ ret |= QAbstractFileEngine::ReadOtherPerm;
+ if (st.st_mode & S_IWOTH)
+ ret |= QAbstractFileEngine::WriteOtherPerm;
+ if (st.st_mode & S_IXOTH)
+ ret |= QAbstractFileEngine::ExeOtherPerm;
+
+ // calculate user permissions
+ if (type & QAbstractFileEngine::ReadUserPerm) {
+ if (QT_ACCESS(nativeFilePath.constData(), R_OK) == 0)
+ ret |= QAbstractFileEngine::ReadUserPerm;
+ }
+ if (type & QAbstractFileEngine::WriteUserPerm) {
+ if (QT_ACCESS(nativeFilePath.constData(), W_OK) == 0)
+ ret |= QAbstractFileEngine::WriteUserPerm;
+ }
+ if (type & QAbstractFileEngine::ExeUserPerm) {
+ if (QT_ACCESS(nativeFilePath.constData(), X_OK) == 0)
+ ret |= QAbstractFileEngine::ExeUserPerm;
+ }
+
+ return ret;
+}
+
/*!
\reimp
*/
@@ -755,32 +795,8 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const
if (!exists && !d->isSymlink())
return ret;
- if (exists && (type & PermsMask)) {
- if (d->st.st_mode & S_IRUSR)
- ret |= ReadOwnerPerm;
- if (d->st.st_mode & S_IWUSR)
- ret |= WriteOwnerPerm;
- if (d->st.st_mode & S_IXUSR)
- ret |= ExeOwnerPerm;
- if (d->st.st_mode & S_IRUSR)
- ret |= ReadUserPerm;
- if (d->st.st_mode & S_IWUSR)
- ret |= WriteUserPerm;
- if (d->st.st_mode & S_IXUSR)
- ret |= ExeUserPerm;
- if (d->st.st_mode & S_IRGRP)
- ret |= ReadGroupPerm;
- if (d->st.st_mode & S_IWGRP)
- ret |= WriteGroupPerm;
- if (d->st.st_mode & S_IXGRP)
- ret |= ExeGroupPerm;
- if (d->st.st_mode & S_IROTH)
- ret |= ReadOtherPerm;
- if (d->st.st_mode & S_IWOTH)
- ret |= WriteOtherPerm;
- if (d->st.st_mode & S_IXOTH)
- ret |= ExeOtherPerm;
- }
+ if (exists && (type & PermsMask))
+ ret |= d->getPermissions(type);
if (type & TypesMask) {
#if !defined(QWS) && defined(Q_OS_MAC)
bool foundAlias = false;
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index d8b1c03..8d34486 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -1405,10 +1405,7 @@ bool QFSFileEngine::link(const QString &newName)
#endif // Q_OS_WINCE
}
-/*!
- \internal
-*/
-QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const
+QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFileEngine::FileFlags type) const
{
QAbstractFileEngine::FileFlags ret = 0;
@@ -1429,7 +1426,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const
if(res == ERROR_SUCCESS) {
ACCESS_MASK access_mask;
TRUSTEE_W trustee;
- { //user
+ if (type & 0x0700) { // user
if(ptrGetEffectiveRightsFromAclW(pDacl, &currentUserTrusteeW, &access_mask) != ERROR_SUCCESS)
access_mask = (ACCESS_MASK)-1;
if(access_mask & ReadMask)
@@ -1439,7 +1436,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const
if(access_mask & ExecMask)
ret |= QAbstractFileEngine::ExeUserPerm;
}
- { //owner
+ if (type & 0x7000) { // owner
ptrBuildTrusteeWithSidW(&trustee, pOwner);
if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS)
access_mask = (ACCESS_MASK)-1;
@@ -1450,7 +1447,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const
if(access_mask & ExecMask)
ret |= QAbstractFileEngine::ExeOwnerPerm;
}
- { //group
+ if (type & 0x0070) { // group
ptrBuildTrusteeWithSidW(&trustee, pGroup);
if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS)
access_mask = (ACCESS_MASK)-1;
@@ -1461,7 +1458,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const
if(access_mask & ExecMask)
ret |= QAbstractFileEngine::ExeGroupPerm;
}
- { //other (world)
+ if (type & 0x0007) { // other (world)
if(ptrGetEffectiveRightsFromAclW(pDacl, &worldTrusteeW, &access_mask) != ERROR_SUCCESS)
access_mask = (ACCESS_MASK)-1; // ###
if(access_mask & ReadMask)
@@ -1476,29 +1473,35 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const
}
} else
#endif
- {
+ {
//### what to do with permissions if we don't use NTFS
// for now just add all permissions and what about exe missions ??
// also qt_ntfs_permission_lookup is now not set by default ... should it ?
- ret |= QAbstractFileEngine::ReadOtherPerm | QAbstractFileEngine::ReadGroupPerm
- | QAbstractFileEngine::ReadOwnerPerm | QAbstractFileEngine::ReadUserPerm
- | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::WriteOwnerPerm
- | QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm;
-
- if (doStat()) {
- if (ret & (QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm |
- QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm)) {
- if (fileAttrib & FILE_ATTRIBUTE_READONLY)
- ret &= ~(QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm |
- QAbstractFileEngine::WriteGroupPerm | QAbstractFileEngine::WriteOtherPerm);
- }
+ ret |= QAbstractFileEngine::ReadOwnerPerm | QAbstractFileEngine::ReadGroupPerm
+ | QAbstractFileEngine::ReadOtherPerm;
- QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath;
- QString ext = fname.right(4).toLower();
- if (ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") ||
- ext == QLatin1String(".pif") || ext == QLatin1String(".cmd") || (fileAttrib & FILE_ATTRIBUTE_DIRECTORY))
- ret |= QAbstractFileEngine::ExeOwnerPerm | QAbstractFileEngine::ExeGroupPerm |
- QAbstractFileEngine::ExeOtherPerm | QAbstractFileEngine::ExeUserPerm;
+ if (!(fileAttrib & FILE_ATTRIBUTE_READONLY)) {
+ ret |= QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteGroupPerm
+ | QAbstractFileEngine::WriteOtherPerm;
+ }
+
+ QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath;
+ QString ext = fname.right(4).toLower();
+ if ((fileAttrib & FILE_ATTRIBUTE_DIRECTORY) ||
+ ext == QLatin1String(".exe") || ext == QLatin1String(".com") || ext == QLatin1String(".bat") ||
+ ext == QLatin1String(".pif") || ext == QLatin1String(".cmd")) {
+ ret |= QAbstractFileEngine::ExeOwnerPerm | QAbstractFileEngine::ExeGroupPerm
+ | QAbstractFileEngine::ExeOtherPerm | QAbstractFileEngine::ExeUserPerm;
+ }
+
+ // calculate user permissions
+ if (type & QAbstractFileEngine::ReadUserPerm) {
+ if (::_waccess((wchar_t*)longFileName(fname).utf16(), R_OK) == 0)
+ ret |= QAbstractFileEngine::ReadUserPerm;
+ }
+ if (type & QAbstractFileEngine::WriteUserPerm) {
+ if (::_waccess((wchar_t*)longFileName(fname).utf16(), W_OK) == 0)
+ ret |= QAbstractFileEngine::WriteUserPerm;
}
}
return ret;
@@ -1555,13 +1558,10 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil
}
if (type & PermsMask) {
- ret |= d->getPermissions();
- // ### Workaround pascals ### above. Since we always set all properties to true
- // we need to disable read and exec access if the file does not exists
- if (d->doStat())
+ if (d->doStat()) {
ret |= ExistsFlag;
- else
- ret &= 0x2222;
+ ret |= d->getPermissions(type);
+ }
}
if (type & TypesMask) {
if (d->filePath.endsWith(QLatin1String(".lnk"))) {
diff --git a/src/corelib/tools/qbytedata_p.h b/src/corelib/tools/qbytedata_p.h
index 9aad6a9..c48bb33 100644
--- a/src/corelib/tools/qbytedata_p.h
+++ b/src/corelib/tools/qbytedata_p.h
@@ -206,6 +206,13 @@ public:
{
return buffers[i];
}
+
+ inline bool canReadLine() const {
+ for (int i = 0; i < buffers.length(); i++)
+ if (buffers.at(i).contains('\n'))
+ return true;
+ return false;
+ }
};
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index c6dd106..67f63f3 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -98,25 +98,6 @@ struct Q_CORE_EXPORT QListData {
inline void **end() const { return d->array + d->end; }
};
-//////////////////////////////////////////////////////////////////////////////////
-//
-// QtPodForSize and QtPodForType are internal and may change or go away any time.
-// We mean it.
-//
-//////////////////////////////////////////////////////////////////////////////////
-template <int N> struct QtPodForSize {
- // This base type is rather obviously broken and cannot be made
- // working due to alignment constraints.
- // This doesn't matter as far as QList is concerned, as we are
- // using this type only for QTypeInfo<T>::isLarge == false.
- typedef struct { } Type;
-};
-template <> struct QtPodForSize<1> { typedef quint8 Type; };
-template <> struct QtPodForSize<2> { typedef quint16 Type; };
-template <> struct QtPodForSize<4> { typedef quint32 Type; };
-template <> struct QtPodForSize<8> { typedef quint64 Type; };
-template <class T> struct QtPodForType : QtPodForSize<sizeof(T)> { };
-
template <typename T>
class QList
{
@@ -377,7 +358,15 @@ Q_INLINE_TEMPLATE void QList<T>::node_construct(Node *n, const T &t)
{
if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) n->v = new T(t);
else if (QTypeInfo<T>::isComplex) new (n) T(t);
+#if (defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__IBMCPP__)) && !defined(__OPTIMIZE__)
+ // This violates pointer aliasing rules, but it is known to be safe (and silent)
+ // in unoptimized GCC builds (-fno-strict-aliasing). The other compilers which
+ // set the same define are assumed to be safe.
else *reinterpret_cast<T*>(n) = t;
+#else
+ // This is always safe, but penaltizes unoptimized builds a lot.
+ else ::memcpy(n, &t, sizeof(T));
+#endif
}
template <typename T>
@@ -521,16 +510,15 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
QT_RETHROW;
}
} else {
- typedef typename QtPodForType<T>::Type PodNode;
- PodNode cpy = *reinterpret_cast<const PodNode *>(&t);
- Node *n = reinterpret_cast<Node *>(p.append());
+ Node *n, copy;
+ node_construct(&copy, t); // t might be a reference to an object in the array
QT_TRY {
- void *ptr = &cpy;
- node_construct(n, *reinterpret_cast<T *>(ptr));
+ n = reinterpret_cast<Node *>(p.append());;
} QT_CATCH(...) {
- --d->end;
+ node_destruct(&copy);
QT_RETHROW;
}
+ *n = copy;
}
}
}
@@ -556,16 +544,15 @@ inline void QList<T>::prepend(const T &t)
QT_RETHROW;
}
} else {
- typedef typename QtPodForType<T>::Type PodNode;
- PodNode cpy = *reinterpret_cast<const PodNode *>(&t);
- Node *n = reinterpret_cast<Node *>(p.prepend());
+ Node *n, copy;
+ node_construct(&copy, t); // t might be a reference to an object in the array
QT_TRY {
- void *ptr = &cpy;
- node_construct(n, *reinterpret_cast<T *>(ptr));
+ n = reinterpret_cast<Node *>(p.prepend());;
} QT_CATCH(...) {
- ++d->begin;
+ node_destruct(&copy);
QT_RETHROW;
}
+ *n = copy;
}
}
}
@@ -591,16 +578,15 @@ inline void QList<T>::insert(int i, const T &t)
QT_RETHROW;
}
} else {
- typedef typename QtPodForType<T>::Type PodNode;
- PodNode cpy = *reinterpret_cast<const PodNode *>(&t);
- Node *n = reinterpret_cast<Node *>(p.insert(i));
+ Node *n, copy;
+ node_construct(&copy, t); // t might be a reference to an object in the array
QT_TRY {
- void *ptr = &cpy;
- node_construct(n, *reinterpret_cast<T *>(ptr));
+ n = reinterpret_cast<Node *>(p.insert(i));;
} QT_CATCH(...) {
- p.remove(i);
+ node_destruct(&copy);
QT_RETHROW;
}
+ *n = copy;
}
}
}
@@ -636,12 +622,10 @@ inline void QList<T>::move(int from, int to)
template<typename T>
Q_OUTOFLINE_TEMPLATE QList<T> QList<T>::mid(int pos, int alength) const
{
- if (alength < 0)
+ if (alength < 0 || pos + alength > size())
alength = size() - pos;
if (pos == 0 && alength == size())
return *this;
- if (pos + alength > size())
- alength = size() - pos;
QList<T> cpy;
cpy.reserve(alength);
cpy.d->end = alength;
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 84bc154..1966a79 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -3147,7 +3147,7 @@ QString QLocale::toString(double i, char f, int prec) const
On Windows and Mac, this locale will use the decimal/grouping characters and date/time
formats specified in the system configuration panel.
- \sa QTextCodec::locale() c()
+ \sa c()
*/
QLocale QLocale::system()
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index b54315c..464e77b 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -3827,100 +3827,6 @@ const char *QString::latin1_helper() const
#endif
-QT_END_NAMESPACE
-
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
-#include "qt_windows.h"
-
-QT_BEGIN_NAMESPACE
-
-QByteArray qt_winQString2MB(const QString& s, int uclen)
-{
- if (uclen < 0)
- uclen = s.length();
- if (s.isNull())
- return QByteArray();
- if (uclen == 0)
- return QByteArray("");
- return qt_winQString2MB(s.constData(), uclen);
-}
-
-QByteArray qt_winQString2MB(const QChar *ch, int uclen)
-{
- if (!ch)
- return QByteArray();
- if (uclen == 0)
- return QByteArray("");
- BOOL used_def;
- QByteArray mb(4096, 0);
- int len;
- while (!(len=WideCharToMultiByte(CP_ACP, 0, (const wchar_t*)ch, uclen,
- mb.data(), mb.size()-1, 0, &used_def)))
- {
- int r = GetLastError();
- if (r == ERROR_INSUFFICIENT_BUFFER) {
- mb.resize(1+WideCharToMultiByte(CP_ACP, 0,
- (const wchar_t*)ch, uclen,
- 0, 0, 0, &used_def));
- // and try again...
- } else {
-#ifndef QT_NO_DEBUG
- // Fail.
- qWarning("WideCharToMultiByte: Cannot convert multibyte text (error %d): %s (UTF-8)",
- r, QString(ch, uclen).toLocal8Bit().data());
-#endif
- break;
- }
- }
- mb.resize(len);
- return mb;
-}
-
-QString qt_winMB2QString(const char *mb, int mblen)
-{
- if (!mb || !mblen)
- return QString();
- const int wclen_auto = 4096;
- wchar_t wc_auto[wclen_auto];
- int wclen = wclen_auto;
- wchar_t *wc = wc_auto;
- int len;
- while (!(len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
- mb, mblen, wc, wclen)))
- {
- int r = GetLastError();
- if (r == ERROR_INSUFFICIENT_BUFFER) {
- if (wc != wc_auto) {
- qWarning("MultiByteToWideChar: Size changed");
- break;
- } else {
- wclen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
- mb, mblen, 0, 0);
- wc = new wchar_t[wclen];
- // and try again...
- }
- } else {
- // Fail.
- qWarning("MultiByteToWideChar: Cannot convert multibyte text");
- break;
- }
- }
- if (len <= 0)
- return QString();
- if (wc[len-1] == 0) // len - 1: we don't want terminator
- --len;
- QString s((QChar*)wc, len);
- if (wc != wc_auto)
- delete [] wc;
- return s;
-}
-
-QT_END_NAMESPACE
-
-#endif // Q_OS_WIN32
-
-QT_BEGIN_NAMESPACE
-
/*!
Returns a QString initialized with the first \a size characters
of the 8-bit string \a str.
@@ -4815,6 +4721,12 @@ int QString::localeAwareCompare(const QString &other) const
return localeAwareCompare_helper(constData(), length(), other.constData(), other.length());
}
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+QT_END_NAMESPACE
+#include "qt_windows.h"
+QT_BEGIN_NAMESPACE
+#endif
+
/*!
\internal
\since 4.5
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index a59c0bd..ea12c2f 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -1096,12 +1096,6 @@ Q_DECLARE_TYPEINFO(QString, Q_MOVABLE_TYPE);
Q_DECLARE_SHARED(QString)
Q_DECLARE_OPERATORS_FOR_FLAGS(QString::SectionFlags)
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
-extern Q_CORE_EXPORT QByteArray qt_winQString2MB(const QString& s, int len=-1);
-extern Q_CORE_EXPORT QByteArray qt_winQString2MB(const QChar *ch, int len);
-extern Q_CORE_EXPORT QString qt_winMB2QString(const char* mb, int len=-1);
-#endif
-
class Q_CORE_EXPORT QStringRef {
const QString *m_string;
diff --git a/src/declarative/qml/qdeclarativeextensionplugin.cpp b/src/declarative/qml/qdeclarativeextensionplugin.cpp
index 7617977..5b7f1e8 100644
--- a/src/declarative/qml/qdeclarativeextensionplugin.cpp
+++ b/src/declarative/qml/qdeclarativeextensionplugin.cpp
@@ -80,6 +80,9 @@ QDeclarativeExtensionPlugin::QDeclarativeExtensionPlugin(QObject *parent)
{
}
+/*!
+ Destructor.
+ */
QDeclarativeExtensionPlugin::~QDeclarativeExtensionPlugin()
{
}
diff --git a/src/declarative/qml/qdeclarativesqldatabase.cpp b/src/declarative/qml/qdeclarativesqldatabase.cpp
index 855d623..2d5f096 100644
--- a/src/declarative/qml/qdeclarativesqldatabase.cpp
+++ b/src/declarative/qml/qdeclarativesqldatabase.cpp
@@ -217,9 +217,15 @@ static QScriptValue qmlsqldatabase_executeSql(QScriptContext *context, QScriptEn
if (context->argumentCount() > 1) {
QScriptValue values = context->argument(1);
if (values.isObject()) {
- for (QScriptValueIterator it(values); it.hasNext();) {
- it.next();
- query.bindValue(it.name(),it.value().toVariant());
+ if (values.isArray()) {
+ int size = values.property(QLatin1String("length")).toInt32();
+ for (int i = 0; i < size; ++i)
+ query.bindValue(i, values.property(i).toVariant());
+ } else {
+ for (QScriptValueIterator it(values); it.hasNext();) {
+ it.next();
+ query.bindValue(it.name(),it.value().toVariant());
+ }
}
} else {
query.bindValue(0,values.toVariant());
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 20449d7..81c548b 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -2131,10 +2131,10 @@ void QDeclarativePropertyAnimation::setProperties(const QString &prop)
}
/*!
- \qmlproperty string PropertyAnimation::property
\qmlproperty string PropertyAnimation::properties
- \qmlproperty Object PropertyAnimation::target
\qmlproperty list<Object> PropertyAnimation::targets
+ \qmlproperty string PropertyAnimation::property
+ \qmlproperty Object PropertyAnimation::target
These properties are used as a set to determine which properties should be animated.
The singular and plural forms are functionally identical, e.g.
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index e3f26d7..b968ca5 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -284,12 +284,11 @@ void ModelNode::setObjectValue(const QScriptValue& valuemap) {
}
void ModelNode::setListValue(const QScriptValue& valuelist) {
- QScriptValueIterator it(valuelist);
+ int size = valuelist.property(QString::fromLatin1("length")).toInt32();
values.clear();
- while (it.hasNext()) {
- it.next();
+ for (int i = 0; i < size; ++i) {
ModelNode *value = new ModelNode;
- QScriptValue v = it.value();
+ QScriptValue v = valuelist.property(i);
if (v.isArray()) {
value->isArray = true;
value->setListValue(v);
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
index 089e04a..ef2b223 100644
--- a/src/gui/dialogs/qfiledialog.cpp
+++ b/src/gui/dialogs/qfiledialog.cpp
@@ -228,7 +228,8 @@ Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook
\value ReadOnly Indicates that the model is readonly.
- \value HideNameFilterDetails Indicates if the is hidden or not.
+ \value HideNameFilterDetails Indicates if the file name filter details are
+ hidden or not.
\value DontUseSheet In previous versions of Qt, the static
functions would create a sheet by default if the static function
diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp
index 3120938..afeed8e 100644
--- a/src/gui/dialogs/qfiledialog_win.cpp
+++ b/src/gui/dialogs/qfiledialog_win.cpp
@@ -583,6 +583,63 @@ static QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args,
return result;
}
+QString qt_win_CID_get_existing_directory(const QFileDialogArgs &args)
+{
+ QString result;
+ QDialog modal_widget;
+ modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
+ modal_widget.setParent(args.parent, Qt::Window);
+ QApplicationPrivate::enterModal(&modal_widget);
+
+ IFileOpenDialog *pfd = 0;
+ HRESULT hr = CoCreateInstance(QT_CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
+ QT_IID_IFileOpenDialog, reinterpret_cast<void**>(&pfd));
+
+ if (SUCCEEDED(hr)) {
+ qt_win_set_IFileDialogOptions(pfd, args.selection,
+ args.directory, args.caption,
+ QStringList(), QFileDialog::ExistingFiles,
+ args.options);
+
+ // Set the FOS_PICKFOLDERS flag
+ DWORD newOptions;
+ hr = pfd->GetOptions(&newOptions);
+ newOptions |= FOS_PICKFOLDERS;
+ if (SUCCEEDED(hr) && SUCCEEDED((hr = pfd->SetOptions(newOptions)))) {
+ QWidget *parentWindow = args.parent;
+ if (parentWindow)
+ parentWindow = parentWindow->window();
+ else
+ parentWindow = QApplication::activeWindow();
+
+ // Show the file dialog.
+ hr = pfd->Show(parentWindow ? parentWindow->winId() : 0);
+ if (SUCCEEDED(hr)) {
+ // Retrieve the result
+ IShellItem *psi = 0;
+ hr = pfd->GetResult(&psi);
+ if (SUCCEEDED(hr)) {
+ // Retrieve the file name from shell item.
+ wchar_t *pszPath;
+ hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
+ if (SUCCEEDED(hr)) {
+ result = QString::fromWCharArray(pszPath);
+ CoTaskMemFree(pszPath);
+ }
+ psi->Release(); // Free the current item.
+ }
+ }
+ }
+ }
+ QApplicationPrivate::leaveModal(&modal_widget);
+
+ qt_win_eatMouseMove();
+
+ if (pfd)
+ pfd->Release();
+ return result;
+}
+
#endif
QStringList qt_win_get_open_file_names(const QFileDialogArgs &args,
@@ -701,6 +758,11 @@ static int __stdcall winGetExistDirCallbackProc(HWND hwnd,
QString qt_win_get_existing_directory(const QFileDialogArgs &args)
{
+#ifndef Q_WS_WINCE
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
+ return qt_win_CID_get_existing_directory(args);
+#endif
+
QString currentDir = QDir::currentPath();
QString result;
QWidget *parent = args.parent;
diff --git a/src/gui/dialogs/qfileinfogatherer.cpp b/src/gui/dialogs/qfileinfogatherer.cpp
index c75cdfd..3b08bf6 100644
--- a/src/gui/dialogs/qfileinfogatherer.cpp
+++ b/src/gui/dialogs/qfileinfogatherer.cpp
@@ -216,41 +216,10 @@ void QFileInfoGatherer::run()
}
}
-/*
- QFileInfo::permissions is different depending upon your platform.
-
- "normalize this" so they can mean the same to us.
-*/
-QFile::Permissions QFileInfoGatherer::translatePermissions(const QFileInfo &fileInfo) const {
- QFile::Permissions permissions = fileInfo.permissions();
-#ifdef Q_OS_WIN
- return permissions;
-#else
- QFile::Permissions p = permissions;
- p &= ~(QFile::ReadUser|QFile::WriteUser|QFile::ExeUser);
- if ( permissions & QFile::ReadOther
- || (fileInfo.ownerId() == userId && permissions & QFile::ReadOwner)
- || (fileInfo.groupId() == groupId && permissions & QFile::ReadGroup))
- p |= QFile::ReadUser;
-
- if ( permissions & QFile::WriteOther
- || (fileInfo.ownerId() == userId && permissions & QFile::WriteOwner)
- || (fileInfo.groupId() == groupId && permissions & QFile::WriteGroup))
- p |= QFile::WriteUser;
-
- if ( permissions & QFile::ExeOther
- || (fileInfo.ownerId() == userId && permissions & QFile::ExeOwner)
- || (fileInfo.groupId() == groupId && permissions & QFile::ExeGroup))
- p |= QFile::ExeUser;
- return p;
-#endif
-}
-
QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const
{
QExtendedInformation info(fileInfo);
info.icon = m_iconProvider->icon(fileInfo);
- info.setPermissions(translatePermissions(fileInfo));
info.displayType = m_iconProvider->type(fileInfo);
#ifndef QT_NO_FILESYSTEMWATCHER
// ### Not ready to listen all modifications
diff --git a/src/gui/dialogs/qfileinfogatherer_p.h b/src/gui/dialogs/qfileinfogatherer_p.h
index b8b58a2..eff6b3c 100644
--- a/src/gui/dialogs/qfileinfogatherer_p.h
+++ b/src/gui/dialogs/qfileinfogatherer_p.h
@@ -88,11 +88,7 @@ public:
return fe.caseSensitive();
}
QFile::Permissions permissions() const {
- return mPermissions;
- }
-
- void setPermissions (QFile::Permissions permissions) {
- mPermissions = permissions;
+ return mFileInfo.permissions();
}
Type type() const {
@@ -140,7 +136,6 @@ public:
private :
QFileInfo mFileInfo;
- QFile::Permissions mPermissions;
};
class QFileIconProvider;
@@ -181,7 +176,6 @@ protected:
private:
void fetch(const QFileInfo &info, QTime &base, bool &firstTime, QList<QPair<QString, QFileInfo> > &updatedFiles, const QString &path);
QString translateDriveName(const QFileInfo &drive) const;
- QFile::Permissions translatePermissions(const QFileInfo &fileInfo) const;
QMutex mutex;
QWaitCondition condition;
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index c7d0e48..28072fc 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -1759,14 +1759,19 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
// (actually two events; one for horizontal and one for vertical).
// As a results of this, and to make sure we dont't receive duplicate events,
// we try to detect when this happend by checking the 'compatibilityEvent'.
+ // Since delta is delivered as pixels rather than degrees, we need to
+ // convert from pixels to degrees in a sensible manner.
+ // It looks like 1/4 degrees per pixel behaves most native.
+ // (NB: Qt expects the unit for delta to be 8 per degree):
+ const int pixelsToDegrees = 2;
SInt32 mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_deltaX = mdelt;
+ wheel_deltaX = mdelt * pixelsToDegrees;
mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothVerticalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_deltaY = mdelt;
+ wheel_deltaY = mdelt * pixelsToDegrees;
GetEventParameter(event, kEventParamEventRef, typeEventRef, 0,
sizeof(compatibilityEvent), 0, &compatibilityEvent);
} else if (ekind == kEventMouseWheelMoved) {
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 20a7ff2..985f825 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -709,6 +709,10 @@ static int qt_x_errhandler(Display *dpy, XErrorEvent *err)
extensionName = "XInputExtension";
else if (err->request_code == X11->mitshm_major)
extensionName = "MIT-SHM";
+#ifndef QT_NO_XKB
+ else if(err->request_code == X11->xkb_major)
+ extensionName = "XKEYBOARD";
+#endif
char minor_str[256];
if (extensionName) {
@@ -1635,6 +1639,11 @@ void qt_init(QApplicationPrivate *priv, int,
X11->xinput_eventbase = 0;
X11->xinput_errorbase = 0;
+ X11->use_xkb = false;
+ X11->xkb_major = 0;
+ X11->xkb_eventbase = 0;
+ X11->xkb_errorbase = 0;
+
// MIT-SHM
X11->use_mitshm = false;
X11->use_mitshm_pixmaps = false;
@@ -2108,6 +2117,33 @@ void qt_init(QApplicationPrivate *priv, int,
}
#endif // QT_NO_XINPUT
+#ifndef QT_NO_XKB
+ int xkblibMajor = XkbMajorVersion;
+ int xkblibMinor = XkbMinorVersion;
+ X11->use_xkb = XkbQueryExtension(X11->display,
+ &X11->xkb_major,
+ &X11->xkb_eventbase,
+ &X11->xkb_errorbase,
+ &xkblibMajor,
+ &xkblibMinor);
+ if (X11->use_xkb) {
+ // If XKB is detected, set the GrabsUseXKBState option so input method
+ // compositions continue to work (ie. deadkeys)
+ unsigned int state = XkbPCF_GrabsUseXKBStateMask;
+ (void) XkbSetPerClientControls(X11->display, state, &state);
+
+ // select for group change events
+ XkbSelectEventDetails(X11->display,
+ XkbUseCoreKbd,
+ XkbStateNotify,
+ XkbAllStateComponentsMask,
+ XkbGroupStateMask);
+
+ // current group state is queried when creating the keymapper, no need to do it here
+ }
+#endif
+
+
#if !defined(QT_NO_FONTCONFIG)
int dpi = 0;
getXDefault("Xft", FC_DPI, &dpi);
@@ -2186,15 +2222,6 @@ void qt_init(QApplicationPrivate *priv, int,
// initialize key mapper
QKeyMapper::changeKeyboard();
-#ifndef QT_NO_XKB
- if (qt_keymapper_private()->useXKB) {
- // If XKB is detected, set the GrabsUseXKBState option so input method
- // compositions continue to work (ie. deadkeys)
- unsigned int state = XkbPCF_GrabsUseXKBStateMask;
- (void) XkbSetPerClientControls(X11->display, state, &state);
- }
-#endif // QT_NO_XKB
-
// Misc. initialization
#if 0 //disabled for now..
QSegfaultHandler::initialize(priv->argv, priv->argc);
@@ -3229,6 +3256,24 @@ int QApplication::x11ProcessEvent(XEvent* event)
QKeyMapper::changeKeyboard();
return 0;
}
+#ifndef QT_NO_XKB
+ else if (X11->use_xkb && event->type == X11->xkb_eventbase) {
+ XkbAnyEvent *xkbevent = (XkbAnyEvent *) event;
+ switch (xkbevent->xkb_type) {
+ case XkbStateNotify:
+ {
+ XkbStateNotifyEvent *xkbstateevent = (XkbStateNotifyEvent *) xkbevent;
+ if ((xkbstateevent->changed & XkbGroupStateMask) != 0) {
+ qt_keymapper_private()->xkb_currentGroup = xkbstateevent->group;
+ QKeyMapper::changeKeyboard();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+#endif
if (!widget) { // don't know this windows
QWidget* popup = QApplication::activePopupWidget();
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index f7cb21f..4f71681 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -480,7 +480,7 @@ static int qCocoaViewCount = 0;
return;
if (QApplicationPrivate::graphicsSystem() != 0) {
- if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore()) {
+ if (qwidgetprivate->maybeBackingStore()) {
// Drawing is handled on the window level
// See qcocoasharedwindowmethods_mac_p.h
if (!qwidget->testAttribute(Qt::WA_PaintOnScreen))
@@ -819,11 +819,12 @@ static int qCocoaViewCount = 0;
// The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad).
// Since deviceDelta is delivered as pixels rather than degrees, we need to
// convert from pixels to degrees in a sensible manner.
- // It looks like four degrees per pixel behaves most native.
- // Qt expects the unit for delta to be 1/8 of a degree:
- deltaX = [theEvent deviceDeltaX];
- deltaY = [theEvent deviceDeltaY];
- deltaZ = [theEvent deviceDeltaZ];
+ // It looks like 1/4 degrees per pixel behaves most native.
+ // (NB: Qt expects the unit for delta to be 8 per degree):
+ const int pixelsToDegrees = 2; // 8 * 1/4
+ deltaX = [theEvent deviceDeltaX] * pixelsToDegrees;
+ deltaY = [theEvent deviceDeltaY] * pixelsToDegrees;
+ deltaZ = [theEvent deviceDeltaZ] * pixelsToDegrees;
} else {
// carbonEventKind == kEventMouseWheelMoved
// Remove acceleration, and use either -120 or 120 as delta:
diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp
index c88a9a7..9dcca17 100644
--- a/src/gui/kernel/qgesturerecognizer.cpp
+++ b/src/gui/kernel/qgesturerecognizer.cpp
@@ -161,6 +161,8 @@ QGestureRecognizer::~QGestureRecognizer()
Reimplement this function to create a custom QGesture-derived gesture
object if necessary.
+
+ The application takes ownership of the created gesture object.
*/
QGesture *QGestureRecognizer::create(QObject *target)
{
diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp
index a31480d..f259654 100644
--- a/src/gui/kernel/qkeymapper_mac.cpp
+++ b/src/gui/kernel/qkeymapper_mac.cpp
@@ -323,6 +323,32 @@ static qt_mac_enum_mapper qt_mac_keyvkey_symbols[] = { //real scan codes
{ 0, QT_MAC_MAP_ENUM(0) }
};
+static qt_mac_enum_mapper qt_mac_private_unicode[] = {
+ { 0xF700, QT_MAC_MAP_ENUM(Qt::Key_Up) }, //NSUpArrowFunctionKey
+ { 0xF701, QT_MAC_MAP_ENUM(Qt::Key_Down) }, //NSDownArrowFunctionKey
+ { 0xF702, QT_MAC_MAP_ENUM(Qt::Key_Left) }, //NSLeftArrowFunctionKey
+ { 0xF703, QT_MAC_MAP_ENUM(Qt::Key_Right) }, //NSRightArrowFunctionKey
+ { 0xF727, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertFunctionKey
+ { 0xF728, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteFunctionKey
+ { 0xF729, QT_MAC_MAP_ENUM(Qt::Key_Home) }, //NSHomeFunctionKey
+ { 0xF72B, QT_MAC_MAP_ENUM(Qt::Key_End) }, //NSEndFunctionKey
+ { 0xF72C, QT_MAC_MAP_ENUM(Qt::Key_PageUp) }, //NSPageUpFunctionKey
+ { 0xF72D, QT_MAC_MAP_ENUM(Qt::Key_PageDown) }, //NSPageDownFunctionKey
+ { 0xF72F, QT_MAC_MAP_ENUM(Qt::Key_ScrollLock) }, //NSScrollLockFunctionKey
+ { 0xF730, QT_MAC_MAP_ENUM(Qt::Key_Pause) }, //NSPauseFunctionKey
+ { 0xF731, QT_MAC_MAP_ENUM(Qt::Key_SysReq) }, //NSSysReqFunctionKey
+ { 0xF735, QT_MAC_MAP_ENUM(Qt::Key_Menu) }, //NSMenuFunctionKey
+ { 0xF738, QT_MAC_MAP_ENUM(Qt::Key_Print) }, //NSPrintFunctionKey
+ { 0xF73A, QT_MAC_MAP_ENUM(Qt::Key_Clear) }, //NSClearDisplayFunctionKey
+ { 0xF73D, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertCharFunctionKey
+ { 0xF73E, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteCharFunctionKey
+ { 0xF741, QT_MAC_MAP_ENUM(Qt::Key_Select) }, //NSSelectFunctionKey
+ { 0xF742, QT_MAC_MAP_ENUM(Qt::Key_Execute) }, //NSExecuteFunctionKey
+ { 0xF746, QT_MAC_MAP_ENUM(Qt::Key_Help) }, //NSHelpFunctionKey
+ { 0xF747, QT_MAC_MAP_ENUM(Qt::Key_Mode_switch) }, //NSModeSwitchFunctionKey
+ { 0, QT_MAC_MAP_ENUM(0) }
+};
+
static int qt_mac_get_key(int modif, const QChar &key, int virtualKey)
{
#ifdef DEBUG_KEY_BINDINGS
@@ -379,6 +405,19 @@ static int qt_mac_get_key(int modif, const QChar &key, int virtualKey)
}
}
+ // check if they belong to key codes in private unicode range
+ if (key >= 0xf700 && key <= 0xf747) {
+ if (key >= 0xf704 && key <= 0xf726) {
+ return Qt::Key_F1 + (key.unicode() - 0xf704) ;
+ }
+ for (int i = 0; qt_mac_private_unicode[i].qt_code; i++) {
+ if (qt_mac_private_unicode[i].mac_code == key) {
+ return qt_mac_private_unicode[i].qt_code;
+ }
+ }
+
+ }
+
//oh well
#ifdef DEBUG_KEY_BINDINGS
qDebug("Unknown case.. %s:%d %d[%d] %d", __FILE__, __LINE__, key.unicode(), key.toLatin1(), virtualKey);
@@ -847,7 +886,11 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef e
}
void
-QKeyMapperPrivate::updateKeyMap(EventHandlerCallRef, EventRef event, void *)
+QKeyMapperPrivate::updateKeyMap(EventHandlerCallRef, EventRef event, void *
+#if defined(QT_MAC_USE_COCOA)
+ unicodeKey // unicode character from NSEvent (modifiers applied)
+#endif
+ )
{
UInt32 macVirtualKey = 0;
GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(macVirtualKey), 0, &macVirtualKey);
@@ -875,6 +918,15 @@ QKeyMapperPrivate::updateKeyMap(EventHandlerCallRef, EventRef event, void *)
qtkey = unicode.unicode();
keyLayout[macVirtualKey]->qtKey[i] = qtkey;
}
+#ifndef Q_WS_MAC32
+ else {
+ const QChar unicode(*((UniChar *)unicodeKey));
+ int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
+ if (qtkey == Qt::Key_unknown)
+ qtkey = unicode.unicode();
+ keyLayout[macVirtualKey]->qtKey[i] = qtkey;
+ }
+#endif
#ifdef Q_WS_MAC32
} else {
const UInt32 keyModifier = (qt_mac_get_mac_modifiers(ModsTbl[i]));
diff --git a/src/gui/kernel/qkeymapper_p.h b/src/gui/kernel/qkeymapper_p.h
index 3e42d6e..38f141e 100644
--- a/src/gui/kernel/qkeymapper_p.h
+++ b/src/gui/kernel/qkeymapper_p.h
@@ -183,7 +183,7 @@ public:
const XEvent *,
bool grab);
- bool useXKB;
+ int xkb_currentGroup;
QXCoreDesc coreDesc;
#elif defined(Q_WS_MAC)
diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp
index d6d1042..428ac3e 100644
--- a/src/gui/kernel/qkeymapper_x11.cpp
+++ b/src/gui/kernel/qkeymapper_x11.cpp
@@ -248,22 +248,17 @@ qt_XTranslateKey(register QXCoreDesc *dpy,
QKeyMapperPrivate::QKeyMapperPrivate()
- : keyboardInputDirection(Qt::LeftToRight), useXKB(false)
+ : keyboardInputDirection(Qt::LeftToRight), xkb_currentGroup(0)
{
memset(&coreDesc, 0, sizeof(coreDesc));
#ifndef QT_NO_XKB
- int opcode = -1;
- int xkbEventBase = -1;
- int xkbErrorBase = -1;
- int xkblibMajor = XkbMajorVersion;
- int xkblibMinor = XkbMinorVersion;
- if (XkbQueryExtension(X11->display, &opcode, &xkbEventBase, &xkbErrorBase, &xkblibMajor, &xkblibMinor))
- useXKB = true;
-#endif
-
-#if 0
- qDebug() << "useXKB =" << useXKB;
+ if (X11->use_xkb) {
+ // get the current group
+ XkbStateRec xkbState;
+ if (XkbGetState(X11->display, XkbUseCoreKbd, &xkbState) == Success)
+ xkb_currentGroup = xkbState.group;
+ }
#endif
}
@@ -276,7 +271,7 @@ QKeyMapperPrivate::~QKeyMapperPrivate()
QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *event)
{
#ifndef QT_NO_XKB
- if (useXKB)
+ if (X11->use_xkb)
return possibleKeysXKB(event);
#endif
return possibleKeysCore(event);
@@ -486,7 +481,7 @@ enum {
void QKeyMapperPrivate::clearMappings()
{
#ifndef QT_NO_XKB
- if (useXKB) {
+ if (X11->use_xkb) {
// try to determine the layout name and input direction by reading the _XKB_RULES_NAMES property off
// the root window
QByteArray layoutName;
@@ -515,8 +510,13 @@ void QKeyMapperPrivate::clearMappings()
p += qstrlen(p) + 1;
} while (p < end);
- layoutName = QByteArray::fromRawData(names[2], qstrlen(names[2]));
- variantName = QByteArray::fromRawData(names[3], qstrlen(names[3]));
+ // the layout names and variants are saved in the _XKB_RULES_NAMES property as a comma separated list
+ QList<QByteArray> layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(',');
+ if (uint(xkb_currentGroup) < uint(layoutNames.count()))
+ layoutName = layoutNames.at(xkb_currentGroup);
+ QList<QByteArray> variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(',');
+ if (uint(xkb_currentGroup) < uint(variantNames.count()))
+ variantName = variantNames.at(xkb_currentGroup);
}
// ### ???
@@ -574,7 +574,7 @@ void QKeyMapperPrivate::clearMappings()
// look at the modifier mapping, and get the correct masks for alt, meta, super, hyper, and mode_switch
#ifndef QT_NO_XKB
- if (useXKB) {
+ if (X11->use_xkb) {
XkbDescPtr xkbDesc = XkbGetMap(X11->display, XkbAllClientInfoMask, XkbUseCoreKbd);
for (int i = xkbDesc->min_key_code; i < xkbDesc->max_key_code; ++i) {
const uint mask = xkbDesc->map->modmap ? xkbDesc->map->modmap[i] : 0;
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 99bf971..7f92a2c 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -696,6 +696,7 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = {
{QKeySequence::Redo, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QApplicationPrivate::KB_Mac}, //different priority from above
{QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
{QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Mac },//different priority from above
+ {QKeySequence::Paste, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Insert, QApplicationPrivate::KB_X11},
{QKeySequence::SelectStartOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Home, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
{QKeySequence::SelectEndOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_End, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
{QKeySequence::SelectPreviousWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 3fbd978..24fe5f7 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -684,7 +684,9 @@ bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEve
EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef]));
Q_ASSERT(key_event);
if ([event type] == NSKeyDown) {
- qt_keymapper_private()->updateKeyMap(0, key_event, 0);
+ NSString *characters = [event characters];
+ unichar value = [characters characterAtIndex:0];
+ qt_keymapper_private()->updateKeyMap(0, key_event, (void *)&value);
}
// Redirect keys to alien widgets.
diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h
index 8af4df5..e1b2625 100644
--- a/src/gui/kernel/qt_x11_p.h
+++ b/src/gui/kernel/qt_x11_p.h
@@ -439,6 +439,12 @@ struct QX11Data
int xinput_eventbase;
int xinput_errorbase;
+ // for XKEYBOARD support
+ bool use_xkb;
+ int xkb_major;
+ int xkb_eventbase;
+ int xkb_errorbase;
+
QList<QWidget *> deferred_map;
struct ScrollInProgress {
long id;
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index a0e4050..b3a6aec 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -3294,7 +3294,7 @@ void QWidgetPrivate::update_sys(const QRect &r)
#ifndef QT_MAC_USE_COCOA
HIViewSetNeedsDisplay(qt_mac_nativeview_for(q), true);
#else
- [qt_mac_nativeview_for(q) setNeedsDisplay:YES];
+ qt_mac_set_needs_display(q, QRegion());
#endif
return;
}
@@ -3332,21 +3332,24 @@ void QWidgetPrivate::update_sys(const QRegion &rgn)
HIViewSetNeedsDisplay(qt_mac_nativeview_for(q), true); // do a complete repaint on overflow.
}
#else
- // Cocoa doesn't do regions, it seems more efficient to just update the bounding rect instead of a potential number of message passes for each rect.
- const QRect & boundingRect = rgn.boundingRect();
-
// Alien support: get the first native ancestor widget (will be q itself in the non-alien case),
// map the coordinates from q space to NSView space and invalidate the rect.
QWidget *nativeParent = q->internalWinId() ? q : q->nativeParentWidget();
if (nativeParent == 0)
- return;
- const QRect nativeBoundingRect = QRect(
- QPoint(q->mapTo(nativeParent, boundingRect.topLeft())),
- QSize(boundingRect.size()));
+ return;
+
+ QVector<QRect> rects = rgn.rects();
+ for (int i = 0; i < rects.count(); ++i) {
+ const QRect &rect = rects.at(i);
- [qt_mac_nativeview_for(nativeParent) setNeedsDisplayInRect:NSMakeRect(nativeBoundingRect.x(),
- nativeBoundingRect.y(), nativeBoundingRect.width(),
- nativeBoundingRect.height())];
+ const QRect nativeBoundingRect = QRect(
+ QPoint(q->mapTo(nativeParent, rect.topLeft())),
+ QSize(rect.size()));
+
+ [qt_mac_nativeview_for(nativeParent) setNeedsDisplayInRect:NSMakeRect(nativeBoundingRect.x(),
+ nativeBoundingRect.y(), nativeBoundingRect.width(),
+ nativeBoundingRect.height())];
+ }
#endif
}
@@ -4027,7 +4030,7 @@ static void qt_mac_update_widget_posisiton(QWidget *q, QRect oldRect, QRect newR
#else
Q_UNUSED(oldRect);
NSRect bounds = NSMakeRect(newRect.x(), newRect.y(),
- newRect.width(), newRect.height());
+ newRect.width(), newRect.height());
[qt_mac_nativeview_for(q) setFrame:bounds];
#endif
}
@@ -4830,7 +4833,7 @@ void QWidgetPrivate::finishCocoaMaskSetup()
[window setOpaque:(extra->imageMask == 0)];
[window invalidateShadow];
}
- [qt_mac_nativeview_for(q) setNeedsDisplay:YES];
+ qt_mac_set_needs_display(q, QRegion());
}
#endif
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 581b538..e5b3ac0 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -4734,7 +4734,7 @@ static void blend_untransformed_argb8565(int count, const QSpan *spans,
static void blend_untransformed_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_16)
+#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -5577,7 +5577,7 @@ static void blend_transformed_bilinear_argb8565(int count, const QSpan *spans, v
static void blend_transformed_bilinear_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_16)
+#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_RGB16)
@@ -6164,7 +6164,7 @@ static void blend_transformed_argb8565(int count, const QSpan *spans,
static void blend_transformed_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_16)
+#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
@@ -6577,7 +6577,7 @@ static void blend_transformed_tiled_argb8565(int count, const QSpan *spans,
static void blend_transformed_tiled_rgb565(int count, const QSpan *spans,
void *userData)
{
-#if defined(QT_QWS_DEPTH_16)
+#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16)
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
if (data->texture.format == QImage::Format_ARGB8565_Premultiplied)
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index f345cd1..6864fe1 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -848,9 +848,9 @@ void QTextControl::copy()
QApplication::clipboard()->setMimeData(data);
}
-void QTextControl::paste()
+void QTextControl::paste(QClipboard::Mode mode)
{
- const QMimeData *md = QApplication::clipboard()->mimeData();
+ const QMimeData *md = QApplication::clipboard()->mimeData(mode);
if (md)
insertFromMimeData(md);
}
@@ -1230,7 +1230,12 @@ void QTextControlPrivate::keyPressEvent(QKeyEvent *e)
q->cut();
}
else if (e == QKeySequence::Paste) {
- q->paste();
+ QClipboard::Mode mode = QClipboard::Clipboard;
+#ifdef Q_WS_X11
+ if (e->modifiers() == (Qt::CTRL | Qt::SHIFT) && e->key() == Qt::Key_Insert)
+ mode = QClipboard::Selection;
+#endif
+ q->paste(mode);
}
#endif
else if (e == QKeySequence::Delete) {
diff --git a/src/gui/text/qtextcontrol_p.h b/src/gui/text/qtextcontrol_p.h
index 40507f4..8399d50 100644
--- a/src/gui/text/qtextcontrol_p.h
+++ b/src/gui/text/qtextcontrol_p.h
@@ -62,6 +62,7 @@
#include <QtCore/qrect.h>
#include <QtGui/qabstracttextdocumentlayout.h>
#include <QtGui/qtextdocumentfragment.h>
+#include <QtGui/qclipboard.h>
#ifdef QT3_SUPPORT
#include <QtGui/qtextobject.h>
@@ -191,7 +192,7 @@ public Q_SLOTS:
#ifndef QT_NO_CLIPBOARD
void cut();
void copy();
- void paste();
+ void paste(QClipboard::Mode mode = QClipboard::Clipboard);
#endif
void undo();
diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp
index d30c996..6f099a9 100644
--- a/src/gui/text/qzip.cpp
+++ b/src/gui/text/qzip.cpp
@@ -280,6 +280,21 @@ static QFile::Permissions modeToPermissions(quint32 mode)
return ret;
}
+static QDateTime readMSDosDate(const uchar *src)
+{
+ uint dosDate = readUInt(src);
+ quint64 uDate;
+ uDate = (quint64)(dosDate >> 16);
+ uint tm_mday = (uDate & 0x1f);
+ uint tm_mon = ((uDate & 0x1E0) >> 5);
+ uint tm_year = (((uDate & 0x0FE00) >> 9) + 1980);
+ uint tm_hour = ((dosDate & 0xF800) >> 11);
+ uint tm_min = ((dosDate & 0x7E0) >> 5);
+ uint tm_sec = ((dosDate & 0x1f) << 1);
+
+ return QDateTime(QDate(tm_year, tm_mon, tm_mday), QTime(tm_hour, tm_min, tm_sec));
+}
+
struct LocalFileHeader
{
uchar signature[4]; // 0x04034b50
@@ -343,7 +358,7 @@ struct FileHeader
};
QZipReader::FileInfo::FileInfo()
- : isDir(false), isFile(true), isSymLink(false), crc32(0), size(0)
+ : isDir(false), isFile(false), isSymLink(false), crc32(0), size(0)
{
}
@@ -365,9 +380,15 @@ QZipReader::FileInfo& QZipReader::FileInfo::operator=(const FileInfo &other)
permissions = other.permissions;
crc32 = other.crc32;
size = other.size;
+ lastModified = other.lastModified;
return *this;
}
+bool QZipReader::FileInfo::isValid() const
+{
+ return isDir || isFile || isSymLink;
+}
+
class QZipPrivate
{
public:
@@ -403,6 +424,7 @@ void QZipPrivate::fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const
fileInfo.permissions = modeToPermissions(mode);
fileInfo.crc32 = readUInt(header.h.crc_32);
fileInfo.size = readUInt(header.h.uncompressed_size);
+ fileInfo.lastModified = readMSDosDate(header.h.last_mod_file);
}
class QZipReaderPrivate : public QZipPrivate
@@ -750,6 +772,14 @@ QZipReader::~QZipReader()
}
/*!
+ Returns device used for reading zip archive.
+*/
+QIODevice* QZipReader::device() const
+{
+ return d->device;
+}
+
+/*!
Returns true if the user can read the file; otherwise returns false.
*/
bool QZipReader::isReadable() const
@@ -796,6 +826,7 @@ int QZipReader::count() const
/*!
Returns a FileInfo of an entry in the zipfile.
The \a index is the index into the directoy listing of the zipfile.
+ Returns an invalid FileInfo if \a index is out of boundaries.
\sa fileInfoList()
*/
@@ -803,7 +834,8 @@ QZipReader::FileInfo QZipReader::entryInfoAt(int index) const
{
d->scanFiles();
QZipReader::FileInfo fi;
- d->fillFileInfo(index, fi);
+ if (index >= 0 && index < d->fileHeaders.count())
+ d->fillFileInfo(index, fi);
return fi;
}
@@ -1022,6 +1054,14 @@ QZipWriter::~QZipWriter()
}
/*!
+ Returns device used for writing zip archive.
+*/
+QIODevice* QZipWriter::device() const
+{
+ return d->device;
+}
+
+/*!
Returns true if the user can write to the archive; otherwise returns false.
*/
bool QZipWriter::isWritable() const
diff --git a/src/gui/text/qzipreader_p.h b/src/gui/text/qzipreader_p.h
index 9b73373..6466a7b 100644
--- a/src/gui/text/qzipreader_p.h
+++ b/src/gui/text/qzipreader_p.h
@@ -55,6 +55,7 @@
// We mean it.
//
+#include <QtCore/qdatetime.h>
#include <QtCore/qfile.h>
#include <QtCore/qstring.h>
@@ -70,6 +71,8 @@ public:
explicit QZipReader(QIODevice *device);
~QZipReader();
+ QIODevice* device() const;
+
bool isReadable() const;
bool exists() const;
@@ -79,6 +82,7 @@ public:
FileInfo(const FileInfo &other);
~FileInfo();
FileInfo &operator=(const FileInfo &other);
+ bool isValid() const;
QString filePath;
uint isDir : 1;
uint isFile : 1;
@@ -86,6 +90,7 @@ public:
QFile::Permissions permissions;
uint crc32;
qint64 size;
+ QDateTime lastModified;
void *d;
};
diff --git a/src/gui/text/qzipwriter_p.h b/src/gui/text/qzipwriter_p.h
index 9322f4a..a50c172 100644
--- a/src/gui/text/qzipwriter_p.h
+++ b/src/gui/text/qzipwriter_p.h
@@ -69,6 +69,8 @@ public:
explicit QZipWriter(QIODevice *device);
~QZipWriter();
+ QIODevice* device() const;
+
bool isWritable() const;
bool exists() const;
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp
index 2888490..522d472 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/gui/widgets/qabstractslider.cpp
@@ -712,7 +712,15 @@ bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::Keyb
offset_accumulated = 0;
offset_accumulated += stepsToScrollF;
+#ifndef Q_WS_MAC
+ // Dont't scroll more than one page in any case:
stepsToScroll = qBound(-pageStep, int(offset_accumulated), pageStep);
+#else
+ // Native UI-elements on Mac can scroll hundreds of lines at a time as
+ // a result of acceleration. So keep the same behaviour in Qt, and
+ // dont restrict stepsToScroll to certain maximum (pageStep):
+ stepsToScroll = int(offset_accumulated);
+#endif
offset_accumulated -= int(offset_accumulated);
if (stepsToScroll == 0)
return false;
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index 9ec0feb..8e715a9 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -136,9 +136,9 @@ void QLineControl::copy(QClipboard::Mode mode) const
\sa insert()
*/
-void QLineControl::paste()
+void QLineControl::paste(QClipboard::Mode clipboardMode)
{
- QString clip = QApplication::clipboard()->text(QClipboard::Clipboard);
+ QString clip = QApplication::clipboard()->text(clipboardMode);
if (!clip.isEmpty() || hasSelectedText()) {
separate(); //make it a separate undo/redo command
insert(clip);
@@ -1576,8 +1576,14 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
copy();
}
else if (event == QKeySequence::Paste) {
- if (!isReadOnly())
- paste();
+ if (!isReadOnly()) {
+ QClipboard::Mode mode = QClipboard::Clipboard;
+#ifdef Q_WS_X11
+ if (event->modifiers() == (Qt::CTRL | Qt::SHIFT) && event->key() == Qt::Key_Insert)
+ mode = QClipboard::Selection;
+#endif
+ paste(mode);
+ }
}
else if (event == QKeySequence::Cut) {
if (!isReadOnly()) {
diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h
index 3f1bc2c..dd82581 100644
--- a/src/gui/widgets/qlinecontrol_p.h
+++ b/src/gui/widgets/qlinecontrol_p.h
@@ -128,7 +128,7 @@ public:
#ifndef QT_NO_CLIPBOARD
void copy(QClipboard::Mode mode = QClipboard::Clipboard) const;
- void paste();
+ void paste(QClipboard::Mode mode = QClipboard::Clipboard);
#endif
int cursor() const;
diff --git a/src/imports/qimportbase.pri b/src/imports/qimportbase.pri
index 5433059..ea12356 100644
--- a/src/imports/qimportbase.pri
+++ b/src/imports/qimportbase.pri
@@ -22,7 +22,7 @@ QMAKE_EXTRA_COMPILERS += copy2build
TARGET = $$qtLibraryTarget($$TARGET)
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
-include(../../qt_targets.pri)
+include(../qt_targets.pri)
wince*:LIBS += $$QMAKE_LIBS_GUI
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 7bb1399..1940dd1 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -880,17 +880,18 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return new QDisabledNetworkReply(this, req, op);
}
+#ifdef QT_QNAM_DEFAULT_NETWORK_SESSION
if (!d->networkSession && (d->initializeSession || !d->networkConfiguration.isEmpty())) {
QNetworkConfigurationManager manager;
if (d->networkConfiguration.isEmpty())
d->createSession(manager.defaultConfiguration());
else
d->createSession(manager.configurationFromIdentifier(d->networkConfiguration));
+ }
+#endif
- d->initializeSession = false;
- } else if (d->networkSession) {
+ if (d->networkSession)
d->networkSession->setSessionProperty(QLatin1String("AutoCloseSessionTimeout"), -1);
- }
QNetworkRequest request = req;
if (!request.header(QNetworkRequest::ContentLengthHeader).isValid() &&
@@ -1207,6 +1208,10 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
{
Q_Q(QNetworkAccessManager);
+#ifdef QT_QNAM_DEFAULT_NETWORK_SESSION
+ initializeSession = false;
+#endif
+
if (networkSession)
delete networkSession;
@@ -1229,24 +1234,29 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
void QNetworkAccessManagerPrivate::_q_networkSessionClosed()
{
- networkConfiguration = networkSession->configuration().identifier();
+ if (networkSession) {
+ networkConfiguration = networkSession->configuration().identifier();
- delete networkSession;
- networkSession = 0;
+ networkSession->deleteLater();
+ networkSession = 0;
+ }
}
void QNetworkAccessManagerPrivate::_q_networkSessionNewConfigurationActivated()
{
Q_Q(QNetworkAccessManager);
- networkSession->accept();
+ if (networkSession) {
+ networkSession->accept();
- emit q->networkSessionOnline();
+ emit q->networkSessionOnline();
+ }
}
void QNetworkAccessManagerPrivate::_q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &, bool)
{
- networkSession->migrate();
+ if (networkSession)
+ networkSession->migrate();
}
QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index 0140268..4a2a840 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -77,7 +77,9 @@ public:
#endif
networkSession(0),
networkAccessEnabled(true),
+#ifdef QT_QNAM_DEFAULT_NETWORK_SESSION
initializeSession(true),
+#endif
cookieJarCreated(false)
{ }
~QNetworkAccessManagerPrivate();
@@ -124,7 +126,9 @@ public:
QNetworkSession *networkSession;
QString networkConfiguration;
bool networkAccessEnabled;
+#ifdef QT_QNAM_DEFAULT_NETWORK_SESSION
bool initializeSession;
+#endif
bool cookieJarCreated;
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index b201380..8505a41 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -67,6 +67,8 @@ inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate()
void QNetworkReplyImplPrivate::_q_startOperation()
{
+ Q_Q(QNetworkReplyImpl);
+
// ensure this function is only being called once
if (state == Working) {
qDebug("QNetworkReplyImpl::_q_startOperation was called more than once");
@@ -93,6 +95,9 @@ void QNetworkReplyImplPrivate::_q_startOperation()
QNetworkSession *session = manager->d_func()->networkSession;
if (session) {
+ QObject::connect(session, SIGNAL(error(QNetworkSession::SessionError)),
+ q, SLOT(_q_networkSessionFailed()));
+
if (!session->isOpen())
session->open();
} else {
@@ -247,6 +252,17 @@ void QNetworkReplyImplPrivate::_q_networkSessionOnline()
}
}
+void QNetworkReplyImplPrivate::_q_networkSessionFailed()
+{
+ // Abort waiting replies.
+ if (state == WaitingForSession) {
+ state = Working;
+ error(QNetworkReplyImpl::UnknownNetworkError,
+ QCoreApplication::translate("QNetworkReply", "Network session error."));
+ finished();
+ }
+}
+
void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const QNetworkRequest &req,
QIODevice *data)
{
@@ -707,6 +723,13 @@ void QNetworkReplyImpl::close()
d->finished();
}
+bool QNetworkReplyImpl::canReadLine () const
+{
+ Q_D(const QNetworkReplyImpl);
+ return QNetworkReply::canReadLine() || d->readBuffer.canReadLine();
+}
+
+
/*!
Returns the number of bytes available for reading with
QIODevice::read(). The number of bytes available may grow until
diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h
index b4fbd1e..6045ef4 100644
--- a/src/network/access/qnetworkreplyimpl_p.h
+++ b/src/network/access/qnetworkreplyimpl_p.h
@@ -77,10 +77,11 @@ public:
~QNetworkReplyImpl();
virtual void abort();
- // reimplemented from QNetworkReply
+ // reimplemented from QNetworkReply / QIODevice
virtual void close();
virtual qint64 bytesAvailable() const;
virtual void setReadBufferSize(qint64 size);
+ virtual bool canReadLine () const;
virtual qint64 readData(char *data, qint64 maxlen);
virtual bool event(QEvent *);
@@ -99,6 +100,7 @@ public:
Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData())
Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished())
Q_PRIVATE_SLOT(d_func(), void _q_networkSessionOnline())
+ Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed())
};
class QNetworkReplyImplPrivate: public QNetworkReplyPrivate
@@ -132,6 +134,7 @@ public:
void _q_bufferOutgoingData();
void _q_bufferOutgoingDataFinished();
void _q_networkSessionOnline();
+ void _q_networkSessionFailed();
void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request,
QIODevice *outgoingData);
diff --git a/src/network/bearer/qbearerengine_p.h b/src/network/bearer/qbearerengine_p.h
index 028c174..fd4bf87 100644
--- a/src/network/bearer/qbearerengine_p.h
+++ b/src/network/bearer/qbearerengine_p.h
@@ -73,7 +73,7 @@ class Q_NETWORK_EXPORT QBearerEngine : public QObject
{
Q_OBJECT
- friend class QNetworkConfigurationManager;
+ friend class QNetworkConfigurationManagerPrivate;
public:
QBearerEngine(QObject *parent = 0);
@@ -81,8 +81,6 @@ public:
virtual bool hasIdentifier(const QString &id) = 0;
- virtual void requestUpdate() = 0;
-
virtual QNetworkConfigurationManager::Capabilities capabilities() const = 0;
virtual QNetworkSessionPrivate *createSessionBackend() = 0;
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index b631cf1..e7595a4 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -212,114 +212,7 @@ QNetworkConfigurationManager::~QNetworkConfigurationManager()
*/
QNetworkConfiguration QNetworkConfigurationManager::defaultConfiguration() const
{
- QNetworkConfigurationManagerPrivate *conPriv = connManager();
-
- foreach (QBearerEngine *engine, conPriv->engines()) {
- QNetworkConfigurationPrivatePointer ptr = engine->defaultConfiguration();
-
- if (ptr) {
- QNetworkConfiguration config;
- config.d = ptr;
- return config;
- }
- }
-
- // Engines don't have a default configuration.
-
- // Return first active snap
- QNetworkConfigurationPrivatePointer defaultConfiguration;
-
- foreach (QBearerEngine *engine, conPriv->engines()) {
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
-
- QMutexLocker locker(&engine->mutex);
-
- for (it = engine->snapConfigurations.begin(), end = engine->snapConfigurations.end();
- it != end; ++it) {
- if ((it.value()->state & QNetworkConfiguration::Active) ==
- QNetworkConfiguration::Active) {
- QNetworkConfiguration config;
- config.d = it.value();
- return config;
- } else if (!defaultConfiguration) {
- if ((it.value()->state & QNetworkConfiguration::Discovered) ==
- QNetworkConfiguration::Discovered) {
- defaultConfiguration = it.value();
- }
- }
- }
- }
-
- // No Active SNAPs return first Discovered SNAP.
- if (defaultConfiguration) {
- QNetworkConfiguration config;
- config.d = defaultConfiguration;
- return config;
- }
-
- /*
- No Active or Discovered SNAPs, find the perferred access point.
- The following priority order is used:
-
- 1. Active Ethernet
- 2. Active WLAN
- 3. Active Other
- 4. Discovered Ethernet
- 5. Discovered WLAN
- 6. Discovered Other
- */
-
- defaultConfiguration.reset();
-
- foreach (QBearerEngine *engine, conPriv->engines()) {
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
-
- QMutexLocker locker(&engine->mutex);
-
- for (it = engine->accessPointConfigurations.begin(),
- end = engine->accessPointConfigurations.end(); it != end; ++it) {
-
- if ((it.value()->state & QNetworkConfiguration::Discovered) ==
- QNetworkConfiguration::Discovered) {
- if (!defaultConfiguration) {
- defaultConfiguration = it.value();
- } else {
- if (defaultConfiguration->state == it.value()->state) {
- if (defaultConfiguration->bearerName() == QLatin1String("Ethernet")) {
- // do nothing
- } else if (defaultConfiguration->bearerName() == QLatin1String("WLAN")) {
- // ethernet beats wlan
- if (it.value()->bearerName() == QLatin1String("Ethernet"))
- defaultConfiguration = it.value();
- } else {
- // ethernet and wlan beats other
- if (it.value()->bearerName() == QLatin1String("Ethernet") ||
- it.value()->bearerName() == QLatin1String("WLAN")) {
- defaultConfiguration = it.value();
- }
- }
- } else {
- // active beats discovered
- if ((defaultConfiguration->state & QNetworkConfiguration::Active) !=
- QNetworkConfiguration::Active) {
- defaultConfiguration = it.value();
- }
- }
- }
- }
- }
- }
-
- // No Active InternetAccessPoint return first Discovered InternetAccessPoint.
- if (defaultConfiguration) {
- QNetworkConfiguration config;
- config.d = defaultConfiguration;
- return config;
- }
-
- return QNetworkConfiguration();
+ return connManager()->defaultConfiguration();
}
/*!
@@ -349,37 +242,7 @@ QNetworkConfiguration QNetworkConfigurationManager::defaultConfiguration() const
*/
QList<QNetworkConfiguration> QNetworkConfigurationManager::allConfigurations(QNetworkConfiguration::StateFlags filter) const
{
- QList<QNetworkConfiguration> result;
- QNetworkConfigurationManagerPrivate* conPriv = connManager();
-
- foreach (QBearerEngine *engine, conPriv->engines()) {
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
- QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
-
- QMutexLocker locker(&engine->mutex);
-
- //find all InternetAccessPoints
- for (it = engine->accessPointConfigurations.begin(),
- end = engine->accessPointConfigurations.end(); it != end; ++it) {
- if ((it.value()->state & filter) == filter) {
- QNetworkConfiguration pt;
- pt.d = it.value();
- result << pt;
- }
- }
-
- //find all service networks
- for (it = engine->snapConfigurations.begin(),
- end = engine->snapConfigurations.end(); it != end; ++it) {
- if ((it.value()->state & filter) == filter) {
- QNetworkConfiguration pt;
- pt.d = it.value();
- result << pt;
- }
- }
- }
-
- return result;
+ return connManager()->allConfigurations(filter);
}
/*!
@@ -388,28 +251,9 @@ QList<QNetworkConfiguration> QNetworkConfigurationManager::allConfigurations(QNe
\sa QNetworkConfiguration::identifier()
*/
-QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(const QString& identifier) const
+QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(const QString &identifier) const
{
- QNetworkConfigurationManagerPrivate* conPriv = connManager();
-
- QNetworkConfiguration item;
-
- foreach (QBearerEngine *engine, conPriv->engines()) {
- QMutexLocker locker(&engine->mutex);
-
- if (engine->accessPointConfigurations.contains(identifier))
- item.d = engine->accessPointConfigurations.value(identifier);
- else if (engine->snapConfigurations.contains(identifier))
- item.d = engine->snapConfigurations.value(identifier);
- else if (engine->userChoiceConfigurations.contains(identifier))
- item.d = engine->userChoiceConfigurations.value(identifier);
- else
- continue;
-
- return item;
- }
-
- return item;
+ return connManager()->configurationFromIdentifier(identifier);
}
/*!
@@ -424,10 +268,7 @@ QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(
*/
bool QNetworkConfigurationManager::isOnline() const
{
- QNetworkConfigurationManagerPrivate* conPriv = connManager();
- Q_UNUSED(conPriv);
- QList<QNetworkConfiguration> activeConfigs = allConfigurations(QNetworkConfiguration::Active);
- return activeConfigs.count() > 0;
+ return connManager()->isOnline();
}
/*!
diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp
index 9740424..c665fa2 100644
--- a/src/network/bearer/qnetworkconfigmanager_p.cpp
+++ b/src/network/bearer/qnetworkconfigmanager_p.cpp
@@ -47,6 +47,7 @@
#include <QtCore/qdebug.h>
#include <QtCore/qtimer.h>
#include <QtCore/qstringlist.h>
+#include <QtCore/qthread.h>
#include <QtCore/private/qcoreapplication_p.h>
QT_BEGIN_NAMESPACE
@@ -57,11 +58,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate()
: capFlags(0), mutex(QMutex::Recursive), pollTimer(0), forcedPolling(0), firstUpdate(true)
{
- updateConfigurations();
+ qRegisterMetaType<QNetworkConfiguration>("QNetworkConfiguration");
moveToThread(QCoreApplicationPrivate::mainThread());
- foreach (QBearerEngine *engine, sessionEngines)
- engine->moveToThread(QCoreApplicationPrivate::mainThread());
+ updateConfigurations();
}
QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate()
@@ -71,6 +71,200 @@ QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate()
qDeleteAll(sessionEngines);
}
+QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration()
+{
+ QMutexLocker locker(&mutex);
+
+ foreach (QBearerEngine *engine, sessionEngines) {
+ QNetworkConfigurationPrivatePointer ptr = engine->defaultConfiguration();
+
+ if (ptr) {
+ QNetworkConfiguration config;
+ config.d = ptr;
+ return config;
+ }
+ }
+
+ // Engines don't have a default configuration.
+
+ // Return first active snap
+ QNetworkConfigurationPrivatePointer defaultConfiguration;
+
+ foreach (QBearerEngine *engine, sessionEngines) {
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
+
+ QMutexLocker locker(&engine->mutex);
+
+ for (it = engine->snapConfigurations.begin(), end = engine->snapConfigurations.end();
+ it != end; ++it) {
+ QNetworkConfigurationPrivatePointer ptr = it.value();
+
+ QMutexLocker configLocker(&ptr->mutex);
+
+ if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+ QNetworkConfiguration config;
+ config.d = ptr;
+ return config;
+ } else if (!defaultConfiguration) {
+ if ((ptr->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ defaultConfiguration = ptr;
+ }
+ }
+ }
+ }
+
+ // No Active SNAPs return first Discovered SNAP.
+ if (defaultConfiguration) {
+ QNetworkConfiguration config;
+ config.d = defaultConfiguration;
+ return config;
+ }
+
+ /*
+ No Active or Discovered SNAPs, find the perferred access point.
+ The following priority order is used:
+
+ 1. Active Ethernet
+ 2. Active WLAN
+ 3. Active Other
+ 4. Discovered Ethernet
+ 5. Discovered WLAN
+ 6. Discovered Other
+ */
+
+ defaultConfiguration.reset();
+
+ foreach (QBearerEngine *engine, sessionEngines) {
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
+
+ QMutexLocker locker(&engine->mutex);
+
+ for (it = engine->accessPointConfigurations.begin(),
+ end = engine->accessPointConfigurations.end(); it != end; ++it) {
+ QNetworkConfigurationPrivatePointer ptr = it.value();
+
+ const QString bearerName = ptr->bearerName();
+ QMutexLocker configLocker(&ptr->mutex);
+
+ if ((ptr->state & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
+ if (!defaultConfiguration) {
+ defaultConfiguration = ptr;
+ } else {
+ if (defaultConfiguration->state == ptr->state) {
+ if (defaultConfiguration->bearerName() == QLatin1String("Ethernet")) {
+ // do nothing
+ } else if (defaultConfiguration->bearerName() == QLatin1String("WLAN")) {
+ // ethernet beats wlan
+ if (bearerName == QLatin1String("Ethernet"))
+ defaultConfiguration = ptr;
+ } else {
+ // ethernet and wlan beats other
+ if (bearerName == QLatin1String("Ethernet") ||
+ bearerName == QLatin1String("WLAN")) {
+ defaultConfiguration = ptr;
+ }
+ }
+ } else {
+ // active beats discovered
+ if ((defaultConfiguration->state & QNetworkConfiguration::Active) !=
+ QNetworkConfiguration::Active) {
+ defaultConfiguration = ptr;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // No Active InternetAccessPoint return first Discovered InternetAccessPoint.
+ if (defaultConfiguration) {
+ QNetworkConfiguration config;
+ config.d = defaultConfiguration;
+ return config;
+ }
+
+ return QNetworkConfiguration();
+}
+
+QList<QNetworkConfiguration> QNetworkConfigurationManagerPrivate::allConfigurations(QNetworkConfiguration::StateFlags filter)
+{
+ QList<QNetworkConfiguration> result;
+
+ QMutexLocker locker(&mutex);
+
+ foreach (QBearerEngine *engine, sessionEngines) {
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator it;
+ QHash<QString, QNetworkConfigurationPrivatePointer>::Iterator end;
+
+ QMutexLocker locker(&engine->mutex);
+
+ //find all InternetAccessPoints
+ for (it = engine->accessPointConfigurations.begin(),
+ end = engine->accessPointConfigurations.end(); it != end; ++it) {
+ QNetworkConfigurationPrivatePointer ptr = it.value();
+
+ QMutexLocker configLocker(&ptr->mutex);
+
+ if ((ptr->state & filter) == filter) {
+ QNetworkConfiguration pt;
+ pt.d = ptr;
+ result << pt;
+ }
+ }
+
+ //find all service networks
+ for (it = engine->snapConfigurations.begin(),
+ end = engine->snapConfigurations.end(); it != end; ++it) {
+ QNetworkConfigurationPrivatePointer ptr = it.value();
+
+ QMutexLocker configLocker(&ptr->mutex);
+
+ if ((ptr->state & filter) == filter) {
+ QNetworkConfiguration pt;
+ pt.d = ptr;
+ result << pt;
+ }
+ }
+ }
+
+ return result;
+}
+
+QNetworkConfiguration QNetworkConfigurationManagerPrivate::configurationFromIdentifier(const QString &identifier)
+{
+ QNetworkConfiguration item;
+
+ QMutexLocker locker(&mutex);
+
+ foreach (QBearerEngine *engine, sessionEngines) {
+ QMutexLocker locker(&engine->mutex);
+
+ if (engine->accessPointConfigurations.contains(identifier))
+ item.d = engine->accessPointConfigurations.value(identifier);
+ else if (engine->snapConfigurations.contains(identifier))
+ item.d = engine->snapConfigurations.value(identifier);
+ else if (engine->userChoiceConfigurations.contains(identifier))
+ item.d = engine->userChoiceConfigurations.value(identifier);
+ else
+ continue;
+
+ return item;
+ }
+
+ return item;
+}
+
+bool QNetworkConfigurationManagerPrivate::isOnline()
+{
+ QMutexLocker locker(&mutex);
+
+ return !onlineConfigurations.isEmpty();
+}
+
void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurationPrivatePointer ptr)
{
QMutexLocker locker(&mutex);
@@ -81,10 +275,14 @@ void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurati
emit configurationAdded(item);
}
+ ptr->mutex.lock();
if (ptr->state == QNetworkConfiguration::Active) {
+ ptr->mutex.unlock();
onlineConfigurations.insert(ptr->id);
if (!firstUpdate && onlineConfigurations.count() == 1)
emit onlineStateChanged(true);
+ } else {
+ ptr->mutex.unlock();
}
}
@@ -92,7 +290,9 @@ void QNetworkConfigurationManagerPrivate::configurationRemoved(QNetworkConfigura
{
QMutexLocker locker(&mutex);
+ ptr->mutex.lock();
ptr->isValid = false;
+ ptr->mutex.unlock();
if (!firstUpdate) {
QNetworkConfiguration item;
@@ -117,10 +317,12 @@ void QNetworkConfigurationManagerPrivate::configurationChanged(QNetworkConfigura
bool previous = !onlineConfigurations.isEmpty();
+ ptr->mutex.lock();
if (ptr->state == QNetworkConfiguration::Active)
onlineConfigurations.insert(ptr->id);
else
onlineConfigurations.remove(ptr->id);
+ ptr->mutex.unlock();
bool online = !onlineConfigurations.isEmpty();
@@ -154,6 +356,8 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations()
else
sessionEngines.append(engine);
+ engine->moveToThread(QCoreApplicationPrivate::mainThread());
+
connect(engine, SIGNAL(updateCompleted()),
this, SLOT(updateConfigurations()));
connect(engine, SIGNAL(configurationAdded(QNetworkConfigurationPrivatePointer)),
@@ -165,7 +369,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations()
capFlags |= engine->capabilities();
- engine->requestUpdate();
+ QMetaObject::invokeMethod(engine, "requestUpdate");
}
}
@@ -211,7 +415,7 @@ void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate()
for (int i = 0; i < sessionEngines.count(); ++i) {
updatingEngines.insert(i);
- sessionEngines.at(i)->requestUpdate();
+ QMetaObject::invokeMethod(sessionEngines.at(i), "requestUpdate");
}
}
@@ -266,7 +470,7 @@ void QNetworkConfigurationManagerPrivate::pollEngines()
if ((forcedPolling && sessionEngines.at(i)->requiresPolling()) ||
sessionEngines.at(i)->configurationsInUse()) {
pollingEngines.insert(i);
- sessionEngines.at(i)->requestUpdate();
+ QMetaObject::invokeMethod(sessionEngines.at(i), "requestUpdate");
}
}
}
@@ -278,7 +482,7 @@ void QNetworkConfigurationManagerPrivate::enablePolling()
++forcedPolling;
if (forcedPolling == 1)
- startPolling();
+ QMetaObject::invokeMethod(this, "startPolling");
}
void QNetworkConfigurationManagerPrivate::disablePolling()
diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h
index ac8518c..8ec8152 100644
--- a/src/network/bearer/qnetworkconfigmanager_p.h
+++ b/src/network/bearer/qnetworkconfigmanager_p.h
@@ -66,11 +66,16 @@ class QTimer;
class Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate : public QObject
{
Q_OBJECT
+
public:
QNetworkConfigurationManagerPrivate();
virtual ~QNetworkConfigurationManagerPrivate();
QNetworkConfiguration defaultConfiguration();
+ QList<QNetworkConfiguration> allConfigurations(QNetworkConfiguration::StateFlags filter);
+ QNetworkConfiguration configurationFromIdentifier(const QString &identifier);
+
+ bool isOnline();
QNetworkConfigurationManager::Capabilities capFlags;
@@ -78,7 +83,7 @@ public:
QList<QBearerEngine *> engines();
- void startPolling();
+ Q_INVOKABLE void startPolling();
void enablePolling();
void disablePolling();
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
index c4ba406..82669e0 100644
--- a/src/network/bearer/qnetworkconfiguration.cpp
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -246,7 +246,11 @@ bool QNetworkConfiguration::operator==(const QNetworkConfiguration& other) const
*/
QString QNetworkConfiguration::name() const
{
- return d ? d->name : QString();
+ if (!d)
+ return QString();
+
+ QMutexLocker locker(&d->mutex);
+ return d->name;
}
/*!
@@ -255,7 +259,11 @@ QString QNetworkConfiguration::name() const
*/
QString QNetworkConfiguration::identifier() const
{
- return d ? d->id : QString();
+ if (!d)
+ return QString();
+
+ QMutexLocker locker(&d->mutex);
+ return d->id;
}
/*!
@@ -268,7 +276,11 @@ QString QNetworkConfiguration::identifier() const
*/
QNetworkConfiguration::Type QNetworkConfiguration::type() const
{
- return d ? d->type : QNetworkConfiguration::Invalid;
+ if (!d)
+ return QNetworkConfiguration::Invalid;
+
+ QMutexLocker locker(&d->mutex);
+ return d->type;
}
/*!
@@ -283,7 +295,11 @@ QNetworkConfiguration::Type QNetworkConfiguration::type() const
*/
bool QNetworkConfiguration::isValid() const
{
- return d ? d->isValid : false;
+ if (!d)
+ return false;
+
+ QMutexLocker locker(&d->mutex);
+ return d->isValid;
}
/*!
@@ -291,7 +307,11 @@ bool QNetworkConfiguration::isValid() const
*/
QNetworkConfiguration::StateFlags QNetworkConfiguration::state() const
{
- return d ? d->state : QNetworkConfiguration::Undefined;
+ if (!d)
+ return QNetworkConfiguration::Undefined;
+
+ QMutexLocker locker(&d->mutex);
+ return d->state;
}
/*!
@@ -303,7 +323,11 @@ QNetworkConfiguration::StateFlags QNetworkConfiguration::state() const
*/
QNetworkConfiguration::Purpose QNetworkConfiguration::purpose() const
{
- return d ? d->purpose : QNetworkConfiguration::UnknownPurpose;
+ if (!d)
+ return QNetworkConfiguration::UnknownPurpose;
+
+ QMutexLocker locker(&d->mutex);
+ return d->purpose;
}
/*!
@@ -311,7 +335,11 @@ QNetworkConfiguration::Purpose QNetworkConfiguration::purpose() const
*/
bool QNetworkConfiguration::isRoamingAvailable() const
{
- return d ? d->roamingSupported : false;
+ if (!d)
+ return false;
+
+ QMutexLocker locker(&d->mutex);
+ return d->roamingSupported;
}
/*!
@@ -322,15 +350,25 @@ bool QNetworkConfiguration::isRoamingAvailable() const
QList<QNetworkConfiguration> QNetworkConfiguration::children() const
{
QList<QNetworkConfiguration> results;
- if (type() != QNetworkConfiguration::ServiceNetwork || !isValid() )
+
+ if (type() != QNetworkConfiguration::ServiceNetwork || !isValid())
return results;
+ QMutexLocker locker(&d->mutex);
+
QMutableListIterator<QNetworkConfigurationPrivatePointer> iter(d->serviceNetworkMembers);
- while(iter.hasNext()) {
+ while (iter.hasNext()) {
QNetworkConfigurationPrivatePointer p = iter.next();
+
//if we have an invalid member get rid of it -> was deleted earlier on
- if (!p->isValid)
- iter.remove();
+ {
+ QMutexLocker childLocker(&p->mutex);
+
+ if (!p->isValid) {
+ iter.remove();
+ continue;
+ }
+ }
QNetworkConfiguration item;
item.d = p;
diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h
index 6b40946..6908277 100644
--- a/src/network/bearer/qnetworkconfiguration_p.h
+++ b/src/network/bearer/qnetworkconfiguration_p.h
@@ -54,7 +54,9 @@
//
#include "qnetworkconfiguration.h"
+
#include <QtCore/qshareddata.h>
+#include <QtCore/qmutex.h>
#include <QtNetwork/QNetworkInterface>
QT_BEGIN_NAMESPACE
@@ -64,8 +66,9 @@ class QNetworkConfigurationPrivate : public QSharedData
{
public:
QNetworkConfigurationPrivate ()
- : isValid(false), type(QNetworkConfiguration::Invalid),
- roamingSupported(false), purpose(QNetworkConfiguration::UnknownPurpose), internet(false)
+ : mutex(QMutex::Recursive), type(QNetworkConfiguration::Invalid),
+ purpose(QNetworkConfiguration::UnknownPurpose),
+ isValid(false), roamingSupported(false)
{
}
@@ -77,26 +80,27 @@ public:
virtual QString bearerName() const
{
+ QMutexLocker locker(&mutex);
+
return bearer;
}
- QString bearer;
+ mutable QMutex mutex;
+ QString bearer;
QString name;
-
- bool isValid;
QString id;
+
QNetworkConfiguration::StateFlags state;
QNetworkConfiguration::Type type;
- bool roamingSupported;
QNetworkConfiguration::Purpose purpose;
- bool internet;
-
QList<QNetworkConfigurationPrivatePointer> serviceNetworkMembers;
-private:
+ bool isValid;
+ bool roamingSupported;
+private:
// disallow detaching
QNetworkConfigurationPrivate &operator=(const QNetworkConfigurationPrivate &other);
QNetworkConfigurationPrivate(const QNetworkConfigurationPrivate &other);
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index ce2aee1..4010710 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -153,6 +153,7 @@ static unsigned long id_function()
QSslSocketBackendPrivate::QSslSocketBackendPrivate()
: ssl(0),
ctx(0),
+ pkey(0),
readBio(0),
writeBio(0),
session(0)
@@ -311,11 +312,14 @@ init_context:
}
// Load private key
- EVP_PKEY *pkey = q_EVP_PKEY_new();
+ pkey = q_EVP_PKEY_new();
+ // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
+ // this lead to a memory leak. Now we use the *_set1_* functions which do not
+ // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
if (configuration.privateKey.algorithm() == QSsl::Rsa)
- q_EVP_PKEY_assign_RSA(pkey, (RSA *)configuration.privateKey.handle());
+ q_EVP_PKEY_set1_RSA(pkey, (RSA *)configuration.privateKey.handle());
else
- q_EVP_PKEY_assign_DSA(pkey, (DSA *)configuration.privateKey.handle());
+ q_EVP_PKEY_set1_DSA(pkey, (DSA *)configuration.privateKey.handle());
if (!q_SSL_CTX_use_PrivateKey(ctx, pkey)) {
q->setErrorString(QSslSocket::tr("Error loading private key, %1").arg(SSL_ERRORSTR()));
emit q->error(QAbstractSocket::UnknownSocketError);
@@ -922,6 +926,11 @@ void QSslSocketBackendPrivate::disconnected()
q_SSL_CTX_free(ctx);
ctx = 0;
}
+ if (pkey) {
+ q_EVP_PKEY_free(pkey);
+ pkey = 0;
+ }
+
}
QSslCipher QSslSocketBackendPrivate::sessionCipher() const
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index 836f064..3c08757 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -97,6 +97,7 @@ public:
bool initSslContext();
SSL *ssl;
SSL_CTX *ctx;
+ EVP_PKEY *pkey;
BIO *readBio;
BIO *writeBio;
SSL_SESSION *session;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 94cc9d2..d2eb6f1 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -119,6 +119,8 @@ DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0,
DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return)
+DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
+DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return 0, return)
DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return 0, return)
@@ -510,6 +512,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(ERR_get_error, 749, libs.second )
RESOLVEFUNC(EVP_des_ede3_cbc, 919, libs.second )
RESOLVEFUNC(EVP_PKEY_assign, 859, libs.second )
+ RESOLVEFUNC(EVP_PKEY_set1_RSA, 880, libs.second )
+ RESOLVEFUNC(EVP_PKEY_set1_DSA, 879, libs.second )
RESOLVEFUNC(EVP_PKEY_free, 867, libs.second )
RESOLVEFUNC(EVP_PKEY_get1_DSA, 869, libs.second )
RESOLVEFUNC(EVP_PKEY_get1_RSA, 870, libs.second )
@@ -632,6 +636,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(ERR_get_error)
RESOLVEFUNC(EVP_des_ede3_cbc)
RESOLVEFUNC(EVP_PKEY_assign)
+ RESOLVEFUNC(EVP_PKEY_set1_RSA)
+ RESOLVEFUNC(EVP_PKEY_set1_DSA)
RESOLVEFUNC(EVP_PKEY_free)
RESOLVEFUNC(EVP_PKEY_get1_DSA)
RESOLVEFUNC(EVP_PKEY_get1_RSA)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index c93d547..ef61dbf 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -227,6 +227,8 @@ char *q_ERR_error_string(unsigned long a, char *b);
unsigned long q_ERR_get_error();
const EVP_CIPHER *q_EVP_des_ede3_cbc();
int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c);
+int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
+int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
void q_EVP_PKEY_free(EVP_PKEY *a);
RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a);
DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a);
diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro
index a67c8f6..00be80e 100644
--- a/src/plugins/bearer/bearer.pro
+++ b/src/plugins/bearer/bearer.pro
@@ -1,6 +1,6 @@
TEMPLATE = subdirs
-!maemo:contains(QT_CONFIG, dbus):contains(QT_CONFIG, networkmanager) {
+!maemo6:contains(QT_CONFIG, dbus) {
SUBDIRS += networkmanager generic
}
#win32:SUBDIRS += nla
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.h b/src/plugins/bearer/corewlan/qcorewlanengine.h
index cbaa9d6..76574a8 100644
--- a/src/plugins/bearer/corewlan/qcorewlanengine.h
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.h
@@ -68,7 +68,7 @@ public:
void connectToId(const QString &id);
void disconnectFromId(const QString &id);
- void requestUpdate();
+ Q_INVOKABLE void requestUpdate();
QNetworkSession::State sessionStateForId(const QString &id);
@@ -90,14 +90,21 @@ private:
QMap<QString, QString> configurationInterface;
QStringList scanForSsids(const QString &interfaceName);
- bool isKnownSsid(const QString &interfaceName, const QString &ssid);
+ bool isKnownSsid(const QString &ssid);
QList<QNetworkConfigurationPrivate *> foundConfigurations;
SCDynamicStoreRef storeSession;
CFRunLoopSourceRef runloopSource;
- void startNetworkChangeLoop();
+ bool hasWifi;
+
+protected:
+ QMap<QString, QMap<QString,QString> > userProfiles;
+ void startNetworkChangeLoop();
+ void getUserConfigurations();
+ QString getNetworkNameFromSsid(const QString &ssid);
+ QString getSsidFromNetworkName(const QString &name);
};
QT_END_NAMESPACE
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm
index cb278d9..392e24c 100644
--- a/src/plugins/bearer/corewlan/qcorewlanengine.mm
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm
@@ -50,13 +50,11 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qdebug.h>
-
-#if defined(MAC_SDK_10_6) //not much functionality without this
+#include <QDir>
#include <CoreWLAN/CoreWLAN.h>
#include <CoreWLAN/CWInterface.h>
#include <CoreWLAN/CWNetwork.h>
#include <CoreWLAN/CWNetwork.h>
-#endif
#include <Foundation/NSEnumerator.h>
#include <Foundation/NSKeyValueObserving.h>
@@ -69,16 +67,14 @@
QMap <QString, QString> networkInterfaces;
-#ifdef MAC_SDK_10_6
@interface QNSListener : NSObject
{
NSNotificationCenter *center;
CWInterface *currentInterface;
QCoreWlanEngine *engine;
- NSAutoreleasePool *autoreleasepool;
NSLock *locker;
}
-- (void)notificationHandler:(NSNotification *)notification;
+- (void)notificationHandler;//:(NSNotification *)notification;
- (void)remove;
- (void)setEngine:(QCoreWlanEngine *)coreEngine;
- (void)dealloc;
@@ -91,7 +87,7 @@ QMap <QString, QString> networkInterfaces;
- (id) init
{
[locker lock];
- autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacCocoaAutoReleasePool pool;
center = [NSNotificationCenter defaultCenter];
currentInterface = [CWInterface interface];
// [center addObserver:self selector:@selector(notificationHandler:) name:kCWLinkDidChangeNotification object:nil];
@@ -102,7 +98,6 @@ QMap <QString, QString> networkInterfaces;
-(void)dealloc
{
- [autoreleasepool release];
[super dealloc];
}
@@ -121,7 +116,7 @@ QMap <QString, QString> networkInterfaces;
[locker unlock];
}
-- (void)notificationHandler:(NSNotification *)notification
+- (void)notificationHandler//:(NSNotification *)notification
{
engine->requestUpdate();
}
@@ -129,14 +124,12 @@ QMap <QString, QString> networkInterfaces;
QNSListener *listener = 0;
-#endif
-
QT_BEGIN_NAMESPACE
static QString qGetInterfaceType(const QString &interfaceString)
{
- return networkInterfaces.value(interfaceString, QLatin1String("Unknown"));
+ return networkInterfaces.value(interfaceString, QLatin1String("WLAN"));
}
void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef changedKeys, void *info)
@@ -157,22 +150,24 @@ QCoreWlanEngine::QCoreWlanEngine(QObject *parent)
{
startNetworkChangeLoop();
-#if defined(MAC_SDK_10_6)
- if(!listener) {
+ QMacCocoaAutoReleasePool pool;
+ if([[CWInterface supportedInterfaces] count] > 0 && !listener) {
listener = [[QNSListener alloc] init];
listener.engine = this;
+ hasWifi = true;
+ } else {
+ hasWifi = false;
}
-#endif
+ getUserConfigurations();
+ requestUpdate();
}
QCoreWlanEngine::~QCoreWlanEngine()
{
while (!foundConfigurations.isEmpty())
delete foundConfigurations.takeFirst();
-#if defined(MAC_SDK_10_6)
[listener remove];
[listener release];
-#endif
}
QString QCoreWlanEngine::getInterfaceFromId(const QString &id)
@@ -192,73 +187,88 @@ bool QCoreWlanEngine::hasIdentifier(const QString &id)
void QCoreWlanEngine::connectToId(const QString &id)
{
QMutexLocker locker(&mutex);
-
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacCocoaAutoReleasePool pool;
QString interfaceString = getInterfaceFromId(id);
if(networkInterfaces.value(interfaceString) == "WLAN") {
-#if defined(MAC_SDK_10_6)
CWInterface *wifiInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)];
- CWConfiguration *userConfig = [ wifiInterface configuration];
-
- NSSet *remNets = [userConfig rememberedNetworks]; //CWWirelessProfile
- NSEnumerator *enumerator = [remNets objectEnumerator];
- CWWirelessProfile *wProfile;
- NSUInteger index=0;
- NSDictionary *parametersDict;
- NSArray* apArray;
-
- CW8021XProfile *user8021XProfile;
- NSError *err;
- NSMutableDictionary *params;
+ if([wifiInterface power]) {
+ NSError *err = nil;
+ NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0];
+
+ NSString *wantedSsid = 0;
+ bool okToProceed = true;
+ if(getNetworkNameFromSsid(id) != id) {
+ NSArray *array = [CW8021XProfile allUser8021XProfiles];
+ for (NSUInteger i=0; i<[array count]; ++i) {
+ const QString idCheck = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([[array objectAtIndex:i] userDefinedName])));
+ const QString idCheck2 = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([[array objectAtIndex:i] ssid])));
+
+ if(id == idCheck
+ || id == idCheck2) {
+ QString thisName = getSsidFromNetworkName(id);
+ if(thisName.isEmpty()) {
+ wantedSsid = qt_mac_QStringToNSString(id);
+ } else {
+ wantedSsid = qt_mac_QStringToNSString(thisName);
+ }
+ okToProceed = false;
+ [params setValue: [array objectAtIndex:i] forKey:kCWAssocKey8021XProfile];
+ break;
+ }
+ }
+ }
- while ((wProfile = [enumerator nextObject])) { //CWWirelessProfile
+ if(okToProceed) {
+ NSUInteger index = 0;
- if(id == QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([wProfile ssid])))) {
- user8021XProfile = nil;
- user8021XProfile = [ wProfile user8021XProfile];
+ CWConfiguration *userConfig = [ wifiInterface configuration];
+ NSSet *remNets = [userConfig rememberedNetworks];
+ NSEnumerator *enumerator = [remNets objectEnumerator];
+ CWWirelessProfile *wProfile;
- err = nil;
- params = [NSMutableDictionary dictionaryWithCapacity:0];
+ while ((wProfile = [enumerator nextObject])) {
+ const QString idCheck = QString::number(qHash(QLatin1String("corewlan:") + qt_mac_NSStringToQString([wProfile ssid])));
- if(user8021XProfile) {
- [params setValue: user8021XProfile forKey:kCWAssocKey8021XProfile];
- } else {
- [params setValue: [wProfile passphrase] forKey: kCWAssocKeyPassphrase];
+ if(id == idCheck) {
+ wantedSsid = [wProfile ssid];
+ [params setValue: [wProfile passphrase] forKey: kCWAssocKeyPassphrase];
+ break;
+ }
+ index++;
}
+ }
- parametersDict = nil;
- apArray = [NSMutableArray arrayWithArray:[wifiInterface scanForNetworksWithParameters:parametersDict error:&err]];
-
- if(!err) {
-
- for(uint row=0; row < [apArray count]; row++ ) {
- CWNetwork *apNetwork = [apArray objectAtIndex:row];
- if([[apNetwork ssid] compare:[wProfile ssid]] == NSOrderedSame) {
+ NSDictionary *parametersDict = nil;
+ NSArray *apArray = [NSMutableArray arrayWithArray:[wifiInterface scanForNetworksWithParameters:parametersDict error:&err]];
- bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err];
+ if(!err) {
+ for(uint row=0; row < [apArray count]; row++ ) {
+ CWNetwork *apNetwork = [apArray objectAtIndex:row];
+ if([[apNetwork ssid] compare:wantedSsid] == NSOrderedSame) {
+ bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err];
- if(!result) {
- emit connectionError(id, ConnectError);
- } else {
- [autoreleasepool release];
- return;
- }
+ if(!result) {
+ emit connectionError(id, ConnectError);
+ } else {
+ return;
}
}
}
+ } else {
+ qDebug() <<"ERROR"<< qt_mac_NSStringToQString([err localizedDescription ]);
}
- index++;
- }
+ emit connectionError(id, InterfaceLookupError);
+ } else {
+ // not wifi
+ }
+ locker.unlock();
emit connectionError(id, InterfaceLookupError);
-#endif
- } else {
- // not wifi
+ locker.relock();
}
emit connectionError(id, OperationNotSupported);
- [autoreleasepool release];
}
void QCoreWlanEngine::disconnectFromId(const QString &id)
@@ -268,25 +278,26 @@ void QCoreWlanEngine::disconnectFromId(const QString &id)
QString interfaceString = getInterfaceFromId(id);
if(networkInterfaces.value(getInterfaceFromId(id)) == "WLAN") { //wifi only for now
#if defined(MAC_SDK_10_6)
- NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+ QMacCocoaAutoReleasePool pool;
CWInterface *wifiInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceString)];
[wifiInterface disassociate];
if([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) {
+ locker.unlock();
emit connectionError(id, DisconnectionError);
+ locker.relock();
}
- [autoreleasepool release];
return;
#endif
} else {
}
+
+ locker.unlock();
emit connectionError(id, OperationNotSupported);
}
void QCoreWlanEngine::requestUpdate()
{
- QMutexLocker locker(&mutex);
-
doRequestUpdate();
}
@@ -340,6 +351,8 @@ void QCoreWlanEngine::doRequestUpdate()
bool changed = false;
+ ptr->mutex.lock();
+
if (!ptr->isValid) {
ptr->isValid = true;
changed = true;
@@ -360,8 +373,13 @@ void QCoreWlanEngine::doRequestUpdate()
changed = true;
}
- if (changed)
+ ptr->mutex.unlock();
+
+ if (changed) {
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+ }
}
}
@@ -369,9 +387,13 @@ void QCoreWlanEngine::doRequestUpdate()
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(previous.takeFirst());
configurationInterface.remove(ptr->id);
+
+ locker.unlock();
emit configurationRemoved(ptr);
+ locker.relock();
}
+ locker.unlock();
emit updateCompleted();
}
@@ -381,16 +403,20 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName)
QStringList found;
-#if defined(MAC_SDK_10_6)
- QMacCocoaAutoReleasePool pool;
+ if(!hasWifi) {
+ return found;
+ }
+ QMacCocoaAutoReleasePool pool;
CWInterface *currentInterface = [CWInterface interfaceWithName:qt_mac_QStringToNSString(interfaceName)];
+ QStringList addedConfigs;
+
if([currentInterface power]) {
NSError *err = nil;
NSDictionary *parametersDict = nil;
NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err];
-
CWNetwork *apNetwork;
+
if (!err) {
for(uint row=0; row < [apArray count]; row++ ) {
@@ -402,15 +428,18 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName)
found.append(id);
QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
-
- if ([currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
- if (networkSsid == qt_mac_NSStringToQString([currentInterface ssid]))
+ bool known = isKnownSsid(networkSsid);
+ if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
+ if( networkSsid == qt_mac_NSStringToQString( [currentInterface ssid])) {
state = QNetworkConfiguration::Active;
- } else {
- if (isKnownSsid(interfaceName, networkSsid))
+ }
+ }
+ if(state == QNetworkConfiguration::Undefined) {
+ if(known) {
state = QNetworkConfiguration::Discovered;
- else
- state = QNetworkConfiguration::Defined;
+ } else {
+ state = QNetworkConfiguration::Undefined;
+ }
}
if (accessPointConfigurations.contains(id)) {
@@ -418,6 +447,8 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName)
bool changed = false;
+ ptr->mutex.lock();
+
if (!ptr->isValid) {
ptr->isValid = true;
changed = true;
@@ -438,11 +469,18 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName)
changed = true;
}
- if (changed)
+ ptr->mutex.unlock();
+
+ if (changed) {
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+ }
+ addedConfigs << networkSsid;
} else {
QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
+ found.append(id);
ptr->name = networkSsid;
ptr->isValid = true;
ptr->id = id;
@@ -450,17 +488,60 @@ QStringList QCoreWlanEngine::scanForSsids(const QString &interfaceName)
ptr->type = QNetworkConfiguration::InternetAccessPoint;
ptr->bearer = QLatin1String("WLAN");
- accessPointConfigurations.insert(id, ptr);
- configurationInterface.insert(id, interfaceName);
+ accessPointConfigurations.insert(ptr->id, ptr);
+ configurationInterface.insert(ptr->id, interfaceName);
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
+ addedConfigs << networkSsid;
}
}
}
}
-#else
- Q_UNUSED(interfaceName);
-#endif
+
+ // add known configurations that are not around.
+ QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+ while (i.hasNext()) {
+ i.next();
+ QString networkName = i.key();
+ if(!addedConfigs.contains(networkName)) {
+ QString interfaceName;
+ QMapIterator<QString, QString> ij(i.value());
+ while (ij.hasNext()) {
+ ij.next();
+ interfaceName = ij.value();
+ }
+ QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
+ const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName));
+ found.append(id);
+
+ ptr->name = networkName;
+ ptr->isValid = true;
+ ptr->id = id;
+ ptr->bearer = QLatin1String("WLAN");
+ ptr->type = QNetworkConfiguration::InternetAccessPoint;
+ QString ssid = getSsidFromNetworkName(networkName);
+
+ if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
+ if( ssid == qt_mac_NSStringToQString([currentInterface ssid])) {
+ ptr->state = QNetworkConfiguration::Active;
+ }
+ }
+
+ if(!ptr->state) {
+ if( addedConfigs.contains(ssid)) {
+ ptr->state = QNetworkConfiguration::Discovered;
+ }
+ }
+
+ if(!ptr->state) {
+ ptr->state = QNetworkConfiguration::Defined;
+ }
+ accessPointConfigurations.insert(ptr->id, ptr);
+ configurationInterface.insert(ptr->id, interfaceName);
+ }
+ }
return found;
}
@@ -468,32 +549,27 @@ bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
{
QMutexLocker locker(&mutex);
-#if defined(MAC_SDK_10_6)
- CWInterface *defaultInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(wifiDeviceName)];
- if([defaultInterface power])
- return true;
-#else
- Q_UNUSED(wifiDeviceName);
-#endif
+ if(hasWifi) {
+ QMacCocoaAutoReleasePool pool;
+ CWInterface *defaultInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(wifiDeviceName)];
+ if([defaultInterface power])
+ return true;
+ }
return false;
}
-bool QCoreWlanEngine::isKnownSsid(const QString &interfaceName, const QString &ssid)
+bool QCoreWlanEngine::isKnownSsid(const QString &ssid)
{
QMutexLocker locker(&mutex);
-#if defined(MAC_SDK_10_6)
- CWInterface *wifiInterface = [CWInterface interfaceWithName: qt_mac_QStringToNSString(interfaceName)];
- CWConfiguration *userConfig = [wifiInterface configuration];
- NSSet *remNets = [userConfig rememberedNetworks];
- for (CWWirelessProfile *wProfile in remNets) {
- if(ssid == qt_mac_NSStringToQString([wProfile ssid]))
+ QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+ while (i.hasNext()) {
+ i.next();
+ QMap<QString,QString> map = i.value();
+ if(map.keys().contains(ssid)) {
return true;
+ }
}
-#else
- Q_UNUSED(interfaceName);
- Q_UNUSED(ssid);
-#endif
return false;
}
@@ -508,7 +584,6 @@ bool QCoreWlanEngine::getWifiInterfaces()
for(uint row=0; row < [wifiInterfaces count]; row++ ) {
networkInterfaces.insert( qt_mac_NSStringToQString([wifiInterfaces objectAtIndex:row]),"WLAN");
}
-
return true;
}
@@ -612,4 +687,124 @@ bool QCoreWlanEngine::requiresPolling() const
return true;
}
+QString QCoreWlanEngine::getSsidFromNetworkName(const QString &name)
+{
+ QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+ while (i.hasNext()) {
+ i.next();
+
+ QMap<QString,QString> map = i.value();
+ QMapIterator<QString, QString> ij(i.value());
+ while (ij.hasNext()) {
+ ij.next();
+ const QString idCheck = QString::number(qHash(QLatin1String("corewlan:") +i.key()));
+ if(name == i.key() || name == idCheck) {
+ return ij.key();
+ }
+ }
+ }
+ return QString();
+}
+
+QString QCoreWlanEngine::getNetworkNameFromSsid(const QString &ssid)
+{
+ QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+ while (i.hasNext()) {
+ i.next();
+ QMap<QString,QString> map = i.value();
+ QMapIterator<QString, QString> ij(i.value());
+ while (ij.hasNext()) {
+ ij.next();
+ if(ij.key() == ssid) {
+ return i.key();
+ }
+
+ }
+ return map.key(ssid);
+ }
+ return QString();
+}
+
+
+void QCoreWlanEngine::getUserConfigurations()
+{
+ QMacCocoaAutoReleasePool pool;
+ userProfiles.clear();
+
+ NSArray *wifiInterfaces = [CWInterface supportedInterfaces];
+ for(uint row=0; row < [wifiInterfaces count]; row++ ) {
+
+ CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]];
+
+// add user configured system networks
+ NSString *filePath = @"/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist";
+ NSDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
+ NSString *input = @"KnownNetworks";
+ NSString *ssidStr = @"SSID_STR";
+
+ for (id key in plistDict) {
+ if ([input isEqualToString:key]) {
+
+ NSDictionary *knownNetworksDict = [plistDict objectForKey:key];
+ for (id networkKey in knownNetworksDict) {
+
+ NSDictionary *itemDict = [knownNetworksDict objectForKey:networkKey];
+ NSInteger dictSize = [itemDict count];
+ id objects[dictSize];
+ id keys[dictSize];
+
+ [itemDict getObjects:objects andKeys:keys];
+
+ for(int i = 0; i < dictSize; i++) {
+ if([ssidStr isEqualToString:keys[i]]) {
+ QString thisSsid = qt_mac_NSStringToQString(objects[i]);
+ if(!userProfiles.contains(thisSsid)) {
+ QMap <QString,QString> map;
+ map.insert(thisSsid, qt_mac_NSStringToQString([wifiInterface name]));
+ userProfiles.insert(thisSsid, map);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 802.1X user profiles
+ QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist";
+ NSDictionary* eapDict = [[NSMutableDictionary alloc] initWithContentsOfFile:qt_mac_QStringToNSString(userProfilePath)];
+ NSString *profileStr= @"Profiles";
+ NSString *nameStr = @"UserDefinedName";
+ NSString *networkSsidStr = @"Wireless Network";
+ for (id profileKey in eapDict) {
+ if ([profileStr isEqualToString:profileKey]) {
+ NSDictionary *itemDict = [eapDict objectForKey:profileKey];
+ for (id itemKey in itemDict) {
+
+ NSInteger dictSize = [itemKey count];
+ id objects[dictSize];
+ id keys[dictSize];
+
+ [itemKey getObjects:objects andKeys:keys];
+ QString networkName;
+ QString ssid;
+ for(int i = 0; i < dictSize; i++) {
+ if([nameStr isEqualToString:keys[i]]) {
+ networkName = qt_mac_NSStringToQString(objects[i]);
+ }
+ if([networkSsidStr isEqualToString:keys[i]]) {
+ ssid = qt_mac_NSStringToQString(objects[i]);
+ }
+ if(!userProfiles.contains(networkName)
+ && !ssid.isEmpty()) {
+ QMap<QString,QString> map;
+ map.insert(ssid, qt_mac_NSStringToQString([wifiInterface name]));
+ userProfiles.insert(networkName, map);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp
index a9e78b2..dfc74f2 100644
--- a/src/plugins/bearer/generic/qgenericengine.cpp
+++ b/src/plugins/bearer/generic/qgenericengine.cpp
@@ -50,6 +50,7 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qdebug.h>
+#include <QtCore/private/qcoreapplication_p.h>
#ifdef Q_OS_WIN
#include "../platformdefs_win.h"
@@ -174,8 +175,6 @@ void QGenericEngine::disconnectFromId(const QString &id)
void QGenericEngine::requestUpdate()
{
- QMutexLocker locker(&mutex);
-
doRequestUpdate();
}
@@ -231,6 +230,8 @@ void QGenericEngine::doRequestUpdate()
bool changed = false;
+ ptr->mutex.lock();
+
if (!ptr->isValid) {
ptr->isValid = true;
changed = true;
@@ -251,8 +252,13 @@ void QGenericEngine::doRequestUpdate()
changed = true;
}
- if (changed)
+ ptr->mutex.unlock();
+
+ if (changed) {
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+ }
} else {
QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
@@ -266,7 +272,9 @@ void QGenericEngine::doRequestUpdate()
accessPointConfigurations.insert(id, ptr);
configurationInterface.insert(id, interface.name());
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
}
}
@@ -275,9 +283,13 @@ void QGenericEngine::doRequestUpdate()
accessPointConfigurations.take(previous.takeFirst());
configurationInterface.remove(ptr->id);
+
+ locker.unlock();
emit configurationRemoved(ptr);
+ locker.relock();
}
+ locker.unlock();
emit updateCompleted();
}
@@ -290,6 +302,8 @@ QNetworkSession::State QGenericEngine::sessionStateForId(const QString &id)
if (!ptr)
return QNetworkSession::Invalid;
+ QMutexLocker configLocker(&ptr->mutex);
+
if (!ptr->isValid) {
return QNetworkSession::Invalid;
} else if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
diff --git a/src/plugins/bearer/generic/qgenericengine.h b/src/plugins/bearer/generic/qgenericengine.h
index a1b9167..616a3fd 100644
--- a/src/plugins/bearer/generic/qgenericengine.h
+++ b/src/plugins/bearer/generic/qgenericengine.h
@@ -68,7 +68,7 @@ public:
void connectToId(const QString &id);
void disconnectFromId(const QString &id);
- void requestUpdate();
+ Q_INVOKABLE void requestUpdate();
QNetworkSession::State sessionStateForId(const QString &id);
diff --git a/src/plugins/bearer/icd/qicdengine.cpp b/src/plugins/bearer/icd/qicdengine.cpp
index 5e506ef..5e9dc0a 100644
--- a/src/plugins/bearer/icd/qicdengine.cpp
+++ b/src/plugins/bearer/icd/qicdengine.cpp
@@ -180,7 +180,10 @@ void QIcdEngine::doRequestUpdate()
ptr->roamingSupported = false;
userChoiceConfigurations.insert(ptr->id, ptr);
+
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
}
/* We return currently configured IAPs in the first run and do the WLAN
@@ -241,7 +244,10 @@ void QIcdEngine::doRequestUpdate()
QNetworkConfigurationPrivatePointer ptr(cpPriv);
accessPointConfigurations.insert(iap_id, ptr);
+
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
#ifdef BEARER_MANAGEMENT_DEBUG
qDebug("IAP: %s, name: %s, ssid: %s, added to known list",
@@ -299,6 +305,8 @@ void QIcdEngine::doRequestUpdate()
bool changed = false;
+ ptr->mutex.lock();
+
if (!ptr->isValid) {
ptr->isValid = true;
changed = true;
@@ -319,8 +327,13 @@ void QIcdEngine::doRequestUpdate()
iapid.toAscii().data(), scanned_ssid.data());
#endif
- if (changed)
+ ptr->mutex.unlock();
+
+ if (changed) {
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+ }
if (!ap.scan.network_type.startsWith("WLAN"))
continue; // not a wlan AP
@@ -354,7 +367,10 @@ void QIcdEngine::doRequestUpdate()
QNetworkConfigurationPrivatePointer ptr(cpPriv);
accessPointConfigurations.insert(ptr->id, ptr);
+
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
}
}
}
@@ -363,11 +379,15 @@ void QIcdEngine::doRequestUpdate()
QNetworkConfigurationPrivatePointer ptr =
accessPointConfigurations.take(previous.takeFirst());
+ locker.unlock();
emit configurationRemoved(ptr);
+ locker.relock();
}
- if (sender())
+ if (sender()) {
+ locker.unlock();
emit updateCompleted();
+ }
}
void QIcdEngine::deleteConfiguration(const QString &iap_id)
@@ -384,6 +404,7 @@ void QIcdEngine::deleteConfiguration(const QString &iap_id)
qDebug() << "IAP" << iap_id << "was removed from storage.";
#endif
+ locker.unlock();
emit configurationRemoved(ptr);
} else {
#ifdef BEARER_MANAGEMENT_DEBUG
diff --git a/src/plugins/bearer/icd/qicdengine.h b/src/plugins/bearer/icd/qicdengine.h
index 6ebe40d..50cda62 100644
--- a/src/plugins/bearer/icd/qicdengine.h
+++ b/src/plugins/bearer/icd/qicdengine.h
@@ -86,7 +86,7 @@ public:
bool hasIdentifier(const QString &id);
- void requestUpdate();
+ Q_INVOKABLE void requestUpdate();
QNetworkConfigurationManager::Capabilities capabilities() const;
diff --git a/src/plugins/bearer/icd/qnetworksession_impl.cpp b/src/plugins/bearer/icd/qnetworksession_impl.cpp
index bb81408..a2ae65c 100644
--- a/src/plugins/bearer/icd/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/icd/qnetworksession_impl.cpp
@@ -312,19 +312,42 @@ void QNetworkSessionPrivateImpl::updateState(QNetworkSession::State newState)
state = newState;
if (state == QNetworkSession::Disconnected) {
- isOpen = false;
+ isOpen = false;
currentNetworkInterface.clear();
- if (publicConfig.type() == QNetworkConfiguration::UserChoice)
- privateConfiguration(activeConfig)->state = QNetworkConfiguration::Defined;
- privateConfiguration(publicConfig)->state = QNetworkConfiguration::Defined;
+ if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
+ IcdNetworkConfigurationPrivate *icdConfig =
+ toIcdConfig(privateConfiguration(activeConfig));
+
+ icdConfig->mutex.lock();
+ icdConfig->state = QNetworkConfiguration::Defined;
+ icdConfig->mutex.unlock();
+ }
+
+ IcdNetworkConfigurationPrivate *icdConfig =
+ toIcdConfig(privateConfiguration(publicConfig));
+
+ icdConfig->mutex.lock();
+ icdConfig->state = QNetworkConfiguration::Defined;
+ icdConfig->mutex.unlock();
} else if (state == QNetworkSession::Connected) {
- isOpen = true;
+ isOpen = true;
if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
- privateConfiguration(activeConfig)->state = QNetworkConfiguration::Active;
- privateConfiguration(activeConfig)->type = QNetworkConfiguration::InternetAccessPoint;
+ IcdNetworkConfigurationPrivate *icdConfig =
+ toIcdConfig(privateConfiguration(activeConfig));
+
+ icdConfig->mutex.lock();
+ icdConfig->state = QNetworkConfiguration::Active;
+ icdConfig->type = QNetworkConfiguration::InternetAccessPoint;
+ icdConfig->mutex.unlock();
}
- privateConfiguration(publicConfig)->state = QNetworkConfiguration::Active;
+
+ IcdNetworkConfigurationPrivate *icdConfig =
+ toIcdConfig(privateConfiguration(publicConfig));
+
+ icdConfig->mutex.lock();
+ icdConfig->state = QNetworkConfiguration::Active;
+ icdConfig->mutex.unlock();
}
emit stateChanged(newState);
@@ -334,13 +357,22 @@ void QNetworkSessionPrivateImpl::updateState(QNetworkSession::State newState)
void QNetworkSessionPrivateImpl::updateIdentifier(QString &newId)
{
if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
- toIcdConfig(privateConfiguration(activeConfig))->network_attrs |= ICD_NW_ATTR_IAPNAME;
- privateConfiguration(activeConfig)->id = newId;
+ IcdNetworkConfigurationPrivate *icdConfig =
+ toIcdConfig(privateConfiguration(activeConfig));
+
+ icdConfig->mutex.lock();
+ icdConfig->network_attrs |= ICD_NW_ATTR_IAPNAME;
+ icdConfig->id = newId;
+ icdConfig->mutex.unlock();
} else {
- toIcdConfig(privateConfiguration(publicConfig))->network_attrs |= ICD_NW_ATTR_IAPNAME;
- if (privateConfiguration(publicConfig)->id != newId) {
- privateConfiguration(publicConfig)->id = newId;
- }
+ IcdNetworkConfigurationPrivate *icdConfig =
+ toIcdConfig(privateConfiguration(publicConfig));
+
+ icdConfig->mutex.lock();
+ icdConfig->network_attrs |= ICD_NW_ATTR_IAPNAME;
+ if (icdConfig->id != newId)
+ icdConfig->id = newId;
+ icdConfig->mutex.unlock();
}
}
@@ -368,10 +400,15 @@ quint64 QNetworkSessionPrivateImpl::getStatistics(bool sent) const
}
} else {
/* We probably will never get to this branch */
- if (res.params.network_id == toIcdConfig(privateConfiguration(activeConfig))->network_id) {
- counter_tx = res.bytes_sent;
- counter_rx = res.bytes_received;
+ IcdNetworkConfigurationPrivate *icdConfig =
+ toIcdConfig(privateConfiguration(activeConfig));
+
+ icdConfig->mutex.lock();
+ if (res.params.network_id == icdConfig->network_id) {
+ counter_tx = res.bytes_sent;
+ counter_rx = res.bytes_received;
}
+ icdConfig->mutex.unlock();
}
}
@@ -413,20 +450,25 @@ QNetworkConfiguration& QNetworkSessionPrivateImpl::copyConfig(QNetworkConfigurat
cpPriv = toIcdConfig(privateConfiguration(toConfig));
}
- cpPriv->name = privateConfiguration(fromConfig)->name;
- cpPriv->isValid = privateConfiguration(fromConfig)->isValid;
+ IcdNetworkConfigurationPrivate *fromPriv = toIcdConfig(privateConfiguration(fromConfig));
+
+ QMutexLocker toLocker(&cpPriv->mutex);
+ QMutexLocker fromLocker(&fromPriv->mutex);
+
+ cpPriv->name = fromPriv->name;
+ cpPriv->isValid = fromPriv->isValid;
// Note that we do not copy id field here as the publicConfig does
// not contain a valid IAP id.
- cpPriv->state = privateConfiguration(fromConfig)->state;
- cpPriv->type = privateConfiguration(fromConfig)->type;
- cpPriv->roamingSupported = privateConfiguration(fromConfig)->roamingSupported;
- cpPriv->purpose = privateConfiguration(fromConfig)->purpose;
- cpPriv->network_id = toIcdConfig(privateConfiguration(fromConfig))->network_id;
- cpPriv->iap_type = toIcdConfig(privateConfiguration(fromConfig))->iap_type;
- cpPriv->network_attrs = toIcdConfig(privateConfiguration(fromConfig))->network_attrs;
- cpPriv->service_type = toIcdConfig(privateConfiguration(fromConfig))->service_type;
- cpPriv->service_id = toIcdConfig(privateConfiguration(fromConfig))->service_id;
- cpPriv->service_attrs = toIcdConfig(privateConfiguration(fromConfig))->service_attrs;
+ cpPriv->state = fromPriv->state;
+ cpPriv->type = fromPriv->type;
+ cpPriv->roamingSupported = fromPriv->roamingSupported;
+ cpPriv->purpose = fromPriv->purpose;
+ cpPriv->network_id = fromPriv->network_id;
+ cpPriv->iap_type = fromPriv->iap_type;
+ cpPriv->network_attrs = fromPriv->network_attrs;
+ cpPriv->service_type = fromPriv->service_type;
+ cpPriv->service_id = fromPriv->service_id;
+ cpPriv->service_attrs = fromPriv->service_attrs;
return toConfig;
}
@@ -511,18 +553,30 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface()
* then do not update current state etc.
*/
if (publicConfig.type() == QNetworkConfiguration::UserChoice ||
- privateConfiguration(publicConfig)->id == state_results.first().params.network_id) {
+ publicConfig.identifier() == state_results.first().params.network_id) {
switch (state_results.first().state) {
case ICD_STATE_DISCONNECTED:
state = QNetworkSession::Disconnected;
- if (privateConfiguration(activeConfig))
- privateConfiguration(activeConfig)->isValid = true;
+ {
+ QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig);
+ if (ptr) {
+ ptr->mutex.lock();
+ ptr->isValid = true;
+ ptr->mutex.unlock();
+ }
+ }
break;
case ICD_STATE_CONNECTING:
state = QNetworkSession::Connecting;
- if (privateConfiguration(activeConfig))
- privateConfiguration(activeConfig)->isValid = true;
+ {
+ QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig);
+ if (ptr) {
+ ptr->mutex.lock();
+ ptr->isValid = true;
+ ptr->mutex.unlock();
+ }
+ }
break;
case ICD_STATE_CONNECTED:
{
@@ -540,6 +594,8 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface()
QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig);
+ QMutexLocker configLocker(&ptr->mutex);
+
state = QNetworkSession::Connected;
toIcdConfig(ptr)->network_id = state_results.first().params.network_id;
ptr->id = toIcdConfig(ptr)->network_id;
@@ -553,26 +609,35 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface()
ptr->isValid = true;
currentNetworkInterface = get_network_interface();
- Maemo::IAPConf iap_name(privateConfiguration(activeConfig)->id);
+ Maemo::IAPConf iap_name(ptr->id);
QString name_value = iap_name.value("name").toString();
if (!name_value.isEmpty())
- privateConfiguration(activeConfig)->name = name_value;
+ ptr->name = name_value;
else
- privateConfiguration(activeConfig)->name = privateConfiguration(activeConfig)->id;
+ ptr->name = ptr->id;
// Add the new active configuration to manager or update the old config
- if (!engine->hasIdentifier(privateConfiguration(activeConfig)->id))
- engine->addSessionConfiguration(privateConfiguration(activeConfig));
- else
- engine->changedSessionConfiguration(privateConfiguration(activeConfig));
- }
+ if (!engine->hasIdentifier(ptr->id)) {
+ configLocker.unlock();
+ engine->addSessionConfiguration(ptr);
+ } else {
+ configLocker.unlock();
+ engine->changedSessionConfiguration(ptr);
+ }
+ }
break;
case ICD_STATE_DISCONNECTING:
state = QNetworkSession::Closing;
- if (privateConfiguration(activeConfig))
- privateConfiguration(activeConfig)->isValid = true;
+ {
+ QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig);
+ if (ptr) {
+ ptr->mutex.lock();
+ ptr->isValid = true;
+ ptr->mutex.unlock();
+ }
+ }
break;
default:
break;
@@ -634,12 +699,16 @@ void QNetworkSessionPrivateImpl::updateStateFromServiceNetwork()
void QNetworkSessionPrivateImpl::clearConfiguration(QNetworkConfiguration &config)
{
- toIcdConfig(privateConfiguration(config))->network_id.clear();
- toIcdConfig(privateConfiguration(config))->iap_type.clear();
- toIcdConfig(privateConfiguration(config))->network_attrs = 0;
- toIcdConfig(privateConfiguration(config))->service_type.clear();
- toIcdConfig(privateConfiguration(config))->service_id.clear();
- toIcdConfig(privateConfiguration(config))->service_attrs = 0;
+ IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(config));
+
+ QMutexLocker locker(&icdConfig->mutex);
+
+ icdConfig->network_id.clear();
+ icdConfig->iap_type.clear();
+ icdConfig->network_attrs = 0;
+ icdConfig->service_type.clear();
+ icdConfig->service_id.clear();
+ icdConfig->service_attrs = 0;
}
@@ -649,8 +718,8 @@ void QNetworkSessionPrivateImpl::updateStateFromActiveConfig()
bool newActive = false;
- if (!privateConfiguration(activeConfig))
- return;
+ if (!activeConfig.isValid())
+ return;
if (!activeConfig.isValid()) {
state = QNetworkSession::Invalid;
@@ -837,16 +906,21 @@ void QNetworkSessionPrivateImpl::do_open()
QList<Maemo::ConnectParams> params;
Maemo::ConnectParams param;
- param.connect.service_type = toIcdConfig(privateConfiguration(config))->service_type;
- param.connect.service_attrs = toIcdConfig(privateConfiguration(config))->service_attrs;
- param.connect.service_id = toIcdConfig(privateConfiguration(config))->service_id;
- param.connect.network_type = toIcdConfig(privateConfiguration(config))->iap_type;
- param.connect.network_attrs = toIcdConfig(privateConfiguration(config))->network_attrs;
- if (toIcdConfig(privateConfiguration(config))->network_attrs & ICD_NW_ATTR_IAPNAME)
+
+ IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(config));
+
+ icdConfig->mutex.lock();
+ param.connect.service_type = icdConfig->service_type;
+ param.connect.service_attrs = icdConfig->service_attrs;
+ param.connect.service_id = icdConfig->service_id;
+ param.connect.network_type = icdConfig->iap_type;
+ param.connect.network_attrs = icdConfig->network_attrs;
+ if (icdConfig->network_attrs & ICD_NW_ATTR_IAPNAME)
param.connect.network_id = QByteArray(iap.toLatin1());
else
- param.connect.network_id = toIcdConfig(privateConfiguration(config))->network_id;
+ param.connect.network_id = icdConfig->network_id;
params.append(param);
+ icdConfig->mutex.unlock();
#ifdef BEARER_MANAGEMENT_DEBUG
qDebug("connecting to %s/%s/0x%x/%s/0x%x/%s",
@@ -887,26 +961,30 @@ void QNetworkSessionPrivateImpl::do_open()
return;
}
+ IcdNetworkConfigurationPrivate *icdConfig = toIcdConfig(privateConfiguration(config));
/* Did we connect to non saved IAP? */
- if (!(toIcdConfig(privateConfiguration(config))->network_attrs & ICD_NW_ATTR_IAPNAME)) {
+ icdConfig->mutex.lock();
+ if (!(icdConfig->network_attrs & ICD_NW_ATTR_IAPNAME)) {
/* Because the connection succeeded, the IAP is now known.
*/
- toIcdConfig(privateConfiguration(config))->network_attrs |= ICD_NW_ATTR_IAPNAME;
- privateConfiguration(config)->id = connected_iap;
+ icdConfig->network_attrs |= ICD_NW_ATTR_IAPNAME;
+ icdConfig->id = connected_iap;
}
/* User might have changed the IAP name when a new IAP was saved */
- Maemo::IAPConf iap_name(privateConfiguration(config)->id);
+ Maemo::IAPConf iap_name(icdConfig->id);
QString name = iap_name.value("name").toString();
if (!name.isEmpty())
- privateConfiguration(config)->name = name;
+ icdConfig->name = name;
+
+ icdConfig->iap_type = connect_result.connect.network_type;
- toIcdConfig(privateConfiguration(config))->iap_type = connect_result.connect.network_type;
+ icdConfig->isValid = true;
+ icdConfig->state = QNetworkConfiguration::Active;
+ icdConfig->type = QNetworkConfiguration::InternetAccessPoint;
- privateConfiguration(config)->isValid = true;
- privateConfiguration(config)->state = QNetworkConfiguration::Active;
- privateConfiguration(config)->type = QNetworkConfiguration::InternetAccessPoint;
+ icdConfig->mutex.unlock();
startTime = QDateTime::currentDateTime();
updateState(QNetworkSession::Connected);
@@ -995,8 +1073,11 @@ void QNetworkSessionPrivateImpl::stop()
* configurationChanged is emitted (below).
*/
- privateConfiguration(activeConfig)->state = QNetworkConfiguration::Discovered;
- engine->changedSessionConfiguration(privateConfiguration(activeConfig));
+ QNetworkConfigurationPrivatePointer ptr = privateConfiguration(activeConfig);
+ ptr->mutex.lock();
+ ptr->state = QNetworkConfiguration::Discovered;
+ ptr->mutex.unlock();
+ engine->changedSessionConfiguration(ptr);
opened = false;
isOpen = false;
diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp
index b6522ad..6c74159 100644
--- a/src/plugins/bearer/nativewifi/qnativewifiengine.cpp
+++ b/src/plugins/bearer/nativewifi/qnativewifiengine.cpp
@@ -185,6 +185,8 @@ void QNativeWifiEngine::scanComplete()
bool changed = false;
+ ptr->mutex.lock();
+
if (!ptr->isValid) {
ptr->isValid = true;
changed = true;
@@ -200,8 +202,13 @@ void QNativeWifiEngine::scanComplete()
changed = true;
}
- if (changed)
+ ptr->mutex.unlock();
+
+ if (changed) {
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+ }
} else {
QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
@@ -214,7 +221,9 @@ void QNativeWifiEngine::scanComplete()
accessPointConfigurations.insert(id, ptr);
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
}
}
@@ -227,9 +236,12 @@ void QNativeWifiEngine::scanComplete()
QNetworkConfigurationPrivatePointer ptr =
accessPointConfigurations.take(previous.takeFirst());
+ locker.unlock();
emit configurationRemoved(ptr);
+ locker.relock();
}
+ locker.unlock();
emit updateCompleted();
}
@@ -358,6 +370,7 @@ void QNativeWifiEngine::connectToId(const QString &id)
#ifdef BEARER_MANAGEMENT_DEBUG
qDebug("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
#endif
+ locker.unlock();
emit connectionError(id, InterfaceLookupError);
return;
}
@@ -405,7 +418,9 @@ void QNativeWifiEngine::connectToId(const QString &id)
#ifdef BEARER_MANAGEMENT_DEBUG
qDebug("%s: WlanConnect failed with error %ld\n", __FUNCTION__, result);
#endif
+ locker.unlock();
emit connectionError(id, ConnectError);
+ locker.relock();
break;
}
@@ -415,8 +430,10 @@ void QNativeWifiEngine::connectToId(const QString &id)
local_WlanFreeMemory(interfaceList);
- if (profile.isEmpty())
+ if (profile.isEmpty()) {
+ locker.unlock();
emit connectionError(id, InterfaceLookupError);
+ }
}
void QNativeWifiEngine::disconnectFromId(const QString &id)
@@ -426,6 +443,7 @@ void QNativeWifiEngine::disconnectFromId(const QString &id)
QString interface = getInterfaceFromId(id);
if (interface.isEmpty()) {
+ locker.unlock();
emit connectionError(id, InterfaceLookupError);
return;
}
@@ -446,6 +464,7 @@ void QNativeWifiEngine::disconnectFromId(const QString &id)
#ifdef BEARER_MANAGEMENT_DEBUG
qDebug("%s: WlanDisconnect failed with error %ld\n", __FUNCTION__, result);
#endif
+ locker.unlock();
emit connectionError(id, DisconnectionError);
return;
}
diff --git a/src/plugins/bearer/nativewifi/qnativewifiengine.h b/src/plugins/bearer/nativewifi/qnativewifiengine.h
index 56489b6..2005b2b 100644
--- a/src/plugins/bearer/nativewifi/qnativewifiengine.h
+++ b/src/plugins/bearer/nativewifi/qnativewifiengine.h
@@ -78,7 +78,7 @@ public:
void connectToId(const QString &id);
void disconnectFromId(const QString &id);
- void requestUpdate();
+ Q_INVOKABLE void requestUpdate();
QNetworkSession::State sessionStateForId(const QString &id);
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
index 0fa8f3c..d7e315a 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp
@@ -297,10 +297,17 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path,
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
if (ptr) {
+ ptr->mutex.lock();
if (activeConnection->state() == 2 &&
ptr->state != QNetworkConfiguration::Active) {
ptr->state = QNetworkConfiguration::Active;
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+ } else {
+ ptr->mutex.unlock();
}
}
}
@@ -313,9 +320,16 @@ void QNetworkManagerEngine::interfacePropertiesChanged(const QString &path,
QNetworkConfigurationPrivatePointer ptr =
accessPointConfigurations.value(identifiers.takeFirst());
+ ptr->mutex.lock();
if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
ptr->state = QNetworkConfiguration::Discovered;
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+ } else {
+ ptr->mutex.unlock();
}
}
}
@@ -339,10 +353,17 @@ void QNetworkManagerEngine::activeConnectionPropertiesChanged(const QString &pat
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
if (ptr) {
+ ptr->mutex.lock();
if (activeConnection->state() == 2 &&
ptr->state != QNetworkConfiguration::Active) {
ptr->state = QNetworkConfiguration::Active;
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+ } else {
+ ptr->mutex.unlock();
}
}
}
@@ -424,6 +445,8 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path,
QNetworkConfigurationPrivatePointer ptr(cpPriv);
accessPointConfigurations.insert(ptr->id, ptr);
+
+ locker.unlock();
emit configurationAdded(ptr);
}
@@ -444,7 +467,8 @@ void QNetworkManagerEngine::removeConnection(const QString &path)
connection->connectionInterface()->path()));
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(id);
- ptr->isValid = false;
+
+ locker.unlock();
emit configurationRemoved(ptr);
}
@@ -476,11 +500,16 @@ void QNetworkManagerEngine::updateConnection(const QNmSettingsMap &settings)
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(cpPriv->id);
+ ptr->mutex.lock();
+
ptr->isValid = cpPriv->isValid;
ptr->name = cpPriv->name;
ptr->id = cpPriv->id;
ptr->state = cpPriv->state;
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
delete cpPriv;
}
@@ -500,10 +529,17 @@ void QNetworkManagerEngine::activationFinished(QDBusPendingCallWatcher *watcher)
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
if (ptr) {
+ ptr->mutex.lock();
if (activeConnection.state() == 2 &&
ptr->state != QNetworkConfiguration::Active) {
ptr->state = QNetworkConfiguration::Active;
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+ } else {
+ ptr->mutex.unlock();
}
}
}
@@ -543,7 +579,11 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjec
QNetworkConfigurationPrivatePointer ptr =
accessPointConfigurations.value(connectionId);
+ ptr->mutex.lock();
ptr->state = QNetworkConfiguration::Discovered;
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
return;
}
@@ -562,6 +602,8 @@ void QNetworkManagerEngine::newAccessPoint(const QString &path, const QDBusObjec
ptr->bearer = QLatin1String("WLAN");
accessPointConfigurations.insert(ptr->id, ptr);
+
+ locker.unlock();
emit configurationAdded(ptr);
}
@@ -592,7 +634,11 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path,
QNetworkConfigurationPrivatePointer ptr =
accessPointConfigurations.value(connectionId);
+ ptr->mutex.lock();
ptr->state = QNetworkConfiguration::Defined;
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
return;
}
@@ -601,8 +647,11 @@ void QNetworkManagerEngine::removeAccessPoint(const QString &path,
QNetworkConfigurationPrivatePointer ptr =
accessPointConfigurations.take(QString::number(qHash(objectPath.path())));
- if (ptr)
+ if (ptr) {
+ locker.unlock();
emit configurationRemoved(ptr);
+ locker.relock();
+ }
}
delete accessPoint;
@@ -633,7 +682,11 @@ void QNetworkManagerEngine::updateAccessPoint(const QMap<QString, QVariant> &map
QNetworkConfigurationPrivatePointer ptr =
accessPointConfigurations.value(connectionId);
+ ptr->mutex.lock();
ptr->state = QNetworkConfiguration::Discovered;
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
return;
}
@@ -687,7 +740,10 @@ QNetworkConfigurationPrivate *QNetworkManagerEngine::parseConnection(const QStri
QString::number(qHash(accessPoints.at(i)->connectionInterface()->path()));
QNetworkConfigurationPrivatePointer ptr =
accessPointConfigurations.take(accessPointId);
+
+ locker.unlock();
emit configurationRemoved(ptr);
+ locker.relock();
}
break;
}
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
index ca1f857..05a1429 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.h
@@ -80,7 +80,7 @@ public:
void connectToId(const QString &id);
void disconnectFromId(const QString &id);
- void requestUpdate();
+ Q_INVOKABLE void requestUpdate();
QNetworkSession::State sessionStateForId(const QString &id);
diff --git a/src/plugins/bearer/nla/qnlaengine.cpp b/src/plugins/bearer/nla/qnlaengine.cpp
index 334eb14..9ab9924 100644
--- a/src/plugins/bearer/nla/qnlaengine.cpp
+++ b/src/plugins/bearer/nla/qnlaengine.cpp
@@ -522,6 +522,8 @@ void QNlaEngine::networksChanged()
bool changed = false;
+ ptr->mutex.lock();
+
if (ptr->isValid != cpPriv->isValid) {
ptr->isValid = cpPriv->isValid;
changed = true;
@@ -537,8 +539,13 @@ void QNlaEngine::networksChanged()
changed = true;
}
- if (changed)
+ ptr->mutex.unlock();
+
+ if (changed) {
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+ }
delete cpPriv;
} else {
@@ -546,7 +553,9 @@ void QNlaEngine::networksChanged()
accessPointConfigurations.insert(ptr->id, ptr);
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
}
}
@@ -554,9 +563,12 @@ void QNlaEngine::networksChanged()
QNetworkConfigurationPrivatePointer ptr =
accessPointConfigurations.take(previous.takeFirst());
+ locker.unlock();
emit configurationRemoved(ptr);
+ locker.relock();
}
+ locker.unlock();
emit updateCompleted();
}
diff --git a/src/plugins/bearer/nla/qnlaengine.h b/src/plugins/bearer/nla/qnlaengine.h
index 14c5201..1d49464 100644
--- a/src/plugins/bearer/nla/qnlaengine.h
+++ b/src/plugins/bearer/nla/qnlaengine.h
@@ -90,7 +90,7 @@ public:
void connectToId(const QString &id);
void disconnectFromId(const QString &id);
- void requestUpdate();
+ Q_INVOKABLE void requestUpdate();
QNetworkSession::State sessionStateForId(const QString &id);
diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
index bec562d..0737942 100644
--- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp
+++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp
@@ -100,7 +100,7 @@ QNetworkSessionPrivateImpl::~QNetworkSessionPrivateImpl()
void QNetworkSessionPrivateImpl::syncStateWithInterface()
{
- if (!privateConfiguration(publicConfig))
+ if (!publicConfig.isValid())
return;
// Start monitoring changes in IAP states
@@ -143,9 +143,8 @@ void QNetworkSessionPrivateImpl::syncStateWithInterface()
// There were no open connections to used IAP or SNAP
if (iError == QNetworkSession::InvalidConfigurationError) {
newState(QNetworkSession::Invalid);
- }
- else if ((privateConfiguration(publicConfig)->state & QNetworkConfiguration::Discovered) ==
- QNetworkConfiguration::Discovered) {
+ } else if ((publicConfig.state() & QNetworkConfiguration::Discovered) ==
+ QNetworkConfiguration::Discovered) {
newState(QNetworkSession::Disconnected);
} else {
newState(QNetworkSession::NotAvailable);
@@ -293,10 +292,15 @@ void QNetworkSessionPrivateImpl::open()
for (TUint i=1; i<=count; i++) {
// Note: GetConnectionInfo expects 1-based index.
if (iConnection.GetConnectionInfo(i, connInfo) == KErrNone) {
- if (connInfo().iIapId == toSymbianConfig(privateConfiguration(publicConfig))->numericId) {
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(publicConfig));
+
+ QMutexLocker configLocker(&symbianConfig->mutex);
+
+ if (connInfo().iIapId == symbianConfig->numericId) {
if (iConnection.Attach(connInfo, RConnection::EAttachTypeNormal) == KErrNone) {
activeConfig = publicConfig;
- activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId);
+ activeInterface = interface(symbianConfig->numericId);
connected = ETrue;
startTime = QDateTime::currentDateTime();
if (iDynamicSetdefaultif) {
@@ -320,7 +324,12 @@ void QNetworkSessionPrivateImpl::open()
if (!connected) {
TCommDbConnPref pref;
pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
- pref.SetIapId(toSymbianConfig(privateConfiguration(publicConfig))->numericId);
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(publicConfig));
+
+ symbianConfig->mutex.lock();
+ pref.SetIapId(symbianConfig->numericId);
+ symbianConfig->mutex.unlock();
iConnection.Start(pref, iStatus);
if (!IsActive()) {
SetActive();
@@ -328,7 +337,12 @@ void QNetworkSessionPrivateImpl::open()
newState(QNetworkSession::Connecting);
}
} else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
- TConnSnapPref snapPref(toSymbianConfig(privateConfiguration(publicConfig))->numericId);
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(publicConfig));
+
+ symbianConfig->mutex.lock();
+ TConnSnapPref snapPref(symbianConfig->numericId);
+ symbianConfig->mutex.unlock();
iConnection.Start(snapPref, iStatus);
if (!IsActive()) {
SetActive();
@@ -387,7 +401,13 @@ void QNetworkSessionPrivateImpl::close(bool allowSignals)
return;
}
- TUint activeIap = toSymbianConfig(privateConfiguration(activeConfig))->numericId;
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(activeConfig));
+
+ symbianConfig->mutex.lock();
+ TUint activeIap = symbianConfig->numericId;
+ symbianConfig->mutex.unlock();
+
isOpen = false;
activeConfig = QNetworkConfiguration();
serviceConfig = QNetworkConfiguration();
@@ -501,7 +521,13 @@ void QNetworkSessionPrivateImpl::PreferredCarrierAvailable(TAccessPointInfo aOld
iALRUpgradingConnection = aIsUpgrade;
QList<QNetworkConfiguration> configs = publicConfig.children();
for (int i=0; i < configs.count(); i++) {
- if (toSymbianConfig(privateConfiguration(configs[i]))->numericId == aNewAPInfo.AccessPoint()) {
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(configs[i]));
+
+ QMutexLocker configLocker(&symbianConfig->mutex);
+
+ if (symbianConfig->numericId == aNewAPInfo.AccessPoint()) {
+ configLocker.unlock();
emit preferredConfigurationChanged(configs[i], aIsSeamless);
}
}
@@ -625,13 +651,24 @@ quint64 QNetworkSessionPrivateImpl::transferredData(TUint dataType) const
if (config.type() == QNetworkConfiguration::ServiceNetwork) {
QList<QNetworkConfiguration> configs = config.children();
for (int i=0; i < configs.count(); i++) {
- if (toSymbianConfig(privateConfiguration(configs[i]))->numericId == apId) {
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(configs[i]));
+
+ QMutexLocker configLocker(&symbianConfig->mutex);
+
+ if (symbianConfig->numericId == apId) {
configFound = true;
break;
}
}
- } else if (toSymbianConfig(privateConfiguration(config))->numericId == apId) {
- configFound = true;
+ } else {
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(config));
+
+ symbianConfig->mutex.lock();
+ if (symbianConfig->numericId == apId)
+ configFound = true;
+ symbianConfig->mutex.unlock();
}
if (configFound) {
TUint tData;
@@ -668,9 +705,12 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia
// Try to search IAP from the used SNAP using IAP Id
QList<QNetworkConfiguration> children = publicConfig.children();
for (int i=0; i < children.count(); i++) {
- if (toSymbianConfig(privateConfiguration(children[i]))->numericId == iapId) {
+ SymbianNetworkConfigurationPrivate *childConfig =
+ toSymbianConfig(privateConfiguration(children[i]));
+
+ QMutexLocker childLocker(&childConfig->mutex);
+ if (childConfig->numericId == iapId)
return children[i];
- }
}
// Given IAP Id was not found from the used SNAP
@@ -682,10 +722,21 @@ QNetworkConfiguration QNetworkSessionPrivateImpl::activeConfiguration(TUint32 ia
// <=> Note: It's possible that in this case reported IAP is
// clone of the one of the IAPs of the used SNAP
// => If mappingName matches, clone has been found
- QNetworkConfiguration pt = QNetworkConfigurationManager().configurationFromIdentifier(QString::number(qHash(iapId)));
- if (privateConfiguration(pt)) {
+ QNetworkConfiguration pt = QNetworkConfigurationManager()
+ .configurationFromIdentifier(QString::number(qHash(iapId)));
+
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(pt));
+ if (symbianConfig) {
+ QMutexLocker configLocker(&symbianConfig->mutex);
+
for (int i=0; i < children.count(); i++) {
- if (toSymbianConfig(privateConfiguration(children[i]))->mappingName == toSymbianConfig(privateConfiguration(pt))->mappingName) {
+ SymbianNetworkConfigurationPrivate *childConfig =
+ toSymbianConfig(privateConfiguration(children[i]));
+
+ QMutexLocker childLocker(&childConfig->mutex);
+
+ if (childConfig->mappingName == symbianConfig->mappingName) {
return children[i];
}
}
@@ -776,13 +827,21 @@ void QNetworkSessionPrivateImpl::RunL()
iMobility = CActiveCommsMobilityApiExt::NewL(iConnection, *this);
}
#endif
+
isOpen = true;
activeConfig = newActiveConfig;
- activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId);
+
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(activeConfig));
+
+ symbianConfig->mutex.lock();
+ activeInterface = interface(symbianConfig->numericId);
if (publicConfig.type() == QNetworkConfiguration::UserChoice) {
- serviceConfig = QNetworkConfigurationManager().configurationFromIdentifier(toSymbianConfig(privateConfiguration(activeConfig))->serviceNetworkPtr->id);
+ serviceConfig = QNetworkConfigurationManager()
+ .configurationFromIdentifier(symbianConfig->serviceNetworkPtr->id);
}
-
+ symbianConfig->mutex.unlock();
+
startTime = QDateTime::currentDateTime();
newState(QNetworkSession::Connected);
@@ -830,7 +889,14 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
if (isOpen && publicConfig.type() == QNetworkConfiguration::ServiceNetwork &&
newState == QNetworkSession::Connected) {
activeConfig = activeConfiguration(accessPointId);
- activeInterface = interface(toSymbianConfig(privateConfiguration(activeConfig))->numericId);
+
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(activeConfig));
+
+ symbianConfig->mutex.lock();
+ activeInterface = interface(symbianConfig->numericId);
+ symbianConfig->mutex.unlock();
+
#ifdef SNAP_FUNCTIONALITY_AVAILABLE
if (iDynamicSetdefaultif) {
// Use name of the IAP to set default IAP
@@ -880,13 +946,25 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
retVal = true;
} else {
if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- if (toSymbianConfig(privateConfiguration(publicConfig))->numericId == accessPointId) {
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(publicConfig));
+
+ QMutexLocker configLocker(&symbianConfig->mutex);
+ if (symbianConfig->numericId == accessPointId) {
+ configLocker.unlock();
+
state = newState;
emit stateChanged(state);
retVal = true;
}
} else if (publicConfig.type() == QNetworkConfiguration::UserChoice && isOpen) {
- if (toSymbianConfig(privateConfiguration(activeConfig))->numericId == accessPointId) {
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(activeConfig));
+
+ QMutexLocker configLocker(&symbianConfig->mutex);
+ if (symbianConfig->numericId == accessPointId) {
+ configLocker.unlock();
+
state = newState;
emit stateChanged(state);
retVal = true;
@@ -894,11 +972,17 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
} else if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
for (int i = 0; i < subConfigurations.count(); i++) {
- if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId == accessPointId) {
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(subConfigurations[i]));
+
+ QMutexLocker configLocker(&symbianConfig->mutex);
+
+ if (symbianConfig->numericId == accessPointId) {
if (newState == QNetworkSession::Connected) {
// Make sure that when AccessPoint is reported to be Connected
// also state of the related configuration changes to Active.
- privateConfiguration(subConfigurations[i])->state = QNetworkConfiguration::Active;
+ symbianConfig->state = QNetworkConfiguration::Active;
+ configLocker.unlock();
state = newState;
emit stateChanged(state);
@@ -907,11 +991,14 @@ bool QNetworkSessionPrivateImpl::newState(QNetworkSession::State newState, TUint
if (newState == QNetworkSession::Disconnected) {
// Make sure that when AccessPoint is reported to be disconnected
// also state of the related configuration changes from Active to Defined.
- privateConfiguration(subConfigurations[i])->state = QNetworkConfiguration::Defined;
+ symbianConfig->state = QNetworkConfiguration::Defined;
}
QNetworkConfiguration config = bestConfigFromSNAP(publicConfig);
if ((config.state() == QNetworkConfiguration::Defined) ||
(config.state() == QNetworkConfiguration::Discovered)) {
+
+ configLocker.unlock();
+
state = newState;
emit stateChanged(state);
retVal = true;
@@ -1033,15 +1120,24 @@ void QNetworkSessionPrivateImpl::EventL(const CConnMonEventBase& aEvent)
if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
for (int i = 0; i < subConfigurations.count(); i++ ) {
- if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId == connectionId) {
- apId = toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId;
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(subConfigurations[i]));
+
+ QMutexLocker configLocker(&symbianConfig->mutex);
+
+ if (symbianConfig->connectionId == connectionId) {
+ apId = symbianConfig->numericId;
break;
}
}
} else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- if (toSymbianConfig(privateConfiguration(publicConfig))->connectionId == connectionId) {
- apId = toSymbianConfig(privateConfiguration(publicConfig))->numericId;
- }
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(publicConfig));
+
+ symbianConfig->mutex.lock();
+ if (symbianConfig->connectionId == connectionId)
+ apId = symbianConfig->numericId;
+ symbianConfig->mutex.unlock();
}
if (apId > 0) {
@@ -1064,15 +1160,24 @@ void QNetworkSessionPrivateImpl::EventL(const CConnMonEventBase& aEvent)
if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
for (int i = 0; i < subConfigurations.count(); i++ ) {
- if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->numericId == apId) {
- toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId = connectionId;
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(subConfigurations[i]));
+
+ QMutexLocker configLocker(&symbianConfig->mutex);
+
+ if (symbianConfig->numericId == apId) {
+ symbianConfig->connectionId = connectionId;
break;
}
}
} else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- if (toSymbianConfig(privateConfiguration(publicConfig))->numericId == apId) {
- toSymbianConfig(privateConfiguration(publicConfig))->connectionId = connectionId;
- }
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(publicConfig));
+
+ symbianConfig->mutex.lock();
+ if (symbianConfig->numericId == apId)
+ symbianConfig->connectionId = connectionId;
+ symbianConfig->mutex.unlock();
}
}
}
@@ -1087,15 +1192,24 @@ void QNetworkSessionPrivateImpl::EventL(const CConnMonEventBase& aEvent)
if (publicConfig.type() == QNetworkConfiguration::ServiceNetwork) {
QList<QNetworkConfiguration> subConfigurations = publicConfig.children();
for (int i = 0; i < subConfigurations.count(); i++ ) {
- if (toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId == connectionId) {
- toSymbianConfig(privateConfiguration(subConfigurations[i]))->connectionId = 0;
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(subConfigurations[i]));
+
+ QMutexLocker configLocker(&symbianConfig->mutex);
+
+ if (symbianConfig->connectionId == connectionId) {
+ symbianConfig->connectionId = 0;
break;
}
}
} else if (publicConfig.type() == QNetworkConfiguration::InternetAccessPoint) {
- if (toSymbianConfig(privateConfiguration(publicConfig))->connectionId == connectionId) {
- toSymbianConfig(privateConfiguration(publicConfig))->connectionId = 0;
- }
+ SymbianNetworkConfigurationPrivate *symbianConfig =
+ toSymbianConfig(privateConfiguration(publicConfig));
+
+ symbianConfig->mutex.lock();
+ if (symbianConfig->connectionId == connectionId)
+ symbianConfig->connectionId = 0;
+ symbianConfig->mutex.unlock();
}
}
break;
diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp
index 88a563c..980892a 100644
--- a/src/plugins/bearer/symbian/symbianengine.cpp
+++ b/src/plugins/bearer/symbian/symbianengine.cpp
@@ -75,6 +75,8 @@ SymbianNetworkConfigurationPrivate::~SymbianNetworkConfigurationPrivate()
QString SymbianNetworkConfigurationPrivate::bearerName() const
{
+ QMutexLocker locker(&mutex);
+
switch (bearer) {
case BearerEthernet:
return QLatin1String("Ethernet");
@@ -250,7 +252,10 @@ void SymbianEngine::updateConfigurationsL()
if (error == KErrNone) {
QNetworkConfigurationPrivatePointer ptr(cpPriv);
accessPointConfigurations.insert(ptr->id, ptr);
+
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
}
}
CleanupStack::PopAndDestroy(&connectionMethod);
@@ -288,7 +293,10 @@ void SymbianEngine::updateConfigurationsL()
QNetworkConfigurationPrivatePointer ptr(cpPriv);
snapConfigurations.insert(ident, ptr);
+
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
CleanupStack::Pop(cpPriv);
}
@@ -309,7 +317,11 @@ void SymbianEngine::updateConfigurationsL()
QNetworkConfigurationPrivatePointer ptr(cpPriv);
toSymbianConfig(ptr)->serviceNetworkPtr = privSNAP;
accessPointConfigurations.insert(ptr->id, ptr);
+
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
+
privSNAP->serviceNetworkMembers.append(ptr);
}
} else {
@@ -358,7 +370,9 @@ void SymbianEngine::updateConfigurationsL()
QNetworkConfigurationPrivatePointer ptr(cpPriv);
accessPointConfigurations.insert(ident, ptr);
+ locker.unlock();
emit configurationAdded(ptr);
+ locker.relock();
} else {
delete cpPriv;
}
@@ -372,7 +386,10 @@ void SymbianEngine::updateConfigurationsL()
foreach (const QString &oldIface, knownConfigs) {
//remove non existing IAP
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface);
+
+ locker.unlock();
emit configurationRemoved(ptr);
+ locker.relock();
// Remove non existing IAP from SNAPs
foreach (const QString &iface, snapConfigurations.keys()) {
@@ -391,7 +408,10 @@ void SymbianEngine::updateConfigurationsL()
foreach (const QString &oldIface, knownSnapConfigs) {
//remove non existing SNAPs
QNetworkConfigurationPrivatePointer ptr = snapConfigurations.take(oldIface);
+
+ locker.unlock();
emit configurationRemoved(ptr);
+ locker.relock();
}
}
@@ -596,7 +616,7 @@ QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfigurationL()
}
#endif
- if (!ptr->isValid) {
+ if (!ptr || !ptr->isValid) {
QString iface = QString::number(qHash(KUserChoiceIAPId));
ptr = userChoiceConfigurations.value(iface);
}
@@ -651,7 +671,9 @@ void SymbianEngine::updateActiveAccessPoints()
if (iOnline != online) {
iOnline = online;
+ locker.unlock();
emit this->onlineStateChanged(iOnline);
+ locker.relock();
}
}
@@ -704,7 +726,9 @@ void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapIn
if (!iFirstUpdate) {
startCommsDatabaseNotifications();
+ locker.unlock();
emit updateCompleted();
+ locker.relock();
}
}
@@ -746,10 +770,18 @@ bool SymbianEngine::changeConfigurationStateTo(QNetworkConfigurationPrivatePoint
{
QMutexLocker locker(&mutex);
+ ptr->mutex.lock();
if (newState != ptr->state) {
ptr->state = newState;
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+
return true;
+ } else {
+ ptr->mutex.unlock();
}
return false;
}
@@ -763,10 +795,18 @@ bool SymbianEngine::changeConfigurationStateAtMinTo(QNetworkConfigurationPrivate
{
QMutexLocker locker(&mutex);
+ ptr->mutex.lock();
if ((newState | ptr->state) != ptr->state) {
ptr->state = (ptr->state | newState);
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+
return true;
+ } else {
+ ptr->mutex.unlock();
}
return false;
}
@@ -781,10 +821,18 @@ bool SymbianEngine::changeConfigurationStateAtMaxTo(QNetworkConfigurationPrivate
{
QMutexLocker locker(&mutex);
+ ptr->mutex.lock();
if ((newState & ptr->state) != ptr->state) {
ptr->state = (newState & ptr->state);
+ ptr->mutex.unlock();
+
+ locker.unlock();
emit configurationChanged(ptr);
+ locker.relock();
+
return true;
+ } else {
+ ptr->mutex.unlock();
}
return false;
}
@@ -893,7 +941,10 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
if (!iOnline) {
iOnline = true;
+
+ locker.unlock();
emit this->onlineStateChanged(iOnline);
+ locker.relock();
}
}
}
@@ -923,7 +974,10 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent)
}
if (iOnline != online) {
iOnline = online;
+
+ locker.unlock();
emit this->onlineStateChanged(iOnline);
+ locker.relock();
}
}
break;
diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h
index ee6d070..e6af908 100644
--- a/src/plugins/bearer/symbian/symbianengine.h
+++ b/src/plugins/bearer/symbian/symbianengine.h
@@ -109,7 +109,7 @@ public:
bool hasIdentifier(const QString &id);
- void requestUpdate();
+ Q_INVOKABLE void requestUpdate();
QNetworkConfigurationManager::Capabilities capabilities() const;
diff --git a/src/script/api/qscriptcontextinfo.cpp b/src/script/api/qscriptcontextinfo.cpp
index cc5fcc1..ebb1770 100644
--- a/src/script/api/qscriptcontextinfo.cpp
+++ b/src/script/api/qscriptcontextinfo.cpp
@@ -181,7 +181,7 @@ QScriptContextInfoPrivate::QScriptContextInfoPrivate(const QScriptContext *conte
// Get the others informations:
JSC::JSObject *callee = frame->callee();
if (callee && callee->inherits(&JSC::InternalFunction::info))
- functionName = JSC::asInternalFunction(callee)->name(&frame->globalData());
+ functionName = JSC::asInternalFunction(callee)->name(frame);
if (callee && callee->inherits(&JSC::JSFunction::info)) {
functionType = QScriptContextInfo::ScriptFunction;
JSC::FunctionExecutable *body = JSC::asFunction(callee)->jsExecutable();
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 024b4d0..294c3a0 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -898,6 +898,8 @@ QScriptEnginePrivate::QScriptEnginePrivate()
QScriptEnginePrivate::~QScriptEnginePrivate()
{
+ JSC::setCurrentIdentifierTable(globalData->identifierTable);
+
//disconnect all loadedScripts and generate all jsc::debugger::scriptUnload events
QHash<intptr_t,QScript::UStringSourceProviderWithFeedback*>::const_iterator it;
for (it = loadedScripts.constBegin(); it != loadedScripts.constEnd(); ++it)
@@ -988,8 +990,7 @@ JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, co
QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSValue obj)
{
JSC::PropertyNameArray propertyNames(exec);
- propertyNames.setShouldCache(false);
- JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, /*includeNonEnumerable=*/true);
+ JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties);
QVariantMap vmap;
JSC::PropertyNameArray::const_iterator it = propertyNames.begin();
for( ; it != propertyNames.end(); ++it)
@@ -1187,7 +1188,8 @@ bool QScriptEnginePrivate::isCollecting() const
void QScriptEnginePrivate::collectGarbage()
{
JSC::JSLock lock(false);
- globalData->heap.collect();
+ QScript::APIShim shim(this);
+ globalData->heap.collectAllGarbage();
}
QScript::TimeoutCheckerProxy *QScriptEnginePrivate::timeoutChecker() const
@@ -1218,7 +1220,7 @@ JSC::JSValue QScriptEnginePrivate::evaluateHelper(JSC::ExecState *exec, intptr_t
debugger->evaluateStart(sourceId);
q->clearExceptions();
- JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject());
+ JSC::DynamicGlobalObjectScope dynamicGlobalObjectScope(exec, exec->scopeChain()->globalObject);
if (compile) {
JSC::JSObject* error = executable->compile(exec, exec->scopeChain());
@@ -1670,15 +1672,15 @@ void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue object
// deleting getter/setter
if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) {
// deleting both: just delete the property
- thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
+ thisObject->deleteProperty(exec, id);
} else if (flags & QScriptValue::PropertyGetter) {
// preserve setter, if there is one
- thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
+ thisObject->deleteProperty(exec, id);
if (setter && setter.isObject())
thisObject->defineSetter(exec, id, JSC::asObject(setter));
} else { // flags & QScriptValue::PropertySetter
// preserve getter, if there is one
- thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
+ thisObject->deleteProperty(exec, id);
if (getter && getter.isObject())
thisObject->defineGetter(exec, id, JSC::asObject(getter));
}
@@ -1708,10 +1710,10 @@ void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue object
}
if (!value) {
// ### check if it's a getter/setter property
- thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
+ thisObject->deleteProperty(exec, id);
} else if (flags != QScriptValue::KeepExistingFlags) {
if (thisObject->hasOwnProperty(exec, id))
- thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); // ### hmmm - can't we just update the attributes?
+ thisObject->deleteProperty(exec, id); // ### hmmm - can't we just update the attributes?
unsigned attribs = 0;
if (flags & QScriptValue::ReadOnly)
attribs |= JSC::ReadOnly;
@@ -1732,7 +1734,7 @@ void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue object
JSC::JSValue value, const QScriptValue::PropertyFlags &flags)
{
if (!value) {
- JSC::asObject(objectValue)->deleteProperty(exec, index, /*checkDontDelete=*/false);
+ JSC::asObject(objectValue)->deleteProperty(exec, index);
} else {
if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
// fall back to string-based setProperty(), since there is no
@@ -1766,7 +1768,7 @@ QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *
JSC::PropertyDescriptor descriptor;
if (object->getOwnPropertyDescriptor(exec, id, descriptor))
attribs = descriptor.attributes();
- else if (!object->getPropertyAttributes(exec, id, attribs)) {
+ else {
if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) {
JSC::JSValue proto = object->prototype();
return propertyFlags(exec, proto, id, mode);
@@ -1793,6 +1795,15 @@ QScriptValue::PropertyFlags QScriptEnginePrivate::propertyFlags(JSC::ExecState *
return result;
}
+QScriptString QScriptEnginePrivate::toStringHandle(const JSC::Identifier &name)
+{
+ QScriptString result;
+ QScriptStringPrivate *p = new QScriptStringPrivate(this, name, QScriptStringPrivate::HeapAllocated);
+ QScriptStringPrivate::init(result, p);
+ registerScriptString(p);
+ return result;
+}
+
#ifdef QT_NO_QOBJECT
QScriptEngine::QScriptEngine()
@@ -2466,15 +2477,16 @@ QScriptSyntaxCheckResult QScriptEnginePrivate::checkSyntax(const QString &progra
QScriptValue QScriptEngine::evaluate(const QString &program, const QString &fileName, int lineNumber)
{
Q_D(QScriptEngine);
+ QScript::APIShim shim(d);
WTF::PassRefPtr<QScript::UStringSourceProviderWithFeedback> provider
= QScript::UStringSourceProviderWithFeedback::create(program, fileName, lineNumber, d);
intptr_t sourceId = provider->asID();
JSC::SourceCode source(provider, lineNumber); //after construction of SourceCode provider variable will be null.
JSC::ExecState* exec = d->currentFrame;
- JSC::EvalExecutable executable(exec, source);
+ WTF::RefPtr<JSC::EvalExecutable> executable = JSC::EvalExecutable::create(exec, source);
bool compile = true;
- return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, &executable, compile));
+ return d->scriptValueFromJSCValue(d->evaluateHelper(exec, sourceId, executable.get(), compile));
}
/*!
@@ -2491,6 +2503,7 @@ QScriptValue QScriptEngine::evaluate(const QScriptProgram &program)
if (!program_d)
return QScriptValue();
+ QScript::APIShim shim(d);
JSC::ExecState* exec = d->currentFrame;
JSC::EvalExecutable *executable = program_d->executable(exec, d);
bool compile = !program_d->isCompiled;
@@ -2603,7 +2616,7 @@ JSC::CallFrame *QScriptEnginePrivate::pushContext(JSC::CallFrame *exec, JSC::JSV
newCallFrame->init(0, /*vPC=*/0, exec->scopeChain(), exec, flags | ShouldRestoreCallFrame, argc, callee);
} else {
JSC::JSObject *jscObject = originalGlobalObject();
- JSC::ScopeChainNode *scn = new JSC::ScopeChainNode(0, jscObject, &exec->globalData(), jscObject);
+ JSC::ScopeChainNode *scn = new JSC::ScopeChainNode(0, jscObject, &exec->globalData(), exec->lexicalGlobalObject(), jscObject);
newCallFrame->init(0, /*vPC=*/0, scn, exec, flags | ShouldRestoreCallFrame, argc, callee);
}
} else {
@@ -2935,7 +2948,7 @@ JSC::JSValue QScriptEnginePrivate::create(JSC::ExecState *exec, int type, const
}
}
if (result && result.isObject() && info && info->prototype
- && JSC::JSValue::strictEqual(JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) {
+ && JSC::JSValue::strictEqual(exec, JSC::asObject(result)->prototype(), eng->originalGlobalObject()->objectPrototype())) {
JSC::asObject(result)->setPrototype(info->prototype);
}
return result;
@@ -4050,11 +4063,8 @@ QScriptEngineAgent *QScriptEngine::agent() const
QScriptString QScriptEngine::toStringHandle(const QString &str)
{
Q_D(QScriptEngine);
- QScriptString result;
- QScriptStringPrivate *p = new QScriptStringPrivate(d, JSC::Identifier(d->currentFrame, str), QScriptStringPrivate::HeapAllocated);
- QScriptStringPrivate::init(result, p);
- d->registerScriptString(p);
- return result;
+ QScript::APIShim shim(d);
+ return d->toStringHandle(JSC::Identifier(d->currentFrame, str));
}
/*!
diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h
index 5166d89..47e5d8a 100644
--- a/src/script/api/qscriptengine_p.h
+++ b/src/script/api/qscriptengine_p.h
@@ -279,6 +279,7 @@ public:
inline void registerScriptString(QScriptStringPrivate *value);
inline void unregisterScriptString(QScriptStringPrivate *value);
void detachAllRegisteredScriptStrings();
+ QScriptString toStringHandle(const JSC::Identifier &name);
static inline JSC::JSValue newArray(JSC::ExecState *, uint length);
static inline JSC::JSValue newDate(JSC::ExecState *, qsreal value);
@@ -383,6 +384,23 @@ public:
namespace QScript
{
+class APIShim
+{
+public:
+ APIShim(QScriptEnginePrivate *engine)
+ : m_engine(engine), m_oldTable(JSC::setCurrentIdentifierTable(engine->globalData->identifierTable))
+ {
+ }
+ ~APIShim()
+ {
+ JSC::setCurrentIdentifierTable(m_oldTable);
+ }
+
+private:
+ QScriptEnginePrivate *m_engine;
+ JSC::IdentifierTable *m_oldTable;
+};
+
/*Helper class. Main purpose is to give debugger feedback about unloading and loading scripts.
It keeps pointer to JSGlobalObject assuming that it is always the same - there is no way to update
this data. Class is internal and used as an implementation detail in and only in QScriptEngine::evaluate.*/
@@ -685,17 +703,17 @@ inline void QScriptEnginePrivate::setProperty(JSC::ExecState *exec, JSC::JSValue
setProperty(exec, objectValue, JSC::Identifier(exec, name), value, flags);
}
-inline JSC::JSValue QScriptValuePrivate::property(const JSC::Identifier &id, int resolveMode) const
+inline JSC::JSValue QScriptValuePrivate::property(const JSC::Identifier &id, const QScriptValue::ResolveFlags &resolveMode) const
{
return QScriptEnginePrivate::property(engine->currentFrame, jscValue, id, resolveMode);
}
-inline JSC::JSValue QScriptValuePrivate::property(quint32 index, int resolveMode) const
+inline JSC::JSValue QScriptValuePrivate::property(quint32 index, const QScriptValue::ResolveFlags &resolveMode) const
{
return QScriptEnginePrivate::property(engine->currentFrame, jscValue, index, resolveMode);
}
-inline JSC::JSValue QScriptValuePrivate::property(const JSC::UString &name, int resolveMode) const
+inline JSC::JSValue QScriptValuePrivate::property(const JSC::UString &name, const QScriptValue::ResolveFlags &resolveMode) const
{
JSC::ExecState *exec = engine->currentFrame;
return QScriptEnginePrivate::property(exec, jscValue, JSC::Identifier(exec, name), resolveMode);
@@ -779,6 +797,7 @@ inline void QScriptEnginePrivate::unregisterScriptString(QScriptStringPrivate *v
registeredScriptStrings = value->next;
value->prev = 0;
value->next = 0;
+ JSC::setCurrentIdentifierTable(globalData->identifierTable);
}
inline QScriptContext *QScriptEnginePrivate::contextForFrame(JSC::ExecState *frame)
diff --git a/src/script/api/qscriptengineagent.cpp b/src/script/api/qscriptengineagent.cpp
index 3bd97eb..28905e8 100644
--- a/src/script/api/qscriptengineagent.cpp
+++ b/src/script/api/qscriptengineagent.cpp
@@ -151,14 +151,15 @@ void QScriptEngineAgentPrivate::exceptionCatch(const JSC::DebuggerCallFrame& fra
engine->clearCurrentException();
}
-void QScriptEngineAgentPrivate::atStatement(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, int column)
+void QScriptEngineAgentPrivate::atStatement(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno/*, int column*/)
{
QScript::UStringSourceProviderWithFeedback *source = engine->loadedScripts.value(sourceID);
if (!source) {
// QTBUG-6108: We don't have the source for this script, so ignore.
return;
}
- column = source->columnNumberFromOffset(column);
+// column = source->columnNumberFromOffset(column);
+ int column = 1;
JSC::CallFrame *oldFrame = engine->currentFrame;
int oldAgentLineNumber = engine->agentLineNumber;
engine->currentFrame = frame.callFrame();
@@ -182,7 +183,7 @@ void QScriptEngineAgentPrivate::evaluateStop(const JSC::JSValue& returnValue, in
}
void QScriptEngineAgentPrivate::didReachBreakpoint(const JSC::DebuggerCallFrame& frame,
- intptr_t sourceID, int lineno, int column)
+ intptr_t sourceID, int lineno/*, int column*/)
{
if (q_ptr->supportsExtension(QScriptEngineAgent::DebuggerInvocationRequest)) {
QScript::UStringSourceProviderWithFeedback *source = engine->loadedScripts.value(sourceID);
@@ -190,7 +191,8 @@ void QScriptEngineAgentPrivate::didReachBreakpoint(const JSC::DebuggerCallFrame&
// QTBUG-6108: We don't have the source for this script, so ignore.
return;
}
- column = source->columnNumberFromOffset(column);
+// column = source->columnNumberFromOffset(column);
+ int column = 1;
JSC::CallFrame *oldFrame = engine->currentFrame;
int oldAgentLineNumber = engine->agentLineNumber;
engine->currentFrame = frame.callFrame();
diff --git a/src/script/api/qscriptengineagent_p.h b/src/script/api/qscriptengineagent_p.h
index 8354143..fd10e68 100644
--- a/src/script/api/qscriptengineagent_p.h
+++ b/src/script/api/qscriptengineagent_p.h
@@ -75,17 +75,18 @@ public:
};
//exceptions
- virtual void exception(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno)
+ virtual void exception(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, bool hasHandler)
{
Q_UNUSED(frame);
Q_UNUSED(sourceID);
Q_UNUSED(lineno);
+ Q_UNUSED(hasHandler);
};
virtual void exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler);
virtual void exceptionCatch(const JSC::DebuggerCallFrame& frame, intptr_t sourceID);
//statements
- virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno, int column);
+ virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno/*, int column*/);
virtual void callEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno)
{
Q_UNUSED(lineno);
@@ -107,7 +108,7 @@ public:
};
virtual void functionExit(const JSC::JSValue& returnValue, intptr_t sourceID);
//others
- virtual void didReachBreakpoint(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, int column);
+ virtual void didReachBreakpoint(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno/*, int column*/);
virtual void evaluateStart(intptr_t sourceID)
{
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index 414a45c..a3af2d4 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -898,18 +898,21 @@ bool QScriptValue::strictlyEquals(const QScriptValue &other) const
if (d->type == QScriptValuePrivate::JavaScriptCore) {
QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine;
if (eng_p)
- return JSC::JSValue::strictEqual(d->jscValue, eng_p->scriptValueToJSCValue(other));
+ return JSC::JSValue::strictEqual(eng_p->currentFrame, d->jscValue, eng_p->scriptValueToJSCValue(other));
} else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) {
QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine;
if (eng_p)
- return JSC::JSValue::strictEqual(eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue);
+ return JSC::JSValue::strictEqual(eng_p->currentFrame, eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue);
}
return false;
}
switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore:
- return JSC::JSValue::strictEqual(d->jscValue, other.d_ptr->jscValue);
+ case QScriptValuePrivate::JavaScriptCore: {
+ QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine;
+ JSC::ExecState *exec = eng_p ? eng_p->currentFrame : 0;
+ return JSC::JSValue::strictEqual(exec, d->jscValue, other.d_ptr->jscValue);
+ }
case QScriptValuePrivate::Number:
return (d->numberValue == other.d_ptr->numberValue);
case QScriptValuePrivate::String:
@@ -1301,6 +1304,7 @@ void QScriptValue::setProperty(const QString &name, const QScriptValue &value,
Q_D(QScriptValue);
if (!d || !d->isObject())
return;
+ QScript::APIShim shim(d->engine);
QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value);
if (valueEngine && (valueEngine != d->engine)) {
qWarning("QScriptValue::setProperty(%s) failed: "
@@ -1333,6 +1337,7 @@ QScriptValue QScriptValue::property(const QString &name,
Q_D(const QScriptValue);
if (!d || !d->isObject())
return QScriptValue();
+ QScript::APIShim shim(d->engine);
return d->engine->scriptValueFromJSCValue(d->property(name, mode));
}
@@ -1450,6 +1455,7 @@ QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString &name,
Q_D(const QScriptValue);
if (!d || !d->isObject())
return 0;
+ QScript::APIShim shim(d->engine);
JSC::ExecState *exec = d->engine->currentFrame;
return d->propertyFlags(JSC::Identifier(exec, name), mode);
diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h
index 089b923..853c6c8 100644
--- a/src/script/api/qscriptvalue_p.h
+++ b/src/script/api/qscriptvalue_p.h
@@ -86,17 +86,18 @@ public:
return q.d_ptr->engine;
}
- inline JSC::JSValue property(const JSC::Identifier &id, int resolveMode) const;
- inline JSC::JSValue property(quint32 index, int resolveMode) const;
- inline JSC::JSValue property(const JSC::UString &, int resolveMode) const;
+ inline JSC::JSValue property(const JSC::Identifier &id,
+ const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const;
+ inline JSC::JSValue property(quint32 index, const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const;
+ inline JSC::JSValue property(const JSC::UString &, const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const;
inline void setProperty(const JSC::UString &name, const JSC::JSValue &value,
- const QScriptValue::PropertyFlags &flags);
+ const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
inline void setProperty(const JSC::Identifier &id, const JSC::JSValue &value,
- const QScriptValue::PropertyFlags &flags);
+ const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
inline void setProperty(quint32 index, const JSC::JSValue &value,
- const QScriptValue::PropertyFlags &flags);
+ const QScriptValue::PropertyFlags &flags = QScriptValue::KeepExistingFlags);
inline QScriptValue::PropertyFlags propertyFlags(
- const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const;
+ const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode = QScriptValue::ResolvePrototype) const;
void detachFromEngine();
diff --git a/src/script/api/qscriptvalueiterator.cpp b/src/script/api/qscriptvalueiterator.cpp
index 24d9754..5c1e6f2 100644
--- a/src/script/api/qscriptvalueiterator.cpp
+++ b/src/script/api/qscriptvalueiterator.cpp
@@ -84,28 +84,38 @@ public:
QScriptValueIteratorPrivate()
: initialized(false)
{}
+
+ QScriptValuePrivate *object() const
+ {
+ return QScriptValuePrivate::get(objectValue);
+ }
+
+ QScriptEnginePrivate *engine() const
+ {
+ return QScriptEnginePrivate::get(objectValue.engine());
+ }
+
void ensureInitialized()
{
if (initialized)
return;
- QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(object.engine());
+ QScriptEnginePrivate *eng_p = engine();
JSC::ExecState *exec = eng_p->globalExec();
JSC::PropertyNameArray propertyNamesArray(exec);
- propertyNamesArray.setShouldCache(false);
- JSC::asObject(QScriptValuePrivate::get(object)->jscValue)->getOwnPropertyNames(exec, propertyNamesArray, /*includeNonEnumerable=*/true);
+ JSC::asObject(object()->jscValue)->getOwnPropertyNames(exec, propertyNamesArray, JSC::IncludeDontEnumProperties);
JSC::PropertyNameArray::const_iterator propertyNamesIt = propertyNamesArray.begin();
for(; propertyNamesIt != propertyNamesArray.end(); ++propertyNamesIt) {
- propertyNames.append(propertyNamesIt->ustring());
+ propertyNames.append(*propertyNamesIt);
}
it = propertyNames.begin();
initialized = true;
}
- QScriptValue object;
- QLinkedList<JSC::UString> propertyNames;
- QLinkedList<JSC::UString>::iterator it;
- QLinkedList<JSC::UString>::iterator current;
+ QScriptValue objectValue;
+ QLinkedList<JSC::Identifier> propertyNames;
+ QLinkedList<JSC::Identifier>::iterator it;
+ QLinkedList<JSC::Identifier>::iterator current;
bool initialized;
};
@@ -119,7 +129,7 @@ QScriptValueIterator::QScriptValueIterator(const QScriptValue &object)
{
if (object.isObject()) {
d_ptr.reset(new QScriptValueIteratorPrivate());
- d_ptr->object = object;
+ d_ptr->objectValue = object;
}
}
@@ -240,9 +250,9 @@ void QScriptValueIterator::toBack()
QString QScriptValueIterator::name() const
{
Q_D(const QScriptValueIterator);
- if (!d || !d->initialized)
+ if (!d || !d->initialized || !d->engine())
return QString();
- return *d->current;
+ return d->current->ustring();
}
/*!
@@ -254,9 +264,9 @@ QString QScriptValueIterator::name() const
QScriptString QScriptValueIterator::scriptName() const
{
Q_D(const QScriptValueIterator);
- if (!d || !d->initialized)
+ if (!d || !d->initialized || !d->engine())
return QScriptString();
- return d->object.engine()->toStringHandle(name());
+ return d->engine()->toStringHandle(*d->current);
}
/*!
@@ -268,9 +278,10 @@ QScriptString QScriptValueIterator::scriptName() const
QScriptValue QScriptValueIterator::value() const
{
Q_D(const QScriptValueIterator);
- if (!d || !d->initialized)
+ if (!d || !d->initialized || !d->engine())
return QScriptValue();
- return d->object.property(name());
+ JSC::JSValue jsValue = d->object()->property(*d->current);
+ return d->engine()->scriptValueFromJSCValue(jsValue);
}
/*!
@@ -282,9 +293,10 @@ QScriptValue QScriptValueIterator::value() const
void QScriptValueIterator::setValue(const QScriptValue &value)
{
Q_D(QScriptValueIterator);
- if (!d || !d->initialized)
+ if (!d || !d->initialized || !d->engine())
return;
- d->object.setProperty(name(), value);
+ JSC::JSValue jsValue = d->engine()->scriptValueToJSCValue(value);
+ d->object()->setProperty(*d->current, jsValue);
}
/*!
@@ -296,9 +308,9 @@ void QScriptValueIterator::setValue(const QScriptValue &value)
QScriptValue::PropertyFlags QScriptValueIterator::flags() const
{
Q_D(const QScriptValueIterator);
- if (!d || !d->initialized)
+ if (!d || !d->initialized || !d->engine())
return 0;
- return d->object.propertyFlags(name());
+ return d->object()->propertyFlags(*d->current);
}
/*!
@@ -310,9 +322,9 @@ QScriptValue::PropertyFlags QScriptValueIterator::flags() const
void QScriptValueIterator::remove()
{
Q_D(QScriptValueIterator);
- if (!d || !d->initialized)
+ if (!d || !d->initialized || !d->engine())
return;
- d->object.setProperty(name(), QScriptValue());
+ d->object()->setProperty(*d->current, JSC::JSValue());
d->propertyNames.erase(d->current);
}
@@ -326,7 +338,7 @@ QScriptValueIterator& QScriptValueIterator::operator=(QScriptValue &object)
d_ptr.reset();
if (object.isObject()) {
d_ptr.reset(new QScriptValueIteratorPrivate());
- d_ptr->object = object;
+ d_ptr->objectValue = object;
}
return *this;
}
diff --git a/src/script/bridge/qscriptactivationobject.cpp b/src/script/bridge/qscriptactivationobject.cpp
index 7189f2e..6a8ae56 100644
--- a/src/script/bridge/qscriptactivationobject.cpp
+++ b/src/script/bridge/qscriptactivationobject.cpp
@@ -63,20 +63,20 @@ bool QScriptActivationObject::getOwnPropertySlot(JSC::ExecState* exec, const JSC
return JSC::JSVariableObject::getOwnPropertySlot(exec, propertyName, slot);
}
-bool QScriptActivationObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, unsigned& attributes) const
+bool QScriptActivationObject::getOwnPropertyDescriptor(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertyDescriptor& descriptor)
{
if (d_ptr()->delegate != 0)
- return d_ptr()->delegate->getPropertyAttributes(exec, propertyName, attributes);
- return JSC::JSVariableObject::getPropertyAttributes(exec, propertyName, attributes);
+ return d_ptr()->delegate->getOwnPropertyDescriptor(exec, propertyName, descriptor);
+ return JSC::JSVariableObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
-void QScriptActivationObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, bool includeNonEnumerable)
+void QScriptActivationObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, JSC::EnumerationMode mode)
{
if (d_ptr()->delegate != 0) {
- d_ptr()->delegate->getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
+ d_ptr()->delegate->getOwnPropertyNames(exec, propertyNames, mode);
return;
}
- return JSC::JSVariableObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
+ return JSC::JSVariableObject::getOwnPropertyNames(exec, propertyNames, mode);
}
void QScriptActivationObject::putWithAttributes(JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, unsigned attributes)
@@ -111,11 +111,11 @@ void QScriptActivationObject::put(JSC::ExecState* exec, unsigned propertyName, J
JSC::JSVariableObject::put(exec, propertyName, value);
}
-bool QScriptActivationObject::deleteProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName, bool checkDontDelete)
+bool QScriptActivationObject::deleteProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName)
{
if (d_ptr()->delegate != 0)
- return d_ptr()->delegate->deleteProperty(exec, propertyName, checkDontDelete);
- return JSC::JSVariableObject::deleteProperty(exec, propertyName, checkDontDelete);
+ return d_ptr()->delegate->deleteProperty(exec, propertyName);
+ return JSC::JSVariableObject::deleteProperty(exec, propertyName);
}
void QScriptActivationObject::defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction)
diff --git a/src/script/bridge/qscriptactivationobject_p.h b/src/script/bridge/qscriptactivationobject_p.h
index 7648a26..72ea11f 100644
--- a/src/script/bridge/qscriptactivationobject_p.h
+++ b/src/script/bridge/qscriptactivationobject_p.h
@@ -51,14 +51,14 @@ public:
virtual bool isDynamicScope() const { return true; }
virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
- virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned&) const;
- virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, bool includeNonEnumerable = false);
+ virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&);
+ virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
virtual void putWithAttributes(JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, unsigned attributes);
virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot&);
virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue value);
- virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName, bool checkDontDelete = true);
+ virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName);
virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction);
virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction);
diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp
index ce0a08e..a7b5f48 100644
--- a/src/script/bridge/qscriptclassobject.cpp
+++ b/src/script/bridge/qscriptclassobject.cpp
@@ -84,6 +84,47 @@ bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object,
return false;
}
+bool ClassObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object,
+ JSC::ExecState *exec,
+ const JSC::Identifier &propertyName,
+ JSC::PropertyDescriptor &descriptor)
+{
+ QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
+ QScript::SaveFrameHelper saveFrame(engine, exec);
+ // for compatibility with the old back-end, normal JS properties
+ // are queried first.
+ if (QScriptObjectDelegate::getOwnPropertyDescriptor(object, exec, propertyName, descriptor))
+ return true;
+
+ QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
+ QScriptString scriptName;
+ QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
+ QScriptStringPrivate::init(scriptName, &scriptName_d);
+ uint id = 0;
+ QScriptClass::QueryFlags qflags = m_scriptClass->queryProperty(
+ scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id);
+ if (qflags & QScriptClass::HandlesReadAccess) {
+ QScriptValue::PropertyFlags pflags = m_scriptClass->propertyFlags(scriptObject, scriptName, id);
+ unsigned attribs = 0;
+ if (pflags & QScriptValue::ReadOnly)
+ attribs |= JSC::ReadOnly;
+ if (pflags & QScriptValue::SkipInEnumeration)
+ attribs |= JSC::DontEnum;
+ if (pflags & QScriptValue::Undeletable)
+ attribs |= JSC::DontDelete;
+ if (pflags & QScriptValue::PropertyGetter)
+ attribs |= JSC::Getter;
+ if (pflags & QScriptValue::PropertySetter)
+ attribs |= JSC::Setter;
+ attribs |= pflags & QScriptValue::UserRange;
+ // Rather than calling the getter, we could return an access descriptor here.
+ QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id);
+ descriptor.setDescriptor(engine->scriptValueToJSCValue(value), attribs);
+ return true;
+ }
+ return false;
+}
+
void ClassObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec,
const JSC::Identifier &propertyName,
JSC::JSValue value, JSC::PutPropertySlot &slot)
@@ -105,8 +146,7 @@ void ClassObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec,
}
bool ClassObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *exec,
- const JSC::Identifier &propertyName,
- bool checkDontDelete)
+ const JSC::Identifier &propertyName)
{
// ### avoid duplication of put()
QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
@@ -124,44 +164,12 @@ bool ClassObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *
m_scriptClass->setProperty(scriptObject, scriptName, id, QScriptValue());
return true;
}
- return QScriptObjectDelegate::deleteProperty(object, exec, propertyName, checkDontDelete);
-}
-
-bool ClassObjectDelegate::getPropertyAttributes(const QScriptObject* object, JSC::ExecState *exec,
- const JSC::Identifier &propertyName,
- unsigned &attribs) const
-{
- QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
- QScript::SaveFrameHelper saveFrame(engine, exec);
- QScriptValue scriptObject = engine->scriptValueFromJSCValue(object);
- QScriptString scriptName;
- QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated);
- QScriptStringPrivate::init(scriptName, &scriptName_d);
- uint id = 0;
- QScriptClass::QueryFlags flags = m_scriptClass->queryProperty(
- scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id);
- if (flags & QScriptClass::HandlesReadAccess) {
- QScriptValue::PropertyFlags flags = m_scriptClass->propertyFlags(scriptObject, scriptName, id);
- attribs = 0;
- if (flags & QScriptValue::ReadOnly)
- attribs |= JSC::ReadOnly;
- if (flags & QScriptValue::SkipInEnumeration)
- attribs |= JSC::DontEnum;
- if (flags & QScriptValue::Undeletable)
- attribs |= JSC::DontDelete;
- if (flags & QScriptValue::PropertyGetter)
- attribs |= JSC::Getter;
- if (flags & QScriptValue::PropertySetter)
- attribs |= JSC::Setter;
- attribs |= flags & QScriptValue::UserRange;
- return true;
- }
- return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attribs);
+ return QScriptObjectDelegate::deleteProperty(object, exec, propertyName);
}
void ClassObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec,
JSC::PropertyNameArray &propertyNames,
- bool includeNonEnumerable)
+ JSC::EnumerationMode mode)
{
QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
QScript::SaveFrameHelper saveFrame(engine, exec);
@@ -175,7 +183,7 @@ void ClassObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecSt
}
delete it;
}
- QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable);
+ QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode);
}
JSC::CallType ClassObjectDelegate::getCallData(QScriptObject*, JSC::CallData &callData)
diff --git a/src/script/bridge/qscriptclassobject_p.h b/src/script/bridge/qscriptclassobject_p.h
index 89142ab..83fa61b 100644
--- a/src/script/bridge/qscriptclassobject_p.h
+++ b/src/script/bridge/qscriptclassobject_p.h
@@ -60,18 +60,17 @@ public:
virtual bool getOwnPropertySlot(QScriptObject*, JSC::ExecState*,
const JSC::Identifier& propertyName,
JSC::PropertySlot&);
+ virtual bool getOwnPropertyDescriptor(QScriptObject*, JSC::ExecState*,
+ const JSC::Identifier& propertyName,
+ JSC::PropertyDescriptor&);
virtual void put(QScriptObject*, JSC::ExecState* exec,
const JSC::Identifier& propertyName,
JSC::JSValue, JSC::PutPropertySlot&);
virtual bool deleteProperty(QScriptObject*, JSC::ExecState*,
- const JSC::Identifier& propertyName,
- bool checkDontDelete = true);
- virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*,
- const JSC::Identifier&,
- unsigned&) const;
+ const JSC::Identifier& propertyName);
virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*,
JSC::PropertyNameArray&,
- bool includeNonEnumerable = false);
+ JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&);
static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*,
diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp
index 1d11ede..a753f59 100644
--- a/src/script/bridge/qscriptdeclarativeclass.cpp
+++ b/src/script/bridge/qscriptdeclarativeclass.cpp
@@ -141,19 +141,22 @@ QScriptValue QScriptDeclarativeClass::Value::toScriptValue(QScriptEngine *engine
}
QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier()
-: identifier(0)
+ : identifier(0), engine(0)
{
new (&d) JSC::Identifier();
}
QScriptDeclarativeClass::PersistentIdentifier::~PersistentIdentifier()
{
+ if (engine)
+ JSC::setCurrentIdentifierTable(engine->globalData->identifierTable);
((JSC::Identifier &)d).JSC::Identifier::~Identifier();
}
QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier(const PersistentIdentifier &other)
{
identifier = other.identifier;
+ engine = other.engine;
new (&d) JSC::Identifier((JSC::Identifier &)(other.d));
}
@@ -161,6 +164,7 @@ QScriptDeclarativeClass::PersistentIdentifier &
QScriptDeclarativeClass::PersistentIdentifier::operator=(const PersistentIdentifier &other)
{
identifier = other.identifier;
+ engine = other.engine;
((JSC::Identifier &)d) = (JSC::Identifier &)(other.d);
return *this;
}
@@ -419,7 +423,7 @@ QScriptDeclarativeClass::createPersistentIdentifier(const QString &str)
static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine));
JSC::ExecState* exec = p->currentFrame;
- PersistentIdentifier rv(true);
+ PersistentIdentifier rv(p);
new (&rv.d) JSC::Identifier(exec, (UChar *)str.constData(), str.size());
rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep();
return rv;
@@ -432,7 +436,7 @@ QScriptDeclarativeClass::createPersistentIdentifier(const Identifier &id)
static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine));
JSC::ExecState* exec = p->currentFrame;
- PersistentIdentifier rv(true);
+ PersistentIdentifier rv(p);
new (&rv.d) JSC::Identifier(exec, (JSC::UString::Rep *)id);
rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep();
return rv;
diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h
index a0fd6d5..a187391 100644
--- a/src/script/bridge/qscriptdeclarativeclass_p.h
+++ b/src/script/bridge/qscriptdeclarativeclass_p.h
@@ -104,7 +104,8 @@ public:
private:
friend class QScriptDeclarativeClass;
- PersistentIdentifier(bool) : identifier(0), d(0) {}
+ PersistentIdentifier(QScriptEnginePrivate *e) : identifier(0), engine(e), d(0) {}
+ QScriptEnginePrivate *engine;
void *d;
};
diff --git a/src/script/bridge/qscriptdeclarativeobject.cpp b/src/script/bridge/qscriptdeclarativeobject.cpp
index c6ab6a7..a45bfbb 100644
--- a/src/script/bridge/qscriptdeclarativeobject.cpp
+++ b/src/script/bridge/qscriptdeclarativeobject.cpp
@@ -66,7 +66,6 @@ bool DeclarativeObjectDelegate::getOwnPropertySlot(QScriptObject* object,
const JSC::Identifier &propertyName,
JSC::PropertySlot &slot)
{
- QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep();
QScriptDeclarativeClassPrivate *p = QScriptDeclarativeClassPrivate::get(m_class);
@@ -106,43 +105,14 @@ void DeclarativeObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec,
}
bool DeclarativeObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *exec,
- const JSC::Identifier &propertyName,
- bool checkDontDelete)
-{
- return QScriptObjectDelegate::deleteProperty(object, exec, propertyName, checkDontDelete);
-}
-
-bool DeclarativeObjectDelegate::getPropertyAttributes(const QScriptObject* object,
- JSC::ExecState *exec,
- const JSC::Identifier &propertyName,
- unsigned &attribs) const
+ const JSC::Identifier &propertyName)
{
- QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep();
-
- QScriptClass::QueryFlags flags =
- m_class->queryProperty(m_object, identifier, QScriptClass::HandlesReadAccess);
- if (flags & QScriptClass::HandlesReadAccess) {
- QScriptValue::PropertyFlags flags = m_class->propertyFlags(m_object, identifier);
- attribs = 0;
- if (flags & QScriptValue::ReadOnly)
- attribs |= JSC::ReadOnly;
- if (flags & QScriptValue::SkipInEnumeration)
- attribs |= JSC::DontEnum;
- if (flags & QScriptValue::Undeletable)
- attribs |= JSC::DontDelete;
- if (flags & QScriptValue::PropertyGetter)
- attribs |= JSC::Getter;
- if (flags & QScriptValue::PropertySetter)
- attribs |= JSC::Setter;
- attribs |= flags & QScriptValue::UserRange;
- return true;
- }
- return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attribs);
+ return QScriptObjectDelegate::deleteProperty(object, exec, propertyName);
}
void DeclarativeObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec,
JSC::PropertyNameArray &propertyNames,
- bool includeNonEnumerable)
+ JSC::EnumerationMode mode)
{
QStringList properties = m_class->propertyNames(m_object);
for (int ii = 0; ii < properties.count(); ++ii) {
@@ -150,7 +120,7 @@ void DeclarativeObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::
propertyNames.add(JSC::Identifier(exec, name));
}
- QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable);
+ QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode);
}
JSC::CallType DeclarativeObjectDelegate::getCallData(QScriptObject *object, JSC::CallData &callData)
diff --git a/src/script/bridge/qscriptdeclarativeobject_p.h b/src/script/bridge/qscriptdeclarativeobject_p.h
index ec8a43e..5024a71 100644
--- a/src/script/bridge/qscriptdeclarativeobject_p.h
+++ b/src/script/bridge/qscriptdeclarativeobject_p.h
@@ -81,14 +81,10 @@ public:
const JSC::Identifier& propertyName,
JSC::JSValue, JSC::PutPropertySlot&);
virtual bool deleteProperty(QScriptObject*, JSC::ExecState*,
- const JSC::Identifier& propertyName,
- bool checkDontDelete = true);
- virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*,
- const JSC::Identifier&,
- unsigned&) const;
+ const JSC::Identifier& propertyName);
virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*,
JSC::PropertyNameArray&,
- bool includeNonEnumerable = false);
+ JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&);
static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*,
diff --git a/src/script/bridge/qscriptglobalobject.cpp b/src/script/bridge/qscriptglobalobject.cpp
index e7ea0df..4c002b7 100644
--- a/src/script/bridge/qscriptglobalobject.cpp
+++ b/src/script/bridge/qscriptglobalobject.cpp
@@ -72,6 +72,23 @@ bool GlobalObject::getOwnPropertySlot(JSC::ExecState* exec,
return JSC::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot);
}
+bool GlobalObject::getOwnPropertyDescriptor(JSC::ExecState* exec,
+ const JSC::Identifier& propertyName,
+ JSC::PropertyDescriptor& descriptor)
+{
+ // Must match the logic of getOwnPropertySlot().
+ QScriptEnginePrivate *engine = scriptEngineFromExec(exec);
+ if (propertyName == exec->propertyNames().arguments && engine->currentFrame->argumentCount() > 0) {
+ // ### Can we get rid of this special handling of the arguments property?
+ JSC::JSValue args = engine->scriptValueToJSCValue(engine->contextForFrame(engine->currentFrame)->argumentsObject());
+ descriptor.setValue(args);
+ return true;
+ }
+ if (customGlobalObject)
+ return customGlobalObject->getOwnPropertyDescriptor(exec, propertyName, descriptor);
+ return JSC::JSGlobalObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+}
+
void GlobalObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName,
JSC::JSValue value, JSC::PutPropertySlot& slot)
{
@@ -90,29 +107,20 @@ void GlobalObject::putWithAttributes(JSC::ExecState* exec, const JSC::Identifier
JSC::JSGlobalObject::putWithAttributes(exec, propertyName, value, attributes);
}
-bool GlobalObject::deleteProperty(JSC::ExecState* exec,
- const JSC::Identifier& propertyName, bool checkDontDelete)
-{
- if (customGlobalObject)
- return customGlobalObject->deleteProperty(exec, propertyName, checkDontDelete);
- return JSC::JSGlobalObject::deleteProperty(exec, propertyName, checkDontDelete);
-}
-
-bool GlobalObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName,
- unsigned& attributes) const
+bool GlobalObject::deleteProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName)
{
if (customGlobalObject)
- return customGlobalObject->getPropertyAttributes(exec, propertyName, attributes);
- return JSC::JSGlobalObject::getPropertyAttributes(exec, propertyName, attributes);
+ return customGlobalObject->deleteProperty(exec, propertyName);
+ return JSC::JSGlobalObject::deleteProperty(exec, propertyName);
}
void GlobalObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames,
- bool includeNonEnumerable)
+ JSC::EnumerationMode mode)
{
if (customGlobalObject)
- customGlobalObject->getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
+ customGlobalObject->getOwnPropertyNames(exec, propertyNames, mode);
else
- JSC::JSGlobalObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
+ JSC::JSGlobalObject::getOwnPropertyNames(exec, propertyNames, mode);
}
void GlobalObject::defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes)
diff --git a/src/script/bridge/qscriptglobalobject_p.h b/src/script/bridge/qscriptglobalobject_p.h
index b210f78..c0a419f 100644
--- a/src/script/bridge/qscriptglobalobject_p.h
+++ b/src/script/bridge/qscriptglobalobject_p.h
@@ -54,17 +54,17 @@ public:
virtual bool getOwnPropertySlot(JSC::ExecState*,
const JSC::Identifier& propertyName,
JSC::PropertySlot&);
+ virtual bool getOwnPropertyDescriptor(JSC::ExecState*,
+ const JSC::Identifier& propertyName,
+ JSC::PropertyDescriptor&);
virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName,
JSC::JSValue, JSC::PutPropertySlot&);
virtual void putWithAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName,
JSC::JSValue value, unsigned attributes);
virtual bool deleteProperty(JSC::ExecState*,
- const JSC::Identifier& propertyName,
- bool checkDontDelete = true);
- virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&,
- unsigned&) const;
+ const JSC::Identifier& propertyName);
virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&,
- bool includeNonEnumerable = false);
+ JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes = 0);
virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes = 0);
virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName);
@@ -94,19 +94,20 @@ public:
const JSC::Identifier& propertyName,
JSC::PropertySlot& slot)
{ return originalGlobalObject->JSC::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot); }
+ virtual bool getOwnPropertyDescriptor(JSC::ExecState* exec,
+ const JSC::Identifier& propertyName,
+ JSC::PropertyDescriptor& descriptor)
+ { return originalGlobalObject->JSC::JSGlobalObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); }
virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName,
JSC::JSValue value, JSC::PutPropertySlot& slot)
{ originalGlobalObject->JSC::JSGlobalObject::put(exec, propertyName, value, slot); }
virtual void putWithAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, unsigned attributes)
{ originalGlobalObject->JSC::JSGlobalObject::putWithAttributes(exec, propertyName, value, attributes); }
virtual bool deleteProperty(JSC::ExecState* exec,
- const JSC::Identifier& propertyName, bool checkDontDelete = true)
- { return originalGlobalObject->JSC::JSGlobalObject::deleteProperty(exec, propertyName, checkDontDelete); }
- virtual bool getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName,
- unsigned& attributes) const
- { return originalGlobalObject->JSC::JSGlobalObject::getPropertyAttributes(exec, propertyName, attributes); }
- virtual void getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, bool includeNonEnumerable = false)
- { originalGlobalObject->JSC::JSGlobalObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); }
+ const JSC::Identifier& propertyName)
+ { return originalGlobalObject->JSC::JSGlobalObject::deleteProperty(exec, propertyName); }
+ virtual void getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties)
+ { originalGlobalObject->JSC::JSGlobalObject::getOwnPropertyNames(exec, propertyNames, mode); }
virtual void defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes)
{ originalGlobalObject->JSC::JSGlobalObject::defineGetter(exec, propertyName, getterFunction, attributes); }
virtual void defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes)
diff --git a/src/script/bridge/qscriptobject.cpp b/src/script/bridge/qscriptobject.cpp
index 3db109e..9b6910e 100644
--- a/src/script/bridge/qscriptobject.cpp
+++ b/src/script/bridge/qscriptobject.cpp
@@ -81,30 +81,21 @@ void QScriptObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyNam
}
bool QScriptObject::deleteProperty(JSC::ExecState* exec,
- const JSC::Identifier& propertyName,
- bool checkDontDelete)
+ const JSC::Identifier& propertyName)
{
if (!d || !d->delegate)
- return JSC::JSObject::deleteProperty(exec, propertyName, checkDontDelete);
- return d->delegate->deleteProperty(this, exec, propertyName, checkDontDelete);
-}
-
-bool QScriptObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName,
- unsigned& attributes) const
-{
- if (!d || !d->delegate)
- return JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes);
- return d->delegate->getPropertyAttributes(this, exec, propertyName, attributes);
+ return JSC::JSObject::deleteProperty(exec, propertyName);
+ return d->delegate->deleteProperty(this, exec, propertyName);
}
void QScriptObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames,
- bool includeNonEnumerable)
+ JSC::EnumerationMode mode)
{
if (!d || !d->delegate) {
- JSC::JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
+ JSC::JSObject::getOwnPropertyNames(exec, propertyNames, mode);
return;
}
- d->delegate->getOwnPropertyNames(this, exec, propertyNames, includeNonEnumerable);
+ d->delegate->getOwnPropertyNames(this, exec, propertyNames, mode);
}
bool QScriptObject::compareToObject(JSC::ExecState* exec, JSC::JSObject *other)
@@ -189,25 +180,16 @@ void QScriptObjectDelegate::put(QScriptObject* object, JSC::ExecState* exec,
}
bool QScriptObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState* exec,
- const JSC::Identifier& propertyName,
- bool checkDontDelete)
-{
- return object->JSC::JSObject::deleteProperty(exec, propertyName, checkDontDelete);
-}
-
-bool QScriptObjectDelegate::getPropertyAttributes(const QScriptObject* object,
- JSC::ExecState* exec,
- const JSC::Identifier& propertyName,
- unsigned& attributes) const
+ const JSC::Identifier& propertyName)
{
- return object->JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes);
+ return object->JSC::JSObject::deleteProperty(exec, propertyName);
}
void QScriptObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState* exec,
JSC::PropertyNameArray& propertyNames,
- bool includeNonEnumerable)
+ JSC::EnumerationMode mode)
{
- object->JSC::JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
+ object->JSC::JSObject::getOwnPropertyNames(exec, propertyNames, mode);
}
void QScriptObjectDelegate::markChildren(QScriptObject* object, JSC::MarkStack& markStack)
diff --git a/src/script/bridge/qscriptobject_p.h b/src/script/bridge/qscriptobject_p.h
index 4d15bee..f6de418 100644
--- a/src/script/bridge/qscriptobject_p.h
+++ b/src/script/bridge/qscriptobject_p.h
@@ -67,12 +67,9 @@ public:
virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName,
JSC::JSValue, JSC::PutPropertySlot&);
virtual bool deleteProperty(JSC::ExecState*,
- const JSC::Identifier& propertyName,
- bool checkDontDelete = true);
- virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&,
- unsigned&) const;
+ const JSC::Identifier& propertyName);
virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&,
- bool includeNonEnumerable = false);
+ JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
virtual void markChildren(JSC::MarkStack& markStack);
virtual JSC::CallType getCallData(JSC::CallData&);
virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
@@ -84,7 +81,7 @@ public:
static WTF::PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)
{
- return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance | JSC::OverridesHasInstance));
+ return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags));
}
inline JSC::JSValue data() const;
@@ -94,6 +91,8 @@ public:
inline void setDelegate(QScriptObjectDelegate *delegate);
protected:
+ static const unsigned StructureFlags = JSC::ImplementsHasInstance | JSC::OverridesHasInstance | JSC::OverridesGetOwnPropertySlot | JSC::OverridesMarkChildren | JSC::OverridesGetPropertyNames | JSObject::StructureFlags;
+
Data *d;
};
@@ -128,12 +127,9 @@ public:
virtual void put(QScriptObject*, JSC::ExecState* exec, const JSC::Identifier& propertyName,
JSC::JSValue, JSC::PutPropertySlot&);
virtual bool deleteProperty(QScriptObject*, JSC::ExecState*,
- const JSC::Identifier& propertyName,
- bool checkDontDelete = true);
- virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*,
- const JSC::Identifier&, unsigned&) const;
+ const JSC::Identifier& propertyName);
virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*, JSC::PropertyNameArray&,
- bool includeNonEnumerable = false);
+ JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
virtual void markChildren(QScriptObject*, JSC::MarkStack& markStack);
virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&);
virtual JSC::ConstructType getConstructData(QScriptObject*, JSC::ConstructData&);
diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp
index 6c401f8..765e074 100644
--- a/src/script/bridge/qscriptqobject.cpp
+++ b/src/script/bridge/qscriptqobject.cpp
@@ -537,40 +537,43 @@ static JSC::JSValue callQtMethod(JSC::ExecState *exec, QMetaMethod::MethodType c
continue;
}
+ QList<QByteArray> parameterTypeNames = method.parameterTypes();
+
QVector<QScriptMetaType> types;
+ types.resize(1 + parameterTypeNames.size());
+ QScriptMetaType *typesData = types.data();
// resolve return type
QByteArray returnTypeName = method.typeName();
int rtype = QMetaType::type(returnTypeName);
if ((rtype == 0) && !returnTypeName.isEmpty()) {
int enumIndex = indexOfMetaEnum(meta, returnTypeName);
if (enumIndex != -1)
- types.append(QScriptMetaType::metaEnum(enumIndex, returnTypeName));
+ typesData[0] = QScriptMetaType::metaEnum(enumIndex, returnTypeName);
else
- types.append(QScriptMetaType::unresolved(returnTypeName));
+ typesData[0] = QScriptMetaType::unresolved(returnTypeName);
} else {
if (callType == QMetaMethod::Constructor)
- types.append(QScriptMetaType::metaType(QMetaType::QObjectStar, "QObject*"));
+ typesData[0] = QScriptMetaType::metaType(QMetaType::QObjectStar, "QObject*");
else if (rtype == QMetaType::QVariant)
- types.append(QScriptMetaType::variant());
+ typesData[0] = QScriptMetaType::variant();
else
- types.append(QScriptMetaType::metaType(rtype, returnTypeName));
+ typesData[0] = QScriptMetaType::metaType(rtype, returnTypeName);
}
// resolve argument types
- QList<QByteArray> parameterTypeNames = method.parameterTypes();
for (int i = 0; i < parameterTypeNames.count(); ++i) {
QByteArray argTypeName = parameterTypeNames.at(i);
int atype = QMetaType::type(argTypeName);
if (atype == 0) {
int enumIndex = indexOfMetaEnum(meta, argTypeName);
if (enumIndex != -1)
- types.append(QScriptMetaType::metaEnum(enumIndex, argTypeName));
+ typesData[1 + i] = QScriptMetaType::metaEnum(enumIndex, argTypeName);
else
- types.append(QScriptMetaType::unresolved(argTypeName));
+ typesData[1 + i] = QScriptMetaType::unresolved(argTypeName);
} else if (atype == QMetaType::QVariant) {
- types.append(QScriptMetaType::variant());
+ typesData[1 + i] = QScriptMetaType::variant();
} else {
- types.append(QScriptMetaType::metaType(atype, argTypeName));
+ typesData[1 + i] = QScriptMetaType::metaType(atype, argTypeName);
}
}
@@ -1298,7 +1301,7 @@ bool QObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, JSC::ExecS
const JSC::Identifier &propertyName,
JSC::PropertyDescriptor &descriptor)
{
- //Note: this has to be kept in sync with getOwnPropertySlot abd getPropertyAttributes
+ //Note: this has to be kept in sync with getOwnPropertySlot
#ifndef QT_NO_PROPERTIES
QByteArray name = convertToLatin1(propertyName.ustring());
QObject *qobject = data->value;
@@ -1528,8 +1531,7 @@ void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec,
}
bool QObjectDelegate::deleteProperty(QScriptObject *object, JSC::ExecState *exec,
- const JSC::Identifier& propertyName,
- bool checkDontDelete)
+ const JSC::Identifier& propertyName)
{
#ifndef QT_NO_PROPERTIES
QByteArray name = convertToLatin1(propertyName.ustring());
@@ -1569,86 +1571,7 @@ bool QObjectDelegate::deleteProperty(QScriptObject *object, JSC::ExecState *exec
return true;
}
- return QScriptObjectDelegate::deleteProperty(object, exec, propertyName, checkDontDelete);
-#else //QT_NO_PROPERTIES
- return false;
-#endif //QT_NO_PROPERTIES
-}
-
-bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object,
- JSC::ExecState *exec,
- const JSC::Identifier &propertyName,
- unsigned &attributes) const
-{
-#ifndef QT_NO_PROPERTIES
- //Note: this has to be kept in sync with getOwnPropertyDescriptor and getOwnPropertySlot
- QByteArray name = convertToLatin1(propertyName.ustring());
- QObject *qobject = data->value;
- if (!qobject)
- return false;
-
- const QScriptEngine::QObjectWrapOptions &opt = data->options;
- const QMetaObject *meta = qobject->metaObject();
- int index = -1;
- if (name.contains('(')) {
- QByteArray normalized = QMetaObject::normalizedSignature(name);
- if (-1 != (index = meta->indexOfMethod(normalized))) {
- QMetaMethod method = meta->method(index);
- if (hasMethodAccess(method, index, opt)) {
- if (!(opt & QScriptEngine::ExcludeSuperClassMethods)
- || (index >= meta->methodOffset())) {
- attributes = QObjectMemberAttribute;
- if (opt & QScriptEngine::SkipMethodsInEnumeration)
- attributes |= JSC::DontEnum;
- return true;
- }
- }
- }
- }
-
- index = meta->indexOfProperty(name);
- if (index != -1) {
- QMetaProperty prop = meta->property(index);
- if (prop.isScriptable()) {
- if (!(opt & QScriptEngine::ExcludeSuperClassProperties)
- || (index >= meta->propertyOffset())) {
- attributes = flagsForMetaProperty(prop);
- return true;
- }
- }
- }
-
- index = qobject->dynamicPropertyNames().indexOf(name);
- if (index != -1) {
- attributes = QObjectMemberAttribute;
- return true;
- }
-
- const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods)
- ? meta->methodOffset() : 0;
- for (index = meta->methodCount() - 1; index >= offset; --index) {
- QMetaMethod method = meta->method(index);
- if (hasMethodAccess(method, index, opt)
- && methodNameEquals(method, name.constData(), name.length())) {
- attributes = QObjectMemberAttribute;
- if (opt & QScriptEngine::SkipMethodsInEnumeration)
- attributes |= JSC::DontEnum;
- return true;
- }
- }
-
- if (!(opt & QScriptEngine::ExcludeChildObjects)) {
- QList<QObject*> children = qobject->children();
- for (index = 0; index < children.count(); ++index) {
- QObject *child = children.at(index);
- if (child->objectName() == (QString)(propertyName.ustring())) {
- attributes = JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum;
- return true;
- }
- }
- }
-
- return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attributes);
+ return QScriptObjectDelegate::deleteProperty(object, exec, propertyName);
#else //QT_NO_PROPERTIES
return false;
#endif //QT_NO_PROPERTIES
@@ -1656,7 +1579,7 @@ bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object,
void QObjectDelegate::getOwnPropertyNames(QScriptObject *object, JSC::ExecState *exec,
JSC::PropertyNameArray &propertyNames,
- bool includeNonEnumerable)
+ JSC::EnumerationMode mode)
{
#ifndef QT_NO_PROPERTIES
QObject *qobject = data->value;
@@ -1701,7 +1624,7 @@ void QObjectDelegate::getOwnPropertyNames(QScriptObject *object, JSC::ExecState
}
}
- QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable);
+ QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode);
#endif //QT_NO_PROPERTIES
}
@@ -1884,6 +1807,39 @@ bool QMetaObjectWrapperObject::getOwnPropertySlot(
return JSC::JSObject::getOwnPropertySlot(exec, propertyName, slot);
}
+bool QMetaObjectWrapperObject::getOwnPropertyDescriptor(
+ JSC::ExecState* exec, const JSC::Identifier& propertyName,
+ JSC::PropertyDescriptor& descriptor)
+{
+ const QMetaObject *meta = data->value;
+ if (!meta)
+ return false;
+
+ if (propertyName == exec->propertyNames().prototype) {
+ descriptor.setDescriptor(data->ctor
+ ? data->ctor.get(exec, propertyName)
+ : data->prototype,
+ JSC::DontDelete | JSC::DontEnum);
+ return true;
+ }
+
+ QByteArray name = QString(propertyName.ustring()).toLatin1();
+
+ for (int i = 0; i < meta->enumeratorCount(); ++i) {
+ QMetaEnum e = meta->enumerator(i);
+ for (int j = 0; j < e.keyCount(); ++j) {
+ const char *key = e.key(j);
+ if (!qstrcmp(key, name.constData())) {
+ descriptor.setDescriptor(JSC::JSValue(exec, e.value(j)),
+ JSC::ReadOnly | JSC::DontDelete);
+ return true;
+ }
+ }
+ }
+
+ return JSC::JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+}
+
void QMetaObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName,
JSC::JSValue value, JSC::PutPropertySlot &slot)
{
@@ -1909,8 +1865,7 @@ void QMetaObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier&
}
bool QMetaObjectWrapperObject::deleteProperty(
- JSC::ExecState *exec, const JSC::Identifier& propertyName,
- bool checkDontDelete)
+ JSC::ExecState *exec, const JSC::Identifier& propertyName)
{
if (propertyName == exec->propertyNames().prototype)
return false;
@@ -1925,36 +1880,12 @@ bool QMetaObjectWrapperObject::deleteProperty(
}
}
}
- return JSC::JSObject::deleteProperty(exec, propertyName, checkDontDelete);
-}
-
-bool QMetaObjectWrapperObject::getPropertyAttributes(JSC::ExecState *exec,
- const JSC::Identifier &propertyName,
- unsigned &attributes) const
-{
- if (propertyName == exec->propertyNames().prototype) {
- attributes = JSC::DontDelete;
- return true;
- }
- const QMetaObject *meta = data->value;
- if (meta) {
- QByteArray name = convertToLatin1(propertyName.ustring());
- for (int i = 0; i < meta->enumeratorCount(); ++i) {
- QMetaEnum e = meta->enumerator(i);
- for (int j = 0; j < e.keyCount(); ++j) {
- if (!qstrcmp(e.key(j), name.constData())) {
- attributes = JSC::ReadOnly | JSC::DontDelete;
- return true;
- }
- }
- }
- }
- return JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes);
+ return JSC::JSObject::deleteProperty(exec, propertyName);
}
void QMetaObjectWrapperObject::getOwnPropertyNames(JSC::ExecState *exec,
JSC::PropertyNameArray &propertyNames,
- bool includeNonEnumerable)
+ JSC::EnumerationMode mode)
{
const QMetaObject *meta = data->value;
if (!meta)
@@ -1964,7 +1895,7 @@ void QMetaObjectWrapperObject::getOwnPropertyNames(JSC::ExecState *exec,
for (int j = 0; j < e.keyCount(); ++j)
propertyNames.add(JSC::Identifier(exec, e.key(j)));
}
- JSC::JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);
+ JSC::JSObject::getOwnPropertyNames(exec, propertyNames, mode);
}
void QMetaObjectWrapperObject::markChildren(JSC::MarkStack& markStack)
diff --git a/src/script/bridge/qscriptqobject_p.h b/src/script/bridge/qscriptqobject_p.h
index 8b05d6b..b82bcb7 100644
--- a/src/script/bridge/qscriptqobject_p.h
+++ b/src/script/bridge/qscriptqobject_p.h
@@ -86,14 +86,10 @@ public:
const JSC::Identifier& propertyName,
JSC::JSValue, JSC::PutPropertySlot&);
virtual bool deleteProperty(QScriptObject*, JSC::ExecState*,
- const JSC::Identifier& propertyName,
- bool checkDontDelete = true);
- virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*,
- const JSC::Identifier&,
- unsigned&) const;
+ const JSC::Identifier& propertyName);
virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*,
JSC::PropertyNameArray&,
- bool includeNonEnumerable = false);
+ JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
virtual void markChildren(QScriptObject*, JSC::MarkStack& markStack);
virtual bool compareToObject(QScriptObject*, JSC::ExecState*, JSC::JSObject*);
@@ -275,15 +271,15 @@ public:
virtual bool getOwnPropertySlot(JSC::ExecState*,
const JSC::Identifier& propertyName,
JSC::PropertySlot&);
+ virtual bool getOwnPropertyDescriptor(JSC::ExecState*,
+ const JSC::Identifier& propertyName,
+ JSC::PropertyDescriptor&);
virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName,
JSC::JSValue, JSC::PutPropertySlot&);
virtual bool deleteProperty(JSC::ExecState*,
- const JSC::Identifier& propertyName,
- bool checkDontDelete = true);
- virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&,
- unsigned&) const;
+ const JSC::Identifier& propertyName);
virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&,
- bool includeNonEnumerable = false);
+ JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);
virtual void markChildren(JSC::MarkStack& markStack);
virtual JSC::CallType getCallData(JSC::CallData&);
@@ -303,10 +299,12 @@ public:
static WTF::PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)
{
- return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType));
+ return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags));
}
protected:
+ static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesMarkChildren | JSC::OverridesGetPropertyNames | JSObject::StructureFlags;
+
Data *data;
};
diff --git a/src/script/bridge/qscriptvariant.cpp b/src/script/bridge/qscriptvariant.cpp
index b4f0365..b2dd3b0 100644
--- a/src/script/bridge/qscriptvariant.cpp
+++ b/src/script/bridge/qscriptvariant.cpp
@@ -119,11 +119,8 @@ static JSC::JSValue JSC_HOST_CALL variantProtoFuncToString(JSC::ExecState *exec,
JSC::JSValue value = variantProtoFuncValueOf(exec, callee, thisValue, args);
if (value.isObject()) {
result = v.toString();
- if (result.isEmpty() && !v.canConvert(QVariant::String)) {
- result = "QVariant(";
- result += v.typeName();
- result += ")";
- }
+ if (result.isEmpty() && !v.canConvert(QVariant::String))
+ result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(v.typeName()));
} else {
result = value.toString(exec);
}
diff --git a/src/script/script.pro b/src/script/script.pro
index 771047a..df5dbf3 100644
--- a/src/script/script.pro
+++ b/src/script/script.pro
@@ -39,6 +39,11 @@ wince* {
LIBS += -lmmtimer
}
+mac {
+ DEFINES += ENABLE_JSC_MULTIPLE_THREADS=0
+ LIBS_PRIVATE += -framework AppKit
+}
+
include($$WEBKITDIR/JavaScriptCore/JavaScriptCore.pri)
INCLUDEPATH += $$WEBKITDIR/JavaScriptCore
@@ -68,7 +73,7 @@ solaris-g++:isEqual(QT_ARCH,sparc) {
}
# Avoid JSC C API functions being exported.
-DEFINES += JS_EXPORT="" JS_EXPORTDATA=""
+DEFINES += JS_NO_EXPORT JS_EXPORTDATA=""
INCLUDEPATH += $$PWD