summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/CMakeLists.txt1
-rw-r--r--Source/JavaScriptCore/ChangeLog2443
-rw-r--r--Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig5
-rw-r--r--Source/JavaScriptCore/Configurations/Version.xcconfig2
-rw-r--r--Source/JavaScriptCore/GNUmakefile.list.am3
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.pri4
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def8
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj8
-rw-r--r--Source/JavaScriptCore/Target.pri5
-rw-r--r--Source/JavaScriptCore/assembler/ARMAssembler.cpp50
-rw-r--r--Source/JavaScriptCore/assembler/ARMAssembler.h271
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp2
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARM.h18
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h11
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp3
-rw-r--r--Source/JavaScriptCore/bytecode/DFGExitProfile.h1
-rw-r--r--Source/JavaScriptCore/bytecode/Opcode.h2
-rw-r--r--Source/JavaScriptCore/bytecode/SpeculatedType.cpp5
-rw-r--r--Source/JavaScriptCore/bytecode/SpeculatedType.h5
-rw-r--r--Source/JavaScriptCore/bytecode/ValueRecovery.h3
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp5
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h2
-rw-r--r--Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp73
-rw-r--r--Source/JavaScriptCore/debugger/Debugger.h16
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.cpp20
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.h1
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractValue.h68
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp22
-rw-r--r--Source/JavaScriptCore/dfg/DFGCSEPhase.cpp42
-rw-r--r--Source/JavaScriptCore/dfg/DFGDriver.cpp4
-rw-r--r--Source/JavaScriptCore/dfg/DFGFixupPhase.cpp3
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.cpp6
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h46
-rw-r--r--Source/JavaScriptCore/dfg/DFGNode.h15
-rw-r--r--Source/JavaScriptCore/dfg/DFGNodeType.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSREntry.cpp4
-rw-r--r--Source/JavaScriptCore/dfg/DFGOSRExit.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp86
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp84
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp159
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h137
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp62
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp68
-rw-r--r--Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp490
-rw-r--r--Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h50
-rw-r--r--Source/JavaScriptCore/dfg/DFGVariableAccessData.h37
-rw-r--r--Source/JavaScriptCore/heap/BlockAllocator.cpp8
-rw-r--r--Source/JavaScriptCore/heap/BlockAllocator.h27
-rw-r--r--Source/JavaScriptCore/heap/CopiedBlock.h18
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpace.cpp30
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpace.h13
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h4
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp14
-rw-r--r--Source/JavaScriptCore/heap/Heap.h2
-rw-r--r--Source/JavaScriptCore/heap/HeapBlock.h34
-rw-r--r--Source/JavaScriptCore/heap/IncrementalSweeper.cpp58
-rw-r--r--Source/JavaScriptCore/heap/IncrementalSweeper.h19
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.cpp8
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.cpp21
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.h11
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.cpp18
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.h6
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.cpp7
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.h5
-rw-r--r--Source/JavaScriptCore/heap/WeakSetInlines.h3
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp26
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.h2
-rw-r--r--Source/JavaScriptCore/jit/JITInlineMethods.h2
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp7
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes32_64.cpp19
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess.cpp4
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp4
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp90
-rw-r--r--Source/JavaScriptCore/jit/SpecializedThunkJIT.h4
-rw-r--r--Source/JavaScriptCore/jit/ThunkGenerators.cpp8
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp5
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.asm2
-rw-r--r--Source/JavaScriptCore/parser/ASTBuilder.h504
-rw-r--r--Source/JavaScriptCore/parser/Lexer.cpp18
-rw-r--r--Source/JavaScriptCore/parser/Lexer.h18
-rw-r--r--Source/JavaScriptCore/parser/NodeConstructors.h453
-rw-r--r--Source/JavaScriptCore/parser/Nodes.cpp48
-rw-r--r--Source/JavaScriptCore/parser/Nodes.h252
-rw-r--r--Source/JavaScriptCore/parser/Parser.cpp267
-rw-r--r--Source/JavaScriptCore/parser/Parser.h32
-rw-r--r--Source/JavaScriptCore/parser/ParserTokens.h14
-rw-r--r--Source/JavaScriptCore/parser/SourceProviderCacheItem.h6
-rw-r--r--Source/JavaScriptCore/parser/SyntaxChecker.h130
-rw-r--r--Source/JavaScriptCore/runtime/CommonIdentifiers.cpp8
-rw-r--r--Source/JavaScriptCore/runtime/DateConstructor.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/DateConversion.cpp170
-rw-r--r--Source/JavaScriptCore/runtime/DateConversion.h73
-rw-r--r--Source/JavaScriptCore/runtime/DatePrototype.cpp93
-rw-r--r--Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/Identifier.cpp24
-rw-r--r--Source/JavaScriptCore/runtime/Identifier.h21
-rw-r--r--Source/JavaScriptCore/runtime/JSCell.h5
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/Options.h1
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h9
-rw-r--r--Source/JavaScriptCore/runtime/TimeoutChecker.cpp5
101 files changed, 5248 insertions, 1750 deletions
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 4b030ca40..146a11910 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -94,6 +94,7 @@ SET(JavaScriptCore_SOURCES
dfg/DFGSpeculativeJIT.cpp
dfg/DFGSpeculativeJIT32_64.cpp
dfg/DFGSpeculativeJIT64.cpp
+ dfg/DFGStructureCheckHoistingPhase.cpp
dfg/DFGThunks.cpp
dfg/DFGValueSource.cpp
dfg/DFGVariableEvent.cpp
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index c71b441e2..063b2f519 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,20 +1,2443 @@
-2012-06-13 Patrick Gansterer <paroga@webkit.org>
+2012-08-10 Yong Li <yoli@rim.com>
+
+ [BlackBerry] GCActivityCallback should always schedule GC even allocated bytes is a small number
+ https://bugs.webkit.org/show_bug.cgi?id=93650
+
+ Reviewed by Rob Buis.
+
+ Even a small number of allocated JS objects could hold expensive resources.
+
+ * runtime/GCActivityCallbackBlackBerry.cpp:
+ (JSC::DefaultGCActivityCallback::didAllocate):
+
+2012-08-09 Yong Li <yoli@rim.com>
+
+ [QNX] Implement getCPUTime() for OS(QNX)
+ https://bugs.webkit.org/show_bug.cgi?id=93516
+
+ Reviewed by George Staikos.
+
+ Implement getCPUTime() with CLOCK_THREAD_CPUTIME_ID so it will tell
+ exactly how long the current thread has spent without being impacted
+ by other things.
+
+ * runtime/TimeoutChecker.cpp:
+ (JSC::getCPUTime):
+
+2012-08-08 Shane Stephens <shanestephens@google.com>
+
+ Compile flag for CSS Hierarchies
+ https://bugs.webkit.org/show_bug.cgi?id=92433
+
+ Reviewed by Tony Chang.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-08-08 Benjamin Poulain <bpoulain@apple.com>
+
+ Use char* instead of LChar* for the public interface of String construction from literals
+ https://bugs.webkit.org/show_bug.cgi?id=93402
+
+ Reviewed by Michael Saboff.
+
+ Update JSC' Identifier to use StringImpl::createFromLiteral with a char*.
+
+ * runtime/Identifier.cpp:
+ (JSC::IdentifierASCIIStringTranslator::translate):
+
+2012-08-08 Patrick Gansterer <paroga@webkit.org>
+
+ Remove ce_time.(cpp|h) from list of source files
+ https://bugs.webkit.org/show_bug.cgi?id=93446
+
+ Reviewed by Simon Hausmann.
+
+ r125004 removed the last dependency on functions defined in ce_time.cpp.
+
+ * Target.pri:
+
+2012-08-08 Patrick Gansterer <paroga@webkit.org>
+
+ [WIN] Use GetTimeZoneInformation() for getting the timezone name
+ https://bugs.webkit.org/show_bug.cgi?id=91936
+
+ Reviewed by Ryosuke Niwa.
+
+ The MS CRT implementation of strftime calls the same functions in the background.
+ Using them directly avoids the overhead of parsing the format string and removes
+ the dependency on strftime() for WinCE where this function does not exist.
+
+ * runtime/DateConversion.cpp:
+ (JSC::formatTime):
+
+2012-08-07 Gabor Ballabas <gaborb@inf.u-szeged.hu>
+
+ Refactor magic numbers in the ARM port of DFG-JIT
+ https://bugs.webkit.org/show_bug.cgi?id=93348
+
+ Reviewed by Eric Seidel.
+
+ Introduce new names for hard-coded magic numbers.
+ Refactor constant with confusing names to more descriptive ones.
+
+ * assembler/ARMAssembler.cpp:
+ (JSC::ARMAssembler::patchConstantPoolLoad):
+ (JSC::ARMAssembler::getOp2):
+ (JSC::ARMAssembler::genInt):
+ (JSC::ARMAssembler::getImm):
+ (JSC::ARMAssembler::moveImm):
+ (JSC::ARMAssembler::encodeComplexImm):
+ (JSC::ARMAssembler::dataTransfer32):
+ (JSC::ARMAssembler::dataTransfer16):
+ (JSC::ARMAssembler::dataTransferFloat):
+ (JSC::ARMAssembler::executableCopy):
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::emitInstruction):
+ (JSC::ARMAssembler::ands_r):
+ (JSC::ARMAssembler::eors_r):
+ (JSC::ARMAssembler::subs_r):
+ (JSC::ARMAssembler::rsbs_r):
+ (JSC::ARMAssembler::adds_r):
+ (JSC::ARMAssembler::adcs_r):
+ (JSC::ARMAssembler::sbcs_r):
+ (JSC::ARMAssembler::rscs_r):
+ (JSC::ARMAssembler::tst_r):
+ (JSC::ARMAssembler::teq_r):
+ (JSC::ARMAssembler::cmp_r):
+ (JSC::ARMAssembler::cmn_r):
+ (JSC::ARMAssembler::orrs_r):
+ (JSC::ARMAssembler::movs_r):
+ (JSC::ARMAssembler::bics_r):
+ (JSC::ARMAssembler::mvns_r):
+ (JSC::ARMAssembler::muls_r):
+ (JSC::ARMAssembler::ldr_imm):
+ (JSC::ARMAssembler::ldr_un_imm):
+ (JSC::ARMAssembler::dtr_u):
+ (JSC::ARMAssembler::dtr_ur):
+ (JSC::ARMAssembler::dtr_dr):
+ (JSC::ARMAssembler::dtrh_u):
+ (JSC::ARMAssembler::dtrh_ur):
+ (JSC::ARMAssembler::fdtr_u):
+ (JSC::ARMAssembler::push_r):
+ (JSC::ARMAssembler::pop_r):
+ (JSC::ARMAssembler::getLdrImmAddress):
+ (JSC::ARMAssembler::getLdrImmAddressOnPool):
+ (JSC::ARMAssembler::patchConstantPoolLoad):
+ (JSC::ARMAssembler::repatchCompact):
+ (JSC::ARMAssembler::replaceWithJump):
+ (JSC::ARMAssembler::replaceWithLoad):
+ (JSC::ARMAssembler::replaceWithAddressComputation):
+ (JSC::ARMAssembler::getOp2Byte):
+ (JSC::ARMAssembler::getOp2Half):
+ (JSC::ARMAssembler::getImm16Op2):
+ (JSC::ARMAssembler::placeConstantPoolBarrier):
+ (JSC::ARMAssembler::getConditionalField):
+ * assembler/MacroAssemblerARM.cpp:
+ (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::and32):
+ (JSC::MacroAssemblerARM::branch32):
+ (JSC::MacroAssemblerARM::branchTest32):
+ (JSC::MacroAssemblerARM::branchTruncateDoubleToInt32):
+
+2012-08-07 Benjamin Poulain <benjamin@webkit.org>
+
+ Use the initialization from literal for JSC's Identifiers
+ https://bugs.webkit.org/show_bug.cgi?id=93193
+
+ Reviewed by Geoffrey Garen.
+
+ This patches modify Identifier ot take advantage of the new initialization from literal.
+
+ In addition to the memory savings (~600bytes per instance), this gives us a 2% speed
+ improvement on CommonIdentifiers on average.
+
+ * runtime/CommonIdentifiers.cpp:
+ (JSC::CommonIdentifiers::CommonIdentifiers):
+ Null and empty strings are forbidden for literal initialization. Use the most efficient constructors
+ instead of a literal.
+
+ * runtime/Identifier.cpp:
+ (IdentifierASCIIStringTranslator):
+ Rename IdentifierCStringTranslator to IdentifierASCIIStringTranslator to make the text encoding
+ explicit.
+ (JSC::IdentifierASCIIStringTranslator::hash):
+ (JSC::IdentifierASCIIStringTranslator::equal):
+ (JSC::IdentifierASCIIStringTranslator::translate): Use the fast initialization from literal.
+ (JSC::Identifier::add):
+ * runtime/Identifier.h:
+ (JSC::Identifier::Identifier):
+
+2012-08-07 Simon Hausmann <simon.hausmann@nokia.com>
+
+ [Qt][Win] Remove pthreads linkage
+
+ Reviewed by Csaba Osztrogonác.
+
+ After r124823 linkage to pthreads is not needed anymore for the Windows
+ build.
+
+ * JavaScriptCore.pri:
+
+2012-08-07 Gabor Ballabas <gaborb@inf.u-szeged.hu>
+
+ Refactor emit*Inst functions and introduce toARMWord functions in DFG-JIT's traditional ARM port
+ https://bugs.webkit.org/show_bug.cgi?id=93266
+
+ Reviewed by Csaba Osztrogonác.
+
+ First part of a bigger refactoring issue trying to make traditional
+ ARM DFG-JIT port easier to read and understand.
+
+
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::emitInstruction):
+ (JSC::ARMAssembler::emitDoublePrecisionInstruction):
+ (JSC::ARMAssembler::emitSinglePrecisionInstruction):
+ (JSC::ARMAssembler::and_r):
+ (JSC::ARMAssembler::ands_r):
+ (JSC::ARMAssembler::eor_r):
+ (JSC::ARMAssembler::eors_r):
+ (JSC::ARMAssembler::sub_r):
+ (JSC::ARMAssembler::subs_r):
+ (JSC::ARMAssembler::rsb_r):
+ (JSC::ARMAssembler::rsbs_r):
+ (JSC::ARMAssembler::add_r):
+ (JSC::ARMAssembler::adds_r):
+ (JSC::ARMAssembler::adc_r):
+ (JSC::ARMAssembler::adcs_r):
+ (JSC::ARMAssembler::sbc_r):
+ (JSC::ARMAssembler::sbcs_r):
+ (JSC::ARMAssembler::rsc_r):
+ (JSC::ARMAssembler::rscs_r):
+ (JSC::ARMAssembler::tst_r):
+ (JSC::ARMAssembler::teq_r):
+ (JSC::ARMAssembler::cmp_r):
+ (JSC::ARMAssembler::cmn_r):
+ (JSC::ARMAssembler::orr_r):
+ (JSC::ARMAssembler::orrs_r):
+ (JSC::ARMAssembler::mov_r):
+ (JSC::ARMAssembler::movw_r):
+ (JSC::ARMAssembler::movt_r):
+ (JSC::ARMAssembler::movs_r):
+ (JSC::ARMAssembler::bic_r):
+ (JSC::ARMAssembler::bics_r):
+ (JSC::ARMAssembler::mvn_r):
+ (JSC::ARMAssembler::mvns_r):
+ (JSC::ARMAssembler::mul_r):
+ (JSC::ARMAssembler::muls_r):
+ (JSC::ARMAssembler::mull_r):
+ (JSC::ARMAssembler::vmov_f64_r):
+ (JSC::ARMAssembler::vadd_f64_r):
+ (JSC::ARMAssembler::vdiv_f64_r):
+ (JSC::ARMAssembler::vsub_f64_r):
+ (JSC::ARMAssembler::vmul_f64_r):
+ (JSC::ARMAssembler::vcmp_f64_r):
+ (JSC::ARMAssembler::vsqrt_f64_r):
+ (JSC::ARMAssembler::vabs_f64_r):
+ (JSC::ARMAssembler::vneg_f64_r):
+ (JSC::ARMAssembler::ldr_imm):
+ (JSC::ARMAssembler::ldr_un_imm):
+ (JSC::ARMAssembler::dtr_u):
+ (JSC::ARMAssembler::dtr_ur):
+ (JSC::ARMAssembler::dtr_d):
+ (JSC::ARMAssembler::dtr_dr):
+ (JSC::ARMAssembler::dtrh_u):
+ (JSC::ARMAssembler::dtrh_ur):
+ (JSC::ARMAssembler::dtrh_d):
+ (JSC::ARMAssembler::dtrh_dr):
+ (JSC::ARMAssembler::fdtr_u):
+ (JSC::ARMAssembler::fdtr_d):
+ (JSC::ARMAssembler::push_r):
+ (JSC::ARMAssembler::pop_r):
+ (JSC::ARMAssembler::vmov_vfp64_r):
+ (JSC::ARMAssembler::vmov_arm64_r):
+ (JSC::ARMAssembler::vmov_vfp32_r):
+ (JSC::ARMAssembler::vmov_arm32_r):
+ (JSC::ARMAssembler::vcvt_f64_s32_r):
+ (JSC::ARMAssembler::vcvt_s32_f64_r):
+ (JSC::ARMAssembler::vcvt_u32_f64_r):
+ (JSC::ARMAssembler::vcvt_f64_f32_r):
+ (JSC::ARMAssembler::vcvt_f32_f64_r):
+ (JSC::ARMAssembler::vmrs_apsr):
+ (JSC::ARMAssembler::clz_r):
+ (JSC::ARMAssembler::bx):
+ (JSC::ARMAssembler::blx):
+ (JSC::ARMAssembler::linkJump):
+ (JSC::ARMAssembler::toARMWord):
+ (ARMAssembler):
+
+2012-08-06 Patrick Gansterer <paroga@webkit.org>
[WIN] Remove dependency on pthread from MachineStackMarker
https://bugs.webkit.org/show_bug.cgi?id=68429
- Reviewed by NOBODY (OOPS!).
+ Reviewed by Geoffrey Garen.
- Implement pthread TLS functionality with native windows functions.
+ Windows has no support for calling a destructor for thread specific data.
+ Since we need more control over creating and deleting thread specific keys
+ we can not simply extend WTF::ThreadSpecific with this functionality.
- * heap/MachineStackMarker.cpp: Use the new functions instead of pthread directly.
+ All thread specific keys created via the new API get stored in a list.
+ After a thread function finished we iterate over this list and call
+ the registered destructor for every item if needed.
+
+ * heap/MachineStackMarker.cpp: Use the new functions instead of pthread directly.
+ (JSC::MachineThreads::~MachineThreads):
+ (JSC::MachineThreads::makeUsableFromMultipleThreads):
+ (JSC::MachineThreads::addCurrentThread):
* heap/MachineStackMarker.h:
- * wtf/ThreadSpecific.h:
- (WTF::ThreadSpecificKeyCreate): Added wrapper around pthread_key_create.
- (WTF::ThreadSpecificKeyDelete): Added wrapper around pthread_key_delete.
- (WTF::ThreadSpecificSet): Added wrapper around pthread_setspecific.
- (WTF::ThreadSpecificGet): Added wrapper around pthread_getspecific.
- * wtf/ThreadSpecificWin.cpp:
+ (MachineThreads):
+
+2012-08-06 Patrick Gansterer <paroga@webkit.org>
+
+ Unify JSC date and time formating functions
+ https://bugs.webkit.org/show_bug.cgi?id=92282
+
+ Reviewed by Geoffrey Garen.
+
+ Replace the existing functions for formating GregorianDateTime
+ with one single function. This removes some code duplications
+ in DatePrototype and is a preperation to fix encoding issues,
+ since we can add UChar* values to the resulting string now.
+
+ * runtime/DateConstructor.cpp:
+ (JSC::callDate):
+ * runtime/DateConversion.cpp:
+ (JSC::formatDateTime):
+ * runtime/DateConversion.h:
+ (JSC):
+ * runtime/DatePrototype.cpp:
+ (JSC::formateDateInstance):
+ (JSC::dateProtoFuncToString):
+ (JSC::dateProtoFuncToUTCString):
+ (JSC::dateProtoFuncToDateString):
+ (JSC::dateProtoFuncToTimeString):
+ (JSC::dateProtoFuncToGMTString):
+
+2012-08-06 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ Unreviewed. Fix make distcheck.
+
+ * GNUmakefile.list.am: Add missing header file.
+
+2012-08-05 Peter Wang <peter.wang@torchmobile.com.cn>
+
+ Web Inspector: [JSC] implement setting breakpoints by line:column
+ https://bugs.webkit.org/show_bug.cgi?id=53003
+
+ Reviewed by Geoffrey Garen.
+
+ Add a counter to Lexer to record the column info of each Token. Add a column parameter to
+ op_debug, cti_op_debug, and _llint_op_debug byte-code command.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::resolve):
+ (JSC::BytecodeGenerator::emitDebugHook):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ArrayNode::toArgumentList):
+ (JSC::ApplyFunctionCallDotNode::emitBytecode):
+ (JSC::ConstStatementNode::emitBytecode):
+ (JSC::EmptyStatementNode::emitBytecode):
+ (JSC::DebuggerStatementNode::emitBytecode):
+ (JSC::ExprStatementNode::emitBytecode):
+ (JSC::VarStatementNode::emitBytecode):
+ (JSC::IfNode::emitBytecode):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::ContinueNode::emitBytecode):
+ (JSC::BreakNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::WithNode::emitBytecode):
+ (JSC::SwitchNode::emitBytecode):
+ (JSC::LabelNode::emitBytecode):
+ (JSC::ThrowNode::emitBytecode):
+ (JSC::TryNode::emitBytecode):
+ (JSC::ProgramNode::emitBytecode):
+ (JSC::EvalNode::emitBytecode):
+ (JSC::FunctionBodyNode::emitBytecode):
+ * debugger/Debugger.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::debug):
+ (JSC::Interpreter::privateExecute):
+ * interpreter/Interpreter.h:
+ (Interpreter):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_debug):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_debug):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * llint/LowLevelInterpreter.asm:
+ * parser/ASTBuilder.h:
+ (ASTBuilder):
+ (JSC::ASTBuilder::createCommaExpr):
+ (JSC::ASTBuilder::createLogicalNot):
+ (JSC::ASTBuilder::createUnaryPlus):
+ (JSC::ASTBuilder::createVoid):
+ (JSC::ASTBuilder::thisExpr):
+ (JSC::ASTBuilder::createResolve):
+ (JSC::ASTBuilder::createObjectLiteral):
+ (JSC::ASTBuilder::createArray):
+ (JSC::ASTBuilder::createNumberExpr):
+ (JSC::ASTBuilder::createString):
+ (JSC::ASTBuilder::createBoolean):
+ (JSC::ASTBuilder::createNull):
+ (JSC::ASTBuilder::createBracketAccess):
+ (JSC::ASTBuilder::createDotAccess):
+ (JSC::ASTBuilder::createRegExp):
+ (JSC::ASTBuilder::createNewExpr):
+ (JSC::ASTBuilder::createConditionalExpr):
+ (JSC::ASTBuilder::createAssignResolve):
+ (JSC::ASTBuilder::createFunctionExpr):
+ (JSC::ASTBuilder::createFunctionBody):
+ (JSC::ASTBuilder::createGetterOrSetterProperty):
+ (JSC::ASTBuilder::createArgumentsList):
+ (JSC::ASTBuilder::createPropertyList):
+ (JSC::ASTBuilder::createFuncDeclStatement):
+ (JSC::ASTBuilder::createBlockStatement):
+ (JSC::ASTBuilder::createExprStatement):
+ (JSC::ASTBuilder::createIfStatement):
+ (JSC::ASTBuilder::createForLoop):
+ (JSC::ASTBuilder::createForInLoop):
+ (JSC::ASTBuilder::createEmptyStatement):
+ (JSC::ASTBuilder::createVarStatement):
+ (JSC::ASTBuilder::createReturnStatement):
+ (JSC::ASTBuilder::createBreakStatement):
+ (JSC::ASTBuilder::createContinueStatement):
+ (JSC::ASTBuilder::createTryStatement):
+ (JSC::ASTBuilder::createSwitchStatement):
+ (JSC::ASTBuilder::createWhileStatement):
+ (JSC::ASTBuilder::createDoWhileStatement):
+ (JSC::ASTBuilder::createLabelStatement):
+ (JSC::ASTBuilder::createWithStatement):
+ (JSC::ASTBuilder::createThrowStatement):
+ (JSC::ASTBuilder::createDebugger):
+ (JSC::ASTBuilder::createConstStatement):
+ (JSC::ASTBuilder::appendConstDecl):
+ (JSC::ASTBuilder::combineCommaNodes):
+ (JSC::ASTBuilder::appendBinaryOperation):
+ (JSC::ASTBuilder::createAssignment):
+ (JSC::ASTBuilder::createNumber):
+ (JSC::ASTBuilder::makeTypeOfNode):
+ (JSC::ASTBuilder::makeDeleteNode):
+ (JSC::ASTBuilder::makeNegateNode):
+ (JSC::ASTBuilder::makeBitwiseNotNode):
+ (JSC::ASTBuilder::makeMultNode):
+ (JSC::ASTBuilder::makeDivNode):
+ (JSC::ASTBuilder::makeModNode):
+ (JSC::ASTBuilder::makeAddNode):
+ (JSC::ASTBuilder::makeSubNode):
+ (JSC::ASTBuilder::makeLeftShiftNode):
+ (JSC::ASTBuilder::makeRightShiftNode):
+ (JSC::ASTBuilder::makeURightShiftNode):
+ (JSC::ASTBuilder::makeBitOrNode):
+ (JSC::ASTBuilder::makeBitAndNode):
+ (JSC::ASTBuilder::makeBitXOrNode):
+ (JSC::ASTBuilder::makeFunctionCallNode):
+ (JSC::ASTBuilder::makeBinaryNode):
+ (JSC::ASTBuilder::makeAssignNode):
+ (JSC::ASTBuilder::makePrefixNode):
+ (JSC::ASTBuilder::makePostfixNode):
+ * parser/Lexer.cpp:
+ (JSC::::setCode):
+ (JSC::::internalShift):
+ (JSC::::shift):
+ (JSC::::lex):
+ * parser/Lexer.h:
+ (Lexer):
+ (JSC::Lexer::currentColumnNumber):
+ (JSC::::lexExpectIdentifier):
+ * parser/NodeConstructors.h:
+ (JSC::Node::Node):
+ (JSC::ExpressionNode::ExpressionNode):
+ (JSC::StatementNode::StatementNode):
+ (JSC::NullNode::NullNode):
+ (JSC::BooleanNode::BooleanNode):
+ (JSC::NumberNode::NumberNode):
+ (JSC::StringNode::StringNode):
+ (JSC::RegExpNode::RegExpNode):
+ (JSC::ThisNode::ThisNode):
+ (JSC::ResolveNode::ResolveNode):
+ (JSC::ArrayNode::ArrayNode):
+ (JSC::PropertyListNode::PropertyListNode):
+ (JSC::ObjectLiteralNode::ObjectLiteralNode):
+ (JSC::BracketAccessorNode::BracketAccessorNode):
+ (JSC::DotAccessorNode::DotAccessorNode):
+ (JSC::ArgumentListNode::ArgumentListNode):
+ (JSC::NewExprNode::NewExprNode):
+ (JSC::EvalFunctionCallNode::EvalFunctionCallNode):
+ (JSC::FunctionCallValueNode::FunctionCallValueNode):
+ (JSC::FunctionCallResolveNode::FunctionCallResolveNode):
+ (JSC::FunctionCallBracketNode::FunctionCallBracketNode):
+ (JSC::FunctionCallDotNode::FunctionCallDotNode):
+ (JSC::CallFunctionCallDotNode::CallFunctionCallDotNode):
+ (JSC::ApplyFunctionCallDotNode::ApplyFunctionCallDotNode):
+ (JSC::PrePostResolveNode::PrePostResolveNode):
+ (JSC::PostfixResolveNode::PostfixResolveNode):
+ (JSC::PostfixBracketNode::PostfixBracketNode):
+ (JSC::PostfixDotNode::PostfixDotNode):
+ (JSC::PostfixErrorNode::PostfixErrorNode):
+ (JSC::DeleteResolveNode::DeleteResolveNode):
+ (JSC::DeleteBracketNode::DeleteBracketNode):
+ (JSC::DeleteDotNode::DeleteDotNode):
+ (JSC::DeleteValueNode::DeleteValueNode):
+ (JSC::VoidNode::VoidNode):
+ (JSC::TypeOfResolveNode::TypeOfResolveNode):
+ (JSC::TypeOfValueNode::TypeOfValueNode):
+ (JSC::PrefixResolveNode::PrefixResolveNode):
+ (JSC::PrefixBracketNode::PrefixBracketNode):
+ (JSC::PrefixDotNode::PrefixDotNode):
+ (JSC::PrefixErrorNode::PrefixErrorNode):
+ (JSC::UnaryOpNode::UnaryOpNode):
+ (JSC::UnaryPlusNode::UnaryPlusNode):
+ (JSC::NegateNode::NegateNode):
+ (JSC::BitwiseNotNode::BitwiseNotNode):
+ (JSC::LogicalNotNode::LogicalNotNode):
+ (JSC::BinaryOpNode::BinaryOpNode):
+ (JSC::MultNode::MultNode):
+ (JSC::DivNode::DivNode):
+ (JSC::ModNode::ModNode):
+ (JSC::AddNode::AddNode):
+ (JSC::SubNode::SubNode):
+ (JSC::LeftShiftNode::LeftShiftNode):
+ (JSC::RightShiftNode::RightShiftNode):
+ (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode):
+ (JSC::LessNode::LessNode):
+ (JSC::GreaterNode::GreaterNode):
+ (JSC::LessEqNode::LessEqNode):
+ (JSC::GreaterEqNode::GreaterEqNode):
+ (JSC::ThrowableBinaryOpNode::ThrowableBinaryOpNode):
+ (JSC::InstanceOfNode::InstanceOfNode):
+ (JSC::InNode::InNode):
+ (JSC::EqualNode::EqualNode):
+ (JSC::NotEqualNode::NotEqualNode):
+ (JSC::StrictEqualNode::StrictEqualNode):
+ (JSC::NotStrictEqualNode::NotStrictEqualNode):
+ (JSC::BitAndNode::BitAndNode):
+ (JSC::BitOrNode::BitOrNode):
+ (JSC::BitXOrNode::BitXOrNode):
+ (JSC::LogicalOpNode::LogicalOpNode):
+ (JSC::ConditionalNode::ConditionalNode):
+ (JSC::ReadModifyResolveNode::ReadModifyResolveNode):
+ (JSC::AssignResolveNode::AssignResolveNode):
+ (JSC::ReadModifyBracketNode::ReadModifyBracketNode):
+ (JSC::AssignBracketNode::AssignBracketNode):
+ (JSC::AssignDotNode::AssignDotNode):
+ (JSC::ReadModifyDotNode::ReadModifyDotNode):
+ (JSC::AssignErrorNode::AssignErrorNode):
+ (JSC::CommaNode::CommaNode):
+ (JSC::ConstStatementNode::ConstStatementNode):
+ (JSC::EmptyStatementNode::EmptyStatementNode):
+ (JSC::DebuggerStatementNode::DebuggerStatementNode):
+ (JSC::ExprStatementNode::ExprStatementNode):
+ (JSC::VarStatementNode::VarStatementNode):
+ (JSC::IfNode::IfNode):
+ (JSC::IfElseNode::IfElseNode):
+ (JSC::DoWhileNode::DoWhileNode):
+ (JSC::WhileNode::WhileNode):
+ (JSC::ForNode::ForNode):
+ (JSC::ContinueNode::ContinueNode):
+ (JSC::BreakNode::BreakNode):
+ (JSC::ReturnNode::ReturnNode):
+ (JSC::WithNode::WithNode):
+ (JSC::LabelNode::LabelNode):
+ (JSC::ThrowNode::ThrowNode):
+ (JSC::TryNode::TryNode):
+ (JSC::FuncExprNode::FuncExprNode):
+ (JSC::FuncDeclNode::FuncDeclNode):
+ (JSC::SwitchNode::SwitchNode):
+ (JSC::ConstDeclNode::ConstDeclNode):
+ (JSC::BlockNode::BlockNode):
+ (JSC::ForInNode::ForInNode):
+ * parser/Nodes.cpp:
+ (JSC::StatementNode::setLoc):
+ (JSC):
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::ProgramNode::ProgramNode):
+ (JSC::ProgramNode::create):
+ (JSC::EvalNode::EvalNode):
+ (JSC::EvalNode::create):
+ (JSC::FunctionBodyNode::FunctionBodyNode):
+ (JSC::FunctionBodyNode::create):
+ * parser/Nodes.h:
+ (Node):
+ (JSC::Node::columnNo):
+ (ExpressionNode):
+ (StatementNode):
+ (JSC::StatementNode::column):
+ (NullNode):
+ (BooleanNode):
+ (NumberNode):
+ (StringNode):
+ (RegExpNode):
+ (ThisNode):
+ (ResolveNode):
+ (ArrayNode):
+ (PropertyListNode):
+ (ObjectLiteralNode):
+ (BracketAccessorNode):
+ (DotAccessorNode):
+ (ArgumentListNode):
+ (NewExprNode):
+ (EvalFunctionCallNode):
+ (FunctionCallValueNode):
+ (FunctionCallResolveNode):
+ (FunctionCallBracketNode):
+ (FunctionCallDotNode):
+ (CallFunctionCallDotNode):
+ (ApplyFunctionCallDotNode):
+ (PrePostResolveNode):
+ (PostfixResolveNode):
+ (PostfixBracketNode):
+ (PostfixDotNode):
+ (PostfixErrorNode):
+ (DeleteResolveNode):
+ (DeleteBracketNode):
+ (DeleteDotNode):
+ (DeleteValueNode):
+ (VoidNode):
+ (TypeOfResolveNode):
+ (TypeOfValueNode):
+ (PrefixResolveNode):
+ (PrefixBracketNode):
+ (PrefixDotNode):
+ (PrefixErrorNode):
+ (UnaryOpNode):
+ (UnaryPlusNode):
+ (NegateNode):
+ (BitwiseNotNode):
+ (LogicalNotNode):
+ (BinaryOpNode):
+ (MultNode):
+ (DivNode):
+ (ModNode):
+ (AddNode):
+ (SubNode):
+ (LeftShiftNode):
+ (RightShiftNode):
+ (UnsignedRightShiftNode):
+ (LessNode):
+ (GreaterNode):
+ (LessEqNode):
+ (GreaterEqNode):
+ (ThrowableBinaryOpNode):
+ (InstanceOfNode):
+ (InNode):
+ (EqualNode):
+ (NotEqualNode):
+ (StrictEqualNode):
+ (NotStrictEqualNode):
+ (BitAndNode):
+ (BitOrNode):
+ (BitXOrNode):
+ (LogicalOpNode):
+ (ConditionalNode):
+ (ReadModifyResolveNode):
+ (AssignResolveNode):
+ (ReadModifyBracketNode):
+ (AssignBracketNode):
+ (AssignDotNode):
+ (ReadModifyDotNode):
+ (AssignErrorNode):
+ (CommaNode):
+ (ConstDeclNode):
+ (ConstStatementNode):
+ (BlockNode):
+ (EmptyStatementNode):
+ (DebuggerStatementNode):
+ (ExprStatementNode):
+ (VarStatementNode):
+ (IfNode):
+ (IfElseNode):
+ (DoWhileNode):
+ (WhileNode):
+ (ForNode):
+ (ForInNode):
+ (ContinueNode):
+ (BreakNode):
+ (ReturnNode):
+ (WithNode):
+ (LabelNode):
+ (ThrowNode):
+ (TryNode):
+ (ScopeNode):
+ (ProgramNode):
+ (EvalNode):
+ (FunctionBodyNode):
+ (FuncExprNode):
+ (FuncDeclNode):
+ (SwitchNode):
+ * parser/Parser.cpp:
+ (JSC::::parseSourceElements):
+ (JSC::::parseVarDeclaration):
+ (JSC::::parseConstDeclaration):
+ (JSC::::parseDoWhileStatement):
+ (JSC::::parseWhileStatement):
+ (JSC::::parseVarDeclarationList):
+ (JSC::::parseConstDeclarationList):
+ (JSC::::parseForStatement):
+ (JSC::::parseBreakStatement):
+ (JSC::::parseContinueStatement):
+ (JSC::::parseReturnStatement):
+ (JSC::::parseThrowStatement):
+ (JSC::::parseWithStatement):
+ (JSC::::parseSwitchStatement):
+ (JSC::::parseTryStatement):
+ (JSC::::parseDebuggerStatement):
+ (JSC::::parseBlockStatement):
+ (JSC::::parseStatement):
+ (JSC::::parseFunctionBody):
+ (JSC::::parseFunctionInfo):
+ (JSC::::parseFunctionDeclaration):
+ (JSC::::parseExpressionOrLabelStatement):
+ (JSC::::parseExpressionStatement):
+ (JSC::::parseIfStatement):
+ (JSC::::parseExpression):
+ (JSC::::parseAssignmentExpression):
+ (JSC::::parseConditionalExpression):
+ (JSC::::parseBinaryExpression):
+ (JSC::::parseProperty):
+ (JSC::::parseObjectLiteral):
+ (JSC::::parseStrictObjectLiteral):
+ (JSC::::parseArrayLiteral):
+ (JSC::::parsePrimaryExpression):
+ (JSC::::parseArguments):
+ (JSC::::parseMemberExpression):
+ (JSC::::parseUnaryExpression):
+ * parser/Parser.h:
+ (JSC::Parser::next):
+ (JSC::Parser::nextExpectIdentifier):
+ (JSC::Parser::tokenStart):
+ (JSC::Parser::tokenLine):
+ (JSC::Parser::tokenEnd):
+ (JSC::Parser::tokenLocation):
+ (Parser):
+ (JSC::Parser::getTokenName):
+ (JSC::::parse):
+ * parser/ParserTokens.h:
+ (JSC::JSTokenLocation::JSTokenLocation):
+ (JSTokenLocation):
+ (JSToken):
+ * parser/SourceProviderCacheItem.h:
+ (JSC::SourceProviderCacheItem::closeBraceToken):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::makeFunctionCallNode):
+ (JSC::SyntaxChecker::createCommaExpr):
+ (JSC::SyntaxChecker::makeAssignNode):
+ (JSC::SyntaxChecker::makePrefixNode):
+ (JSC::SyntaxChecker::makePostfixNode):
+ (JSC::SyntaxChecker::makeTypeOfNode):
+ (JSC::SyntaxChecker::makeDeleteNode):
+ (JSC::SyntaxChecker::makeNegateNode):
+ (JSC::SyntaxChecker::makeBitwiseNotNode):
+ (JSC::SyntaxChecker::createLogicalNot):
+ (JSC::SyntaxChecker::createUnaryPlus):
+ (JSC::SyntaxChecker::createVoid):
+ (JSC::SyntaxChecker::thisExpr):
+ (JSC::SyntaxChecker::createResolve):
+ (JSC::SyntaxChecker::createObjectLiteral):
+ (JSC::SyntaxChecker::createArray):
+ (JSC::SyntaxChecker::createNumberExpr):
+ (JSC::SyntaxChecker::createString):
+ (JSC::SyntaxChecker::createBoolean):
+ (JSC::SyntaxChecker::createNull):
+ (JSC::SyntaxChecker::createBracketAccess):
+ (JSC::SyntaxChecker::createDotAccess):
+ (JSC::SyntaxChecker::createRegExp):
+ (JSC::SyntaxChecker::createNewExpr):
+ (JSC::SyntaxChecker::createConditionalExpr):
+ (JSC::SyntaxChecker::createAssignResolve):
+ (JSC::SyntaxChecker::createFunctionExpr):
+ (JSC::SyntaxChecker::createFunctionBody):
+ (JSC::SyntaxChecker::createArgumentsList):
+ (JSC::SyntaxChecker::createPropertyList):
+ (JSC::SyntaxChecker::createFuncDeclStatement):
+ (JSC::SyntaxChecker::createBlockStatement):
+ (JSC::SyntaxChecker::createExprStatement):
+ (JSC::SyntaxChecker::createIfStatement):
+ (JSC::SyntaxChecker::createForLoop):
+ (JSC::SyntaxChecker::createForInLoop):
+ (JSC::SyntaxChecker::createEmptyStatement):
+ (JSC::SyntaxChecker::createVarStatement):
+ (JSC::SyntaxChecker::createReturnStatement):
+ (JSC::SyntaxChecker::createBreakStatement):
+ (JSC::SyntaxChecker::createContinueStatement):
+ (JSC::SyntaxChecker::createTryStatement):
+ (JSC::SyntaxChecker::createSwitchStatement):
+ (JSC::SyntaxChecker::createWhileStatement):
+ (JSC::SyntaxChecker::createWithStatement):
+ (JSC::SyntaxChecker::createDoWhileStatement):
+ (JSC::SyntaxChecker::createLabelStatement):
+ (JSC::SyntaxChecker::createThrowStatement):
+ (JSC::SyntaxChecker::createDebugger):
+ (JSC::SyntaxChecker::createConstStatement):
+ (JSC::SyntaxChecker::appendConstDecl):
+ (JSC::SyntaxChecker::createGetterOrSetterProperty):
+ (JSC::SyntaxChecker::combineCommaNodes):
+ (JSC::SyntaxChecker::operatorStackPop):
+
+2012-08-03 Filip Pizlo <fpizlo@apple.com>
+
+ Crashes in dfgBuildPutByIdList when clicking on just about anything on Google Maps
+ https://bugs.webkit.org/show_bug.cgi?id=92691
+
+ Reviewed by Mark Hahnenberg.
+
+ The state of the stubs was changing after we determined the type (by virtue of the slow path
+ function that was called), since the get or put (in this case put) could cause arbitrary
+ side effects. Perhaps a full-blown fix would be to eliminate our reliance of the slow path
+ function to determine what to do, but an easier fix for now is to have the slow path give up
+ if its assumptions were invalidated by a side effect.
+
+ * dfg/DFGOperations.cpp:
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+
+2012-08-03 Filip Pizlo <fpizlo@apple.com>
+
+ DFG handling of get_by_id should always inject a ForceOSRExit node if there is no prediction
+ https://bugs.webkit.org/show_bug.cgi?id=93162
+
+ Reviewed by Mark Hahnenberg.
+
+ This simplifies the DFG IR by ensuring that all nodes that use value profiles will be preceded
+ by a ForceOSRExit if the value profile had no data.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+
+2012-08-03 Filip Pizlo <fpizlo@apple.com>
+
+ DFG::StructureCheckHoistingPhase keeps a Node& around for too long
+ https://bugs.webkit.org/show_bug.cgi?id=93157
+
+ Reviewed by Mark Hahnenberg.
+
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+
+2012-08-02 Patrick Gansterer <paroga@webkit.org>
+
+ Move getLocalTime() as static inline function to DateMath
+ https://bugs.webkit.org/show_bug.cgi?id=92955
+
+ Reviewed by Ryosuke Niwa.
+
+ getCurrentLocalTime() and getLocalTime() has been superseded with the
+ GregorianDateTime class. So we can move it into DateMath.cpp as an static inline
+ function. This allows us to remove the dependecy on time() and localtime()
+ for Windows CE, where this functions require the ce_time library to work.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-08-02 Filip Pizlo <fpizlo@apple.com>
+
+ ASSERTION FAILED: at(m_compileIndex).canExit() || m_isCheckingArgumentTypes
+ https://bugs.webkit.org/show_bug.cgi?id=91074
+
+ Reviewed by Mark Hahnenberg.
+
+ Fixes a bug where the speculative JIT was performing an unnecessary speculation that the
+ CFA had proven shouldn't be performed, leading to asserts that a node should not have
+ exit sites. This is a debug-only assert with no release symptom - we were just emitting
+ a check that was not reachable.
+
+ Also found, and fixed, a bug where structure check hoisting was slightly confusing the
+ CFA by inserting GetLocal's into the graph. CSE would clean the GetLocal's up, which
+ would make the backend happy - but the CFA would produce subtly wrong results.
+
+ * bytecode/SpeculatedType.h:
+ (JSC::isOtherOrEmptySpeculation):
+ (JSC):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
+
+2012-08-02 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, build fix for DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE).
+
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+
+2012-08-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Remove all uses of ClassInfo for JSStrings in JIT code
+ https://bugs.webkit.org/show_bug.cgi?id=92935
+
+ Reviewed by Geoffrey Garen.
+
+ This is the first step in removing our dependence on in-object ClassInfo pointers
+ in JIT code. Most of the changes are to check the Structure, which is unique for
+ JSString primitives.
+
+ * bytecode/SpeculatedType.cpp:
+ (JSC::speculationFromClassInfo):
+ (JSC::speculationFromStructure): Changed to check the TypeInfo in the Structure
+ since there wasn't a JSGlobalData immediately available to grab the JSString
+ Structure out of.
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitLoadCharacterString):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::emit_op_to_primitive):
+ (JSC::JIT::emit_op_convert_this):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ (JSC::JIT::emit_op_to_primitive):
+ (JSC::JIT::emitSlow_op_eq):
+ (JSC::JIT::emitSlow_op_neq):
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emit_op_convert_this):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::stringGetByValStubGenerator):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::stringGetByValStubGenerator):
+ (JSC::JIT::emitSlow_op_get_by_val):
+ * jit/SpecializedThunkJIT.h:
+ (JSC::SpecializedThunkJIT::loadJSStringArgument):
+ * jit/ThunkGenerators.cpp:
+ (JSC::stringCharLoad):
+ (JSC::charCodeAtThunkGenerator):
+ (JSC::charAtThunkGenerator):
+
+2012-08-02 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, missed a style goof in the previous patch: "NodeIndex nodeIndex"
+ in a method signature is painfully redundant.
+
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+
+2012-08-02 Filip Pizlo <fpizlo@apple.com>
+
+ DFGSpeculativeJIT.h has too many inline method bodies
+ https://bugs.webkit.org/show_bug.cgi?id=92957
+
+ Reviewed by Antti Koivisto.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::speculationCheck):
+ (DFG):
+ (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
+ (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
+ (JSC::DFG::SpeculativeJIT::speculationCheckWithConditionalDirection):
+ (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
+ (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+
+2012-08-01 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r124406.
+ http://trac.webkit.org/changeset/124406
+ https://bugs.webkit.org/show_bug.cgi?id=92951
+
+ it set the Mac bots on fire (Requested by pizlo on #webkit).
+
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitDebugHook):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ArrayNode::toArgumentList):
+ (JSC::ApplyFunctionCallDotNode::emitBytecode):
+ (JSC::ConditionalNode::emitBytecode):
+ (JSC::ConstStatementNode::emitBytecode):
+ (JSC::EmptyStatementNode::emitBytecode):
+ (JSC::DebuggerStatementNode::emitBytecode):
+ (JSC::ExprStatementNode::emitBytecode):
+ (JSC::VarStatementNode::emitBytecode):
+ (JSC::IfNode::emitBytecode):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::ContinueNode::emitBytecode):
+ (JSC::BreakNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::WithNode::emitBytecode):
+ (JSC::SwitchNode::emitBytecode):
+ (JSC::LabelNode::emitBytecode):
+ (JSC::ThrowNode::emitBytecode):
+ (JSC::TryNode::emitBytecode):
+ (JSC::ProgramNode::emitBytecode):
+ (JSC::EvalNode::emitBytecode):
+ (JSC::FunctionBodyNode::emitBytecode):
+ * debugger/Debugger.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::debug):
+ * interpreter/Interpreter.h:
+ (Interpreter):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_debug):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_debug):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * parser/ASTBuilder.h:
+ (ASTBuilder):
+ (JSC::ASTBuilder::createCommaExpr):
+ (JSC::ASTBuilder::createLogicalNot):
+ (JSC::ASTBuilder::createUnaryPlus):
+ (JSC::ASTBuilder::createVoid):
+ (JSC::ASTBuilder::thisExpr):
+ (JSC::ASTBuilder::createResolve):
+ (JSC::ASTBuilder::createObjectLiteral):
+ (JSC::ASTBuilder::createArray):
+ (JSC::ASTBuilder::createNumberExpr):
+ (JSC::ASTBuilder::createString):
+ (JSC::ASTBuilder::createBoolean):
+ (JSC::ASTBuilder::createNull):
+ (JSC::ASTBuilder::createBracketAccess):
+ (JSC::ASTBuilder::createDotAccess):
+ (JSC::ASTBuilder::createRegExp):
+ (JSC::ASTBuilder::createNewExpr):
+ (JSC::ASTBuilder::createConditionalExpr):
+ (JSC::ASTBuilder::createAssignResolve):
+ (JSC::ASTBuilder::createFunctionExpr):
+ (JSC::ASTBuilder::createFunctionBody):
+ (JSC::ASTBuilder::createGetterOrSetterProperty):
+ (JSC::ASTBuilder::createArgumentsList):
+ (JSC::ASTBuilder::createPropertyList):
+ (JSC::ASTBuilder::createFuncDeclStatement):
+ (JSC::ASTBuilder::createBlockStatement):
+ (JSC::ASTBuilder::createExprStatement):
+ (JSC::ASTBuilder::createIfStatement):
+ (JSC::ASTBuilder::createForLoop):
+ (JSC::ASTBuilder::createForInLoop):
+ (JSC::ASTBuilder::createEmptyStatement):
+ (JSC::ASTBuilder::createVarStatement):
+ (JSC::ASTBuilder::createReturnStatement):
+ (JSC::ASTBuilder::createBreakStatement):
+ (JSC::ASTBuilder::createContinueStatement):
+ (JSC::ASTBuilder::createTryStatement):
+ (JSC::ASTBuilder::createSwitchStatement):
+ (JSC::ASTBuilder::createWhileStatement):
+ (JSC::ASTBuilder::createDoWhileStatement):
+ (JSC::ASTBuilder::createLabelStatement):
+ (JSC::ASTBuilder::createWithStatement):
+ (JSC::ASTBuilder::createThrowStatement):
+ (JSC::ASTBuilder::createDebugger):
+ (JSC::ASTBuilder::createConstStatement):
+ (JSC::ASTBuilder::appendConstDecl):
+ (JSC::ASTBuilder::combineCommaNodes):
+ (JSC::ASTBuilder::appendBinaryOperation):
+ (JSC::ASTBuilder::createAssignment):
+ (JSC::ASTBuilder::createNumber):
+ (JSC::ASTBuilder::makeTypeOfNode):
+ (JSC::ASTBuilder::makeDeleteNode):
+ (JSC::ASTBuilder::makeNegateNode):
+ (JSC::ASTBuilder::makeBitwiseNotNode):
+ (JSC::ASTBuilder::makeMultNode):
+ (JSC::ASTBuilder::makeDivNode):
+ (JSC::ASTBuilder::makeModNode):
+ (JSC::ASTBuilder::makeAddNode):
+ (JSC::ASTBuilder::makeSubNode):
+ (JSC::ASTBuilder::makeLeftShiftNode):
+ (JSC::ASTBuilder::makeRightShiftNode):
+ (JSC::ASTBuilder::makeURightShiftNode):
+ (JSC::ASTBuilder::makeBitOrNode):
+ (JSC::ASTBuilder::makeBitAndNode):
+ (JSC::ASTBuilder::makeBitXOrNode):
+ (JSC::ASTBuilder::makeFunctionCallNode):
+ (JSC::ASTBuilder::makeBinaryNode):
+ (JSC::ASTBuilder::makeAssignNode):
+ (JSC::ASTBuilder::makePrefixNode):
+ (JSC::ASTBuilder::makePostfixNode):
+ * parser/Lexer.cpp:
+ (JSC::::setCode):
+ (JSC::::internalShift):
+ (JSC::::shift):
+ (JSC::::lex):
+ * parser/Lexer.h:
+ (Lexer):
+ (JSC::::lexExpectIdentifier):
+ * parser/NodeConstructors.h:
+ (JSC::Node::Node):
+ (JSC::ExpressionNode::ExpressionNode):
+ (JSC::StatementNode::StatementNode):
+ (JSC::NullNode::NullNode):
+ (JSC::BooleanNode::BooleanNode):
+ (JSC::NumberNode::NumberNode):
+ (JSC::StringNode::StringNode):
+ (JSC::RegExpNode::RegExpNode):
+ (JSC::ThisNode::ThisNode):
+ (JSC::ResolveNode::ResolveNode):
+ (JSC::ArrayNode::ArrayNode):
+ (JSC::PropertyListNode::PropertyListNode):
+ (JSC::ObjectLiteralNode::ObjectLiteralNode):
+ (JSC::BracketAccessorNode::BracketAccessorNode):
+ (JSC::DotAccessorNode::DotAccessorNode):
+ (JSC::ArgumentListNode::ArgumentListNode):
+ (JSC::NewExprNode::NewExprNode):
+ (JSC::EvalFunctionCallNode::EvalFunctionCallNode):
+ (JSC::FunctionCallValueNode::FunctionCallValueNode):
+ (JSC::FunctionCallResolveNode::FunctionCallResolveNode):
+ (JSC::FunctionCallBracketNode::FunctionCallBracketNode):
+ (JSC::FunctionCallDotNode::FunctionCallDotNode):
+ (JSC::CallFunctionCallDotNode::CallFunctionCallDotNode):
+ (JSC::ApplyFunctionCallDotNode::ApplyFunctionCallDotNode):
+ (JSC::PrePostResolveNode::PrePostResolveNode):
+ (JSC::PostfixResolveNode::PostfixResolveNode):
+ (JSC::PostfixBracketNode::PostfixBracketNode):
+ (JSC::PostfixDotNode::PostfixDotNode):
+ (JSC::PostfixErrorNode::PostfixErrorNode):
+ (JSC::DeleteResolveNode::DeleteResolveNode):
+ (JSC::DeleteBracketNode::DeleteBracketNode):
+ (JSC::DeleteDotNode::DeleteDotNode):
+ (JSC::DeleteValueNode::DeleteValueNode):
+ (JSC::VoidNode::VoidNode):
+ (JSC::TypeOfResolveNode::TypeOfResolveNode):
+ (JSC::TypeOfValueNode::TypeOfValueNode):
+ (JSC::PrefixResolveNode::PrefixResolveNode):
+ (JSC::PrefixBracketNode::PrefixBracketNode):
+ (JSC::PrefixDotNode::PrefixDotNode):
+ (JSC::PrefixErrorNode::PrefixErrorNode):
+ (JSC::UnaryOpNode::UnaryOpNode):
+ (JSC::UnaryPlusNode::UnaryPlusNode):
+ (JSC::NegateNode::NegateNode):
+ (JSC::BitwiseNotNode::BitwiseNotNode):
+ (JSC::LogicalNotNode::LogicalNotNode):
+ (JSC::BinaryOpNode::BinaryOpNode):
+ (JSC::MultNode::MultNode):
+ (JSC::DivNode::DivNode):
+ (JSC::ModNode::ModNode):
+ (JSC::AddNode::AddNode):
+ (JSC::SubNode::SubNode):
+ (JSC::LeftShiftNode::LeftShiftNode):
+ (JSC::RightShiftNode::RightShiftNode):
+ (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode):
+ (JSC::LessNode::LessNode):
+ (JSC::GreaterNode::GreaterNode):
+ (JSC::LessEqNode::LessEqNode):
+ (JSC::GreaterEqNode::GreaterEqNode):
+ (JSC::ThrowableBinaryOpNode::ThrowableBinaryOpNode):
+ (JSC::InstanceOfNode::InstanceOfNode):
+ (JSC::InNode::InNode):
+ (JSC::EqualNode::EqualNode):
+ (JSC::NotEqualNode::NotEqualNode):
+ (JSC::StrictEqualNode::StrictEqualNode):
+ (JSC::NotStrictEqualNode::NotStrictEqualNode):
+ (JSC::BitAndNode::BitAndNode):
+ (JSC::BitOrNode::BitOrNode):
+ (JSC::BitXOrNode::BitXOrNode):
+ (JSC::LogicalOpNode::LogicalOpNode):
+ (JSC::ConditionalNode::ConditionalNode):
+ (JSC::ReadModifyResolveNode::ReadModifyResolveNode):
+ (JSC::AssignResolveNode::AssignResolveNode):
+ (JSC::ReadModifyBracketNode::ReadModifyBracketNode):
+ (JSC::AssignBracketNode::AssignBracketNode):
+ (JSC::AssignDotNode::AssignDotNode):
+ (JSC::ReadModifyDotNode::ReadModifyDotNode):
+ (JSC::AssignErrorNode::AssignErrorNode):
+ (JSC::CommaNode::CommaNode):
+ (JSC::ConstStatementNode::ConstStatementNode):
+ (JSC::EmptyStatementNode::EmptyStatementNode):
+ (JSC::DebuggerStatementNode::DebuggerStatementNode):
+ (JSC::ExprStatementNode::ExprStatementNode):
+ (JSC::VarStatementNode::VarStatementNode):
+ (JSC::IfNode::IfNode):
+ (JSC::IfElseNode::IfElseNode):
+ (JSC::DoWhileNode::DoWhileNode):
+ (JSC::WhileNode::WhileNode):
+ (JSC::ForNode::ForNode):
+ (JSC::ContinueNode::ContinueNode):
+ (JSC::BreakNode::BreakNode):
+ (JSC::ReturnNode::ReturnNode):
+ (JSC::WithNode::WithNode):
+ (JSC::LabelNode::LabelNode):
+ (JSC::ThrowNode::ThrowNode):
+ (JSC::TryNode::TryNode):
+ (JSC::FuncExprNode::FuncExprNode):
+ (JSC::FuncDeclNode::FuncDeclNode):
+ (JSC::SwitchNode::SwitchNode):
+ (JSC::ConstDeclNode::ConstDeclNode):
+ (JSC::BlockNode::BlockNode):
+ (JSC::ForInNode::ForInNode):
+ * parser/Nodes.cpp:
+ (JSC):
+ (JSC::StatementNode::setLoc):
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::ProgramNode::ProgramNode):
+ (JSC::ProgramNode::create):
+ (JSC::EvalNode::EvalNode):
+ (JSC::EvalNode::create):
+ (JSC::FunctionBodyNode::FunctionBodyNode):
+ (JSC::FunctionBodyNode::create):
+ * parser/Nodes.h:
+ (Node):
+ (ExpressionNode):
+ (StatementNode):
+ (NullNode):
+ (BooleanNode):
+ (NumberNode):
+ (StringNode):
+ (RegExpNode):
+ (ThisNode):
+ (ResolveNode):
+ (ArrayNode):
+ (PropertyListNode):
+ (ObjectLiteralNode):
+ (BracketAccessorNode):
+ (DotAccessorNode):
+ (ArgumentListNode):
+ (NewExprNode):
+ (EvalFunctionCallNode):
+ (FunctionCallValueNode):
+ (FunctionCallResolveNode):
+ (FunctionCallBracketNode):
+ (FunctionCallDotNode):
+ (CallFunctionCallDotNode):
+ (ApplyFunctionCallDotNode):
+ (PrePostResolveNode):
+ (PostfixResolveNode):
+ (PostfixBracketNode):
+ (PostfixDotNode):
+ (PostfixErrorNode):
+ (DeleteResolveNode):
+ (DeleteBracketNode):
+ (DeleteDotNode):
+ (DeleteValueNode):
+ (VoidNode):
+ (TypeOfResolveNode):
+ (TypeOfValueNode):
+ (PrefixResolveNode):
+ (PrefixBracketNode):
+ (PrefixDotNode):
+ (PrefixErrorNode):
+ (UnaryOpNode):
+ (UnaryPlusNode):
+ (NegateNode):
+ (BitwiseNotNode):
+ (LogicalNotNode):
+ (BinaryOpNode):
+ (MultNode):
+ (DivNode):
+ (ModNode):
+ (AddNode):
+ (SubNode):
+ (LeftShiftNode):
+ (RightShiftNode):
+ (UnsignedRightShiftNode):
+ (LessNode):
+ (GreaterNode):
+ (LessEqNode):
+ (GreaterEqNode):
+ (ThrowableBinaryOpNode):
+ (InstanceOfNode):
+ (InNode):
+ (EqualNode):
+ (NotEqualNode):
+ (StrictEqualNode):
+ (NotStrictEqualNode):
+ (BitAndNode):
+ (BitOrNode):
+ (BitXOrNode):
+ (LogicalOpNode):
+ (ConditionalNode):
+ (ReadModifyResolveNode):
+ (AssignResolveNode):
+ (ReadModifyBracketNode):
+ (AssignBracketNode):
+ (AssignDotNode):
+ (ReadModifyDotNode):
+ (AssignErrorNode):
+ (CommaNode):
+ (ConstDeclNode):
+ (ConstStatementNode):
+ (BlockNode):
+ (EmptyStatementNode):
+ (DebuggerStatementNode):
+ (ExprStatementNode):
+ (VarStatementNode):
+ (IfNode):
+ (IfElseNode):
+ (DoWhileNode):
+ (WhileNode):
+ (ForNode):
+ (ForInNode):
+ (ContinueNode):
+ (BreakNode):
+ (ReturnNode):
+ (WithNode):
+ (LabelNode):
+ (ThrowNode):
+ (TryNode):
+ (ScopeNode):
+ (ProgramNode):
+ (EvalNode):
+ (FunctionBodyNode):
+ (FuncExprNode):
+ (FuncDeclNode):
+ (SwitchNode):
+ * parser/Parser.cpp:
+ (JSC::::parseSourceElements):
+ (JSC::::parseVarDeclaration):
+ (JSC::::parseConstDeclaration):
+ (JSC::::parseDoWhileStatement):
+ (JSC::::parseWhileStatement):
+ (JSC::::parseVarDeclarationList):
+ (JSC::::parseConstDeclarationList):
+ (JSC::::parseForStatement):
+ (JSC::::parseBreakStatement):
+ (JSC::::parseContinueStatement):
+ (JSC::::parseReturnStatement):
+ (JSC::::parseThrowStatement):
+ (JSC::::parseWithStatement):
+ (JSC::::parseSwitchStatement):
+ (JSC::::parseTryStatement):
+ (JSC::::parseDebuggerStatement):
+ (JSC::::parseBlockStatement):
+ (JSC::::parseStatement):
+ (JSC::::parseFunctionBody):
+ (JSC::::parseFunctionInfo):
+ (JSC::::parseFunctionDeclaration):
+ (JSC::::parseExpressionOrLabelStatement):
+ (JSC::::parseExpressionStatement):
+ (JSC::::parseIfStatement):
+ (JSC::::parseExpression):
+ (JSC::::parseAssignmentExpression):
+ (JSC::::parseConditionalExpression):
+ (JSC::::parseBinaryExpression):
+ (JSC::::parseProperty):
+ (JSC::::parseObjectLiteral):
+ (JSC::::parseStrictObjectLiteral):
+ (JSC::::parseArrayLiteral):
+ (JSC::::parsePrimaryExpression):
+ (JSC::::parseArguments):
+ (JSC::::parseMemberExpression):
+ (JSC::::parseUnaryExpression):
+ * parser/Parser.h:
+ (JSC::Parser::next):
+ (JSC::Parser::nextExpectIdentifier):
+ (JSC::Parser::tokenStart):
+ (JSC::Parser::tokenLine):
+ (JSC::Parser::tokenEnd):
+ (JSC::Parser::getTokenName):
+ (JSC::::parse):
+ * parser/ParserTokens.h:
+ (JSC::JSTokenInfo::JSTokenInfo):
+ (JSTokenInfo):
+ (JSToken):
+ * parser/SourceProviderCacheItem.h:
+ (JSC::SourceProviderCacheItem::closeBraceToken):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::makeFunctionCallNode):
+ (JSC::SyntaxChecker::createCommaExpr):
+ (JSC::SyntaxChecker::makeAssignNode):
+ (JSC::SyntaxChecker::makePrefixNode):
+ (JSC::SyntaxChecker::makePostfixNode):
+ (JSC::SyntaxChecker::makeTypeOfNode):
+ (JSC::SyntaxChecker::makeDeleteNode):
+ (JSC::SyntaxChecker::makeNegateNode):
+ (JSC::SyntaxChecker::makeBitwiseNotNode):
+ (JSC::SyntaxChecker::createLogicalNot):
+ (JSC::SyntaxChecker::createUnaryPlus):
+ (JSC::SyntaxChecker::createVoid):
+ (JSC::SyntaxChecker::thisExpr):
+ (JSC::SyntaxChecker::createResolve):
+ (JSC::SyntaxChecker::createObjectLiteral):
+ (JSC::SyntaxChecker::createArray):
+ (JSC::SyntaxChecker::createNumberExpr):
+ (JSC::SyntaxChecker::createString):
+ (JSC::SyntaxChecker::createBoolean):
+ (JSC::SyntaxChecker::createNull):
+ (JSC::SyntaxChecker::createBracketAccess):
+ (JSC::SyntaxChecker::createDotAccess):
+ (JSC::SyntaxChecker::createRegExp):
+ (JSC::SyntaxChecker::createNewExpr):
+ (JSC::SyntaxChecker::createConditionalExpr):
+ (JSC::SyntaxChecker::createAssignResolve):
+ (JSC::SyntaxChecker::createFunctionExpr):
+ (JSC::SyntaxChecker::createFunctionBody):
+ (JSC::SyntaxChecker::createArgumentsList):
+ (JSC::SyntaxChecker::createPropertyList):
+ (JSC::SyntaxChecker::createFuncDeclStatement):
+ (JSC::SyntaxChecker::createBlockStatement):
+ (JSC::SyntaxChecker::createExprStatement):
+ (JSC::SyntaxChecker::createIfStatement):
+ (JSC::SyntaxChecker::createForLoop):
+ (JSC::SyntaxChecker::createForInLoop):
+ (JSC::SyntaxChecker::createEmptyStatement):
+ (JSC::SyntaxChecker::createVarStatement):
+ (JSC::SyntaxChecker::createReturnStatement):
+ (JSC::SyntaxChecker::createBreakStatement):
+ (JSC::SyntaxChecker::createContinueStatement):
+ (JSC::SyntaxChecker::createTryStatement):
+ (JSC::SyntaxChecker::createSwitchStatement):
+ (JSC::SyntaxChecker::createWhileStatement):
+ (JSC::SyntaxChecker::createWithStatement):
+ (JSC::SyntaxChecker::createDoWhileStatement):
+ (JSC::SyntaxChecker::createLabelStatement):
+ (JSC::SyntaxChecker::createThrowStatement):
+ (JSC::SyntaxChecker::createDebugger):
+ (JSC::SyntaxChecker::createConstStatement):
+ (JSC::SyntaxChecker::appendConstDecl):
+ (JSC::SyntaxChecker::createGetterOrSetterProperty):
+ (JSC::SyntaxChecker::combineCommaNodes):
+ (JSC::SyntaxChecker::operatorStackPop):
+
+2012-08-01 Peter Wang <peter.wang@torchmobile.com.cn>
+
+ Web Inspector: [JSC] implement setting breakpoints by line:column
+ https://bugs.webkit.org/show_bug.cgi?id=53003
+
+ Reviewed by Geoffrey Garen.
+
+ Add a counter in lexer to record the column of each token. Debugger will use column info
+ in "Pretty Print" debug mode of Inspector.
+
+ * bytecode/Opcode.h:
+ (JSC):
+ (JSC::padOpcodeName):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitDebugHook):
+ * bytecompiler/BytecodeGenerator.h:
+ (BytecodeGenerator):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ArrayNode::toArgumentList):
+ (JSC::ApplyFunctionCallDotNode::emitBytecode):
+ (JSC::ConditionalNode::emitBytecode):
+ (JSC::ConstStatementNode::emitBytecode):
+ (JSC::EmptyStatementNode::emitBytecode):
+ (JSC::DebuggerStatementNode::emitBytecode):
+ (JSC::ExprStatementNode::emitBytecode):
+ (JSC::VarStatementNode::emitBytecode):
+ (JSC::IfNode::emitBytecode):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::ContinueNode::emitBytecode):
+ (JSC::BreakNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::WithNode::emitBytecode):
+ (JSC::SwitchNode::emitBytecode):
+ (JSC::LabelNode::emitBytecode):
+ (JSC::ThrowNode::emitBytecode):
+ (JSC::TryNode::emitBytecode):
+ (JSC::ProgramNode::emitBytecode):
+ (JSC::EvalNode::emitBytecode):
+ (JSC::FunctionBodyNode::emitBytecode):
+ * debugger/Debugger.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::debug):
+ * interpreter/Interpreter.h:
+ (Interpreter):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_debug):
+ * jit/JITOpcodes32_64.cpp:
+ (JSC::JIT::emit_op_debug):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+ * parser/ASTBuilder.h:
+ (ASTBuilder):
+ (JSC::ASTBuilder::createCommaExpr):
+ (JSC::ASTBuilder::createLogicalNot):
+ (JSC::ASTBuilder::createUnaryPlus):
+ (JSC::ASTBuilder::createVoid):
+ (JSC::ASTBuilder::thisExpr):
+ (JSC::ASTBuilder::createResolve):
+ (JSC::ASTBuilder::createObjectLiteral):
+ (JSC::ASTBuilder::createArray):
+ (JSC::ASTBuilder::createNumberExpr):
+ (JSC::ASTBuilder::createString):
+ (JSC::ASTBuilder::createBoolean):
+ (JSC::ASTBuilder::createNull):
+ (JSC::ASTBuilder::createBracketAccess):
+ (JSC::ASTBuilder::createDotAccess):
+ (JSC::ASTBuilder::createRegExp):
+ (JSC::ASTBuilder::createNewExpr):
+ (JSC::ASTBuilder::createConditionalExpr):
+ (JSC::ASTBuilder::createAssignResolve):
+ (JSC::ASTBuilder::createFunctionExpr):
+ (JSC::ASTBuilder::createFunctionBody):
+ (JSC::ASTBuilder::createGetterOrSetterProperty):
+ (JSC::ASTBuilder::createArgumentsList):
+ (JSC::ASTBuilder::createPropertyList):
+ (JSC::ASTBuilder::createFuncDeclStatement):
+ (JSC::ASTBuilder::createBlockStatement):
+ (JSC::ASTBuilder::createExprStatement):
+ (JSC::ASTBuilder::createIfStatement):
+ (JSC::ASTBuilder::createForLoop):
+ (JSC::ASTBuilder::createForInLoop):
+ (JSC::ASTBuilder::createEmptyStatement):
+ (JSC::ASTBuilder::createVarStatement):
+ (JSC::ASTBuilder::createReturnStatement):
+ (JSC::ASTBuilder::createBreakStatement):
+ (JSC::ASTBuilder::createContinueStatement):
+ (JSC::ASTBuilder::createTryStatement):
+ (JSC::ASTBuilder::createSwitchStatement):
+ (JSC::ASTBuilder::createWhileStatement):
+ (JSC::ASTBuilder::createDoWhileStatement):
+ (JSC::ASTBuilder::createLabelStatement):
+ (JSC::ASTBuilder::createWithStatement):
+ (JSC::ASTBuilder::createThrowStatement):
+ (JSC::ASTBuilder::createDebugger):
+ (JSC::ASTBuilder::createConstStatement):
+ (JSC::ASTBuilder::appendConstDecl):
+ (JSC::ASTBuilder::combineCommaNodes):
+ (JSC::ASTBuilder::appendBinaryOperation):
+ (JSC::ASTBuilder::createAssignment):
+ (JSC::ASTBuilder::createNumber):
+ (JSC::ASTBuilder::makeTypeOfNode):
+ (JSC::ASTBuilder::makeDeleteNode):
+ (JSC::ASTBuilder::makeNegateNode):
+ (JSC::ASTBuilder::makeBitwiseNotNode):
+ (JSC::ASTBuilder::makeMultNode):
+ (JSC::ASTBuilder::makeDivNode):
+ (JSC::ASTBuilder::makeModNode):
+ (JSC::ASTBuilder::makeAddNode):
+ (JSC::ASTBuilder::makeSubNode):
+ (JSC::ASTBuilder::makeLeftShiftNode):
+ (JSC::ASTBuilder::makeRightShiftNode):
+ (JSC::ASTBuilder::makeURightShiftNode):
+ (JSC::ASTBuilder::makeBitOrNode):
+ (JSC::ASTBuilder::makeBitAndNode):
+ (JSC::ASTBuilder::makeBitXOrNode):
+ (JSC::ASTBuilder::makeFunctionCallNode):
+ (JSC::ASTBuilder::makeBinaryNode):
+ (JSC::ASTBuilder::makeAssignNode):
+ (JSC::ASTBuilder::makePrefixNode):
+ (JSC::ASTBuilder::makePostfixNode):
+ * parser/Lexer.cpp:
+ (JSC::::setCode):
+ (JSC::::internalShift):
+ (JSC::::shift):
+ (JSC::::lex):
+ * parser/Lexer.h:
+ (Lexer):
+ (JSC::Lexer::currentColumnNumber):
+ (JSC::::lexExpectIdentifier):
+ * parser/NodeConstructors.h:
+ (JSC::Node::Node):
+ (JSC::ExpressionNode::ExpressionNode):
+ (JSC::StatementNode::StatementNode):
+ (JSC::NullNode::NullNode):
+ (JSC::BooleanNode::BooleanNode):
+ (JSC::NumberNode::NumberNode):
+ (JSC::StringNode::StringNode):
+ (JSC::RegExpNode::RegExpNode):
+ (JSC::ThisNode::ThisNode):
+ (JSC::ResolveNode::ResolveNode):
+ (JSC::ArrayNode::ArrayNode):
+ (JSC::PropertyListNode::PropertyListNode):
+ (JSC::ObjectLiteralNode::ObjectLiteralNode):
+ (JSC::BracketAccessorNode::BracketAccessorNode):
+ (JSC::DotAccessorNode::DotAccessorNode):
+ (JSC::ArgumentListNode::ArgumentListNode):
+ (JSC::NewExprNode::NewExprNode):
+ (JSC::EvalFunctionCallNode::EvalFunctionCallNode):
+ (JSC::FunctionCallValueNode::FunctionCallValueNode):
+ (JSC::FunctionCallResolveNode::FunctionCallResolveNode):
+ (JSC::FunctionCallBracketNode::FunctionCallBracketNode):
+ (JSC::FunctionCallDotNode::FunctionCallDotNode):
+ (JSC::CallFunctionCallDotNode::CallFunctionCallDotNode):
+ (JSC::ApplyFunctionCallDotNode::ApplyFunctionCallDotNode):
+ (JSC::PrePostResolveNode::PrePostResolveNode):
+ (JSC::PostfixResolveNode::PostfixResolveNode):
+ (JSC::PostfixBracketNode::PostfixBracketNode):
+ (JSC::PostfixDotNode::PostfixDotNode):
+ (JSC::PostfixErrorNode::PostfixErrorNode):
+ (JSC::DeleteResolveNode::DeleteResolveNode):
+ (JSC::DeleteBracketNode::DeleteBracketNode):
+ (JSC::DeleteDotNode::DeleteDotNode):
+ (JSC::DeleteValueNode::DeleteValueNode):
+ (JSC::VoidNode::VoidNode):
+ (JSC::TypeOfResolveNode::TypeOfResolveNode):
+ (JSC::TypeOfValueNode::TypeOfValueNode):
+ (JSC::PrefixResolveNode::PrefixResolveNode):
+ (JSC::PrefixBracketNode::PrefixBracketNode):
+ (JSC::PrefixDotNode::PrefixDotNode):
+ (JSC::PrefixErrorNode::PrefixErrorNode):
+ (JSC::UnaryOpNode::UnaryOpNode):
+ (JSC::UnaryPlusNode::UnaryPlusNode):
+ (JSC::NegateNode::NegateNode):
+ (JSC::BitwiseNotNode::BitwiseNotNode):
+ (JSC::LogicalNotNode::LogicalNotNode):
+ (JSC::BinaryOpNode::BinaryOpNode):
+ (JSC::MultNode::MultNode):
+ (JSC::DivNode::DivNode):
+ (JSC::ModNode::ModNode):
+ (JSC::AddNode::AddNode):
+ (JSC::SubNode::SubNode):
+ (JSC::LeftShiftNode::LeftShiftNode):
+ (JSC::RightShiftNode::RightShiftNode):
+ (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode):
+ (JSC::LessNode::LessNode):
+ (JSC::GreaterNode::GreaterNode):
+ (JSC::LessEqNode::LessEqNode):
+ (JSC::GreaterEqNode::GreaterEqNode):
+ (JSC::ThrowableBinaryOpNode::ThrowableBinaryOpNode):
+ (JSC::InstanceOfNode::InstanceOfNode):
+ (JSC::InNode::InNode):
+ (JSC::EqualNode::EqualNode):
+ (JSC::NotEqualNode::NotEqualNode):
+ (JSC::StrictEqualNode::StrictEqualNode):
+ (JSC::NotStrictEqualNode::NotStrictEqualNode):
+ (JSC::BitAndNode::BitAndNode):
+ (JSC::BitOrNode::BitOrNode):
+ (JSC::BitXOrNode::BitXOrNode):
+ (JSC::LogicalOpNode::LogicalOpNode):
+ (JSC::ConditionalNode::ConditionalNode):
+ (JSC::ReadModifyResolveNode::ReadModifyResolveNode):
+ (JSC::AssignResolveNode::AssignResolveNode):
+ (JSC::ReadModifyBracketNode::ReadModifyBracketNode):
+ (JSC::AssignBracketNode::AssignBracketNode):
+ (JSC::AssignDotNode::AssignDotNode):
+ (JSC::ReadModifyDotNode::ReadModifyDotNode):
+ (JSC::AssignErrorNode::AssignErrorNode):
+ (JSC::CommaNode::CommaNode):
+ (JSC::ConstStatementNode::ConstStatementNode):
+ (JSC::EmptyStatementNode::EmptyStatementNode):
+ (JSC::DebuggerStatementNode::DebuggerStatementNode):
+ (JSC::ExprStatementNode::ExprStatementNode):
+ (JSC::VarStatementNode::VarStatementNode):
+ (JSC::IfNode::IfNode):
+ (JSC::IfElseNode::IfElseNode):
+ (JSC::DoWhileNode::DoWhileNode):
+ (JSC::WhileNode::WhileNode):
+ (JSC::ForNode::ForNode):
+ (JSC::ContinueNode::ContinueNode):
+ (JSC::BreakNode::BreakNode):
+ (JSC::ReturnNode::ReturnNode):
+ (JSC::WithNode::WithNode):
+ (JSC::LabelNode::LabelNode):
+ (JSC::ThrowNode::ThrowNode):
+ (JSC::TryNode::TryNode):
+ (JSC::FuncExprNode::FuncExprNode):
+ (JSC::FuncDeclNode::FuncDeclNode):
+ (JSC::SwitchNode::SwitchNode):
+ (JSC::ConstDeclNode::ConstDeclNode):
+ (JSC::BlockNode::BlockNode):
+ (JSC::ForInNode::ForInNode):
+ * parser/Nodes.cpp:
+ (JSC::StatementNode::setLoc):
+ (JSC):
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::ProgramNode::ProgramNode):
+ (JSC::ProgramNode::create):
+ (JSC::EvalNode::EvalNode):
+ (JSC::EvalNode::create):
+ (JSC::FunctionBodyNode::FunctionBodyNode):
+ (JSC::FunctionBodyNode::create):
+ * parser/Nodes.h:
+ (Node):
+ (JSC::Node::columnNo):
+ (ExpressionNode):
+ (StatementNode):
+ (JSC::StatementNode::column):
+ (NullNode):
+ (BooleanNode):
+ (NumberNode):
+ (StringNode):
+ (RegExpNode):
+ (ThisNode):
+ (ResolveNode):
+ (ArrayNode):
+ (PropertyListNode):
+ (ObjectLiteralNode):
+ (BracketAccessorNode):
+ (DotAccessorNode):
+ (ArgumentListNode):
+ (NewExprNode):
+ (EvalFunctionCallNode):
+ (FunctionCallValueNode):
+ (FunctionCallResolveNode):
+ (FunctionCallBracketNode):
+ (FunctionCallDotNode):
+ (CallFunctionCallDotNode):
+ (ApplyFunctionCallDotNode):
+ (PrePostResolveNode):
+ (PostfixResolveNode):
+ (PostfixBracketNode):
+ (PostfixDotNode):
+ (PostfixErrorNode):
+ (DeleteResolveNode):
+ (DeleteBracketNode):
+ (DeleteDotNode):
+ (DeleteValueNode):
+ (VoidNode):
+ (TypeOfResolveNode):
+ (TypeOfValueNode):
+ (PrefixResolveNode):
+ (PrefixBracketNode):
+ (PrefixDotNode):
+ (PrefixErrorNode):
+ (UnaryOpNode):
+ (UnaryPlusNode):
+ (NegateNode):
+ (BitwiseNotNode):
+ (LogicalNotNode):
+ (BinaryOpNode):
+ (MultNode):
+ (DivNode):
+ (ModNode):
+ (AddNode):
+ (SubNode):
+ (LeftShiftNode):
+ (RightShiftNode):
+ (UnsignedRightShiftNode):
+ (LessNode):
+ (GreaterNode):
+ (LessEqNode):
+ (GreaterEqNode):
+ (ThrowableBinaryOpNode):
+ (InstanceOfNode):
+ (InNode):
+ (EqualNode):
+ (NotEqualNode):
+ (StrictEqualNode):
+ (NotStrictEqualNode):
+ (BitAndNode):
+ (BitOrNode):
+ (BitXOrNode):
+ (LogicalOpNode):
+ (ConditionalNode):
+ (ReadModifyResolveNode):
+ (AssignResolveNode):
+ (ReadModifyBracketNode):
+ (AssignBracketNode):
+ (AssignDotNode):
+ (ReadModifyDotNode):
+ (AssignErrorNode):
+ (CommaNode):
+ (ConstDeclNode):
+ (ConstStatementNode):
+ (BlockNode):
+ (EmptyStatementNode):
+ (DebuggerStatementNode):
+ (ExprStatementNode):
+ (VarStatementNode):
+ (IfNode):
+ (IfElseNode):
+ (DoWhileNode):
+ (WhileNode):
+ (ForNode):
+ (ForInNode):
+ (ContinueNode):
+ (BreakNode):
+ (ReturnNode):
+ (WithNode):
+ (LabelNode):
+ (ThrowNode):
+ (TryNode):
+ (ScopeNode):
+ (ProgramNode):
+ (EvalNode):
+ (FunctionBodyNode):
+ (FuncExprNode):
+ (FuncDeclNode):
+ (SwitchNode):
+ * parser/Parser.cpp:
+ (JSC::::parseSourceElements):
+ (JSC::::parseVarDeclaration):
+ (JSC::::parseConstDeclaration):
+ (JSC::::parseDoWhileStatement):
+ (JSC::::parseWhileStatement):
+ (JSC::::parseVarDeclarationList):
+ (JSC::::parseConstDeclarationList):
+ (JSC::::parseForStatement):
+ (JSC::::parseBreakStatement):
+ (JSC::::parseContinueStatement):
+ (JSC::::parseReturnStatement):
+ (JSC::::parseThrowStatement):
+ (JSC::::parseWithStatement):
+ (JSC::::parseSwitchStatement):
+ (JSC::::parseTryStatement):
+ (JSC::::parseDebuggerStatement):
+ (JSC::::parseBlockStatement):
+ (JSC::::parseStatement):
+ (JSC::::parseFunctionBody):
+ (JSC::::parseFunctionInfo):
+ (JSC::::parseFunctionDeclaration):
+ (JSC::::parseExpressionOrLabelStatement):
+ (JSC::::parseExpressionStatement):
+ (JSC::::parseIfStatement):
+ (JSC::::parseExpression):
+ (JSC::::parseAssignmentExpression):
+ (JSC::::parseConditionalExpression):
+ (JSC::::parseBinaryExpression):
+ (JSC::::parseProperty):
+ (JSC::::parseObjectLiteral):
+ (JSC::::parseStrictObjectLiteral):
+ (JSC::::parseArrayLiteral):
+ (JSC::::parsePrimaryExpression):
+ (JSC::::parseArguments):
+ (JSC::::parseMemberExpression):
+ (JSC::::parseUnaryExpression):
+ * parser/Parser.h:
+ (JSC::Parser::next):
+ (JSC::Parser::nextExpectIdentifier):
+ (JSC::Parser::tokenStart):
+ (JSC::Parser::tokenLine):
+ (JSC::Parser::tokenEnd):
+ (JSC::Parser::tokenLocation):
+ (Parser):
+ (JSC::Parser::getTokenName):
+ (JSC::::parse):
+ * parser/ParserTokens.h:
+ (JSC::JSTokenLocation::JSTokenLocation):
+ (JSTokenLocation):
+ (JSToken):
+ * parser/SourceProviderCacheItem.h:
+ (JSC::SourceProviderCacheItem::closeBraceToken):
+ * parser/SyntaxChecker.h:
+ (JSC::SyntaxChecker::makeFunctionCallNode):
+ (JSC::SyntaxChecker::createCommaExpr):
+ (JSC::SyntaxChecker::makeAssignNode):
+ (JSC::SyntaxChecker::makePrefixNode):
+ (JSC::SyntaxChecker::makePostfixNode):
+ (JSC::SyntaxChecker::makeTypeOfNode):
+ (JSC::SyntaxChecker::makeDeleteNode):
+ (JSC::SyntaxChecker::makeNegateNode):
+ (JSC::SyntaxChecker::makeBitwiseNotNode):
+ (JSC::SyntaxChecker::createLogicalNot):
+ (JSC::SyntaxChecker::createUnaryPlus):
+ (JSC::SyntaxChecker::createVoid):
+ (JSC::SyntaxChecker::thisExpr):
+ (JSC::SyntaxChecker::createResolve):
+ (JSC::SyntaxChecker::createObjectLiteral):
+ (JSC::SyntaxChecker::createArray):
+ (JSC::SyntaxChecker::createNumberExpr):
+ (JSC::SyntaxChecker::createString):
+ (JSC::SyntaxChecker::createBoolean):
+ (JSC::SyntaxChecker::createNull):
+ (JSC::SyntaxChecker::createBracketAccess):
+ (JSC::SyntaxChecker::createDotAccess):
+ (JSC::SyntaxChecker::createRegExp):
+ (JSC::SyntaxChecker::createNewExpr):
+ (JSC::SyntaxChecker::createConditionalExpr):
+ (JSC::SyntaxChecker::createAssignResolve):
+ (JSC::SyntaxChecker::createFunctionExpr):
+ (JSC::SyntaxChecker::createFunctionBody):
+ (JSC::SyntaxChecker::createArgumentsList):
+ (JSC::SyntaxChecker::createPropertyList):
+ (JSC::SyntaxChecker::createFuncDeclStatement):
+ (JSC::SyntaxChecker::createBlockStatement):
+ (JSC::SyntaxChecker::createExprStatement):
+ (JSC::SyntaxChecker::createIfStatement):
+ (JSC::SyntaxChecker::createForLoop):
+ (JSC::SyntaxChecker::createForInLoop):
+ (JSC::SyntaxChecker::createEmptyStatement):
+ (JSC::SyntaxChecker::createVarStatement):
+ (JSC::SyntaxChecker::createReturnStatement):
+ (JSC::SyntaxChecker::createBreakStatement):
+ (JSC::SyntaxChecker::createContinueStatement):
+ (JSC::SyntaxChecker::createTryStatement):
+ (JSC::SyntaxChecker::createSwitchStatement):
+ (JSC::SyntaxChecker::createWhileStatement):
+ (JSC::SyntaxChecker::createWithStatement):
+ (JSC::SyntaxChecker::createDoWhileStatement):
+ (JSC::SyntaxChecker::createLabelStatement):
+ (JSC::SyntaxChecker::createThrowStatement):
+ (JSC::SyntaxChecker::createDebugger):
+ (JSC::SyntaxChecker::createConstStatement):
+ (JSC::SyntaxChecker::appendConstDecl):
+ (JSC::SyntaxChecker::createGetterOrSetterProperty):
+ (JSC::SyntaxChecker::combineCommaNodes):
+ (JSC::SyntaxChecker::operatorStackPop):
+
+2012-08-01 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should hoist structure checks
+ https://bugs.webkit.org/show_bug.cgi?id=92696
+
+ Reviewed by Gavin Barraclough.
+
+ This hoists structure checks in the same way that we would hoist array checks, but with added
+ complexity to cope with the fact that the structure of an object may change. This is handled
+ by performing a side effects analysis over the region in which the respective variable is
+ live. If a structure clobbering side effect may happen then we either hoist the structure
+ checks and fall back on structure transition watchpoints (if the watchpoint set is still
+ valid), or we avoid hoisting altogether.
+
+ Doing this required teaching the CFA that we may have an expectation that an object has a
+ particular structure even after structure clobbering happens, in the sense that structure
+ proofs that were cobbered can be revived using watchpoints. CFA must know about this so that
+ OSR entry may know about it, since we cannot allow entry to happen if the variable has a
+ clobbered structure proof, will have a watchpoint to revive the proof, and the variable in
+ the baseline JIT has a completely unrelated structure.
+
+ This is mostly performance neutral.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * Target.pri:
+ * bytecode/ValueRecovery.h:
+ (JSC::ValueRecovery::isSet):
+ (JSC::ValueRecovery::operator!):
+ (ValueRecovery):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ (JSC::DFG::AbstractState::clobberWorld):
+ (DFG):
+ (JSC::DFG::AbstractState::clobberCapturedVars):
+ * dfg/DFGAbstractState.h:
+ (AbstractState):
+ * dfg/DFGAbstractValue.h:
+ (JSC::DFG::AbstractValue::clear):
+ (JSC::DFG::AbstractValue::isClear):
+ (JSC::DFG::AbstractValue::makeTop):
+ (JSC::DFG::AbstractValue::isTop):
+ (JSC::DFG::AbstractValue::set):
+ (JSC::DFG::AbstractValue::operator==):
+ (JSC::DFG::AbstractValue::merge):
+ (JSC::DFG::AbstractValue::filter):
+ (JSC::DFG::AbstractValue::validate):
+ (JSC::DFG::AbstractValue::validateForEntry):
+ (AbstractValue):
+ (JSC::DFG::AbstractValue::checkConsistency):
+ (JSC::DFG::AbstractValue::dump):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::setLocal):
+ (JSC::DFG::ByteCodeParser::getArgument):
+ (JSC::DFG::ByteCodeParser::setArgument):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ (JSC::DFG::ByteCodeParser::fixVariableAccessSpeculations):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::checkStructureLoadElimination):
+ (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+ (JSC::DFG::CSEPhase::putStructureStoreElimination):
+ (JSC::DFG::CSEPhase::getLocalLoadElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGDriver.cpp:
+ (JSC::DFG::compile):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::vote):
+ (Graph):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::convertToStructureTransitionWatchpoint):
+ (Node):
+ (JSC::DFG::Node::hasStructureSet):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGOSREntry.cpp:
+ (JSC::DFG::prepareOSREntry):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ (PredictionPropagationPhase):
+ (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
+ (JSC::DFG::SpeculativeJIT::speculationCheckWithConditionalDirection):
+ (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection):
+ (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
+ (JSC::DFG::SpeculateCellOperand::gpr):
+ (SpeculateCellOperand):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStructureCheckHoistingPhase.cpp: Added.
+ (DFG):
+ (StructureCheckHoistingPhase):
+ (JSC::DFG::StructureCheckHoistingPhase::StructureCheckHoistingPhase):
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+ (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck):
+ (JSC::DFG::StructureCheckHoistingPhase::noticeClobber):
+ (JSC::DFG::StructureCheckHoistingPhase::clobber):
+ (CheckData):
+ (JSC::DFG::StructureCheckHoistingPhase::CheckData::CheckData):
+ (JSC::DFG::performStructureCheckHoisting):
+ * dfg/DFGStructureCheckHoistingPhase.h: Added.
+ (DFG):
+ * dfg/DFGVariableAccessData.h:
+ (VariableAccessData):
+ (JSC::DFG::VariableAccessData::VariableAccessData):
+ (JSC::DFG::VariableAccessData::mergeStructureCheckHoistingFailed):
+ (JSC::DFG::VariableAccessData::structureCheckHoistingFailed):
+ (JSC::DFG::VariableAccessData::clearVotes):
+ (JSC::DFG::VariableAccessData::vote):
+ (JSC::DFG::VariableAccessData::voteRatio):
+ (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
+ * runtime/Options.h:
+ (JSC):
+
+2012-08-01 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should distinguish between PutByVal's that clobber the world and ones that don't
+ https://bugs.webkit.org/show_bug.cgi?id=92923
+
+ Reviewed by Mark Hahnenberg.
+
+ This is performance-neutral. I also confirmed that it's neutral if we make the
+ clobbering variant (PutByValSafe) clobber all knowledge of what is an array,
+ which should feed nicely into work on removing uses of ClassInfo.
+
+ * bytecode/DFGExitProfile.h:
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::getByValLoadElimination):
+ (JSC::DFG::CSEPhase::checkStructureLoadElimination):
+ (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
+ (JSC::DFG::CSEPhase::getByOffsetLoadElimination):
+ (JSC::DFG::CSEPhase::putByOffsetStoreElimination):
+ (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::byValIsPure):
+ (JSC::DFG::Graph::clobbersWorld):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-08-01 Jian Li <jianli@chromium.org>
+
+ Add new CSS property "-webkit-widget-region" to expose dashboard region support for other port
+ https://bugs.webkit.org/show_bug.cgi?id=90298
+
+ Reviewed by Adam Barth.
+
+ * Configurations/FeatureDefines.xcconfig: Add ENABLE_WIDGET_REGION define.
+
+2012-08-01 Patrick Gansterer <paroga@webkit.org>
+
+ Replace WTF::getCurrentLocalTime() with GregorianDateTime::setToCurrentLocalTime()
+ https://bugs.webkit.org/show_bug.cgi?id=92286
+
+ Reviewed by Geoffrey Garen.
+
+ Add a method to GregorianDateTime to set its values to the current locale time.
+ Replacing all occurrences of getCurrentLocalTime with the new function allows
+ us to remove getCurrentLocalTime in a next step.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-08-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ C++ code should get ClassInfo from the Structure
+ https://bugs.webkit.org/show_bug.cgi?id=92892
+
+ Reviewed by Geoffrey Garen.
+
+ In our march to remove ClassInfo from our JSCell object headers, we can switch
+ C++ code over to grabbing the ClassInfo from the Structure since it is finally
+ safe to do so now that Structure access is safe during finalization/destruction.
+ The remaining JIT code changes can be done in a separate patch.
+
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::callDestructor): We don't want to clear the Structure any more
+ since the Structure should still be valid at this point.
+ * heap/WeakSetInlines.h:
+ (JSC::WeakBlock::finalize): Ditto.
+ * runtime/JSCell.h:
+ (JSC):
+ * runtime/Structure.h:
+ (JSC::JSCell::classInfo): Move JSCell's classInfo() to Structure.h so it can be
+ inline. Use a different method of getting the JSCell's Structure based on
+ whether we're in GC_VALIDATION mode or not, since always using get() will cause
+ infinite recursion in GC_VALIDATION mode.
+ (JSC):
+
+2012-07-31 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ MarkedBlock::sweep() should sweep another block if it can't sweep a Structure block
+ https://bugs.webkit.org/show_bug.cgi?id=92819
+
+ Reviewed by Geoffrey Garen.
+
+ If we are forced to allocate a new block for Structures because we are unable to safely
+ sweep our pre-existing Structure blocks, we should sweep another random block so that we
+ can start sweeping Structure blocks sooner.
+
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::doSweep): Change to use sweepNextBlock.
+ (JSC):
+ (JSC::IncrementalSweeper::sweepNextBlock):
+ * heap/IncrementalSweeper.h:
+ (IncrementalSweeper):
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::tryAllocateHelper): When we can't safely sweep
+ our Structure blocks, call sweepNextBlock instead.
+
+2012-07-31 Sam Weinig <sam@webkit.org>
+
+ Fix the Windows build.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2012-07-31 Geoffrey Garen <ggaren@apple.com>
+
+ Maybe fix the GCC build.
+
+ * heap/HeapBlock.h:
+ (HeapBlock): Accommodate incorrect parsing in GCC.
+
+2012-07-31 Sam Weinig <sam@webkit.org>
+
+ Stop masking 8 bits off of the visited link hash. We need all the bits!
+ https://bugs.webkit.org/show_bug.cgi?id=92799
+
+ Reviewed by Anders Carlsson.
+
+ * runtime/Identifier.cpp:
+ (JSC::IdentifierCStringTranslator::hash):
+ (JSC::IdentifierLCharFromUCharTranslator::hash):
+ * runtime/Identifier.h:
+ (JSC::IdentifierCharBufferTranslator::hash):
+ Update for new function names.
+
+2012-07-31 Geoffrey Garen <ggaren@apple.com>
+
+ Maybe break the Windows build.
+
+ Reviewed by Anders Carlsson.
+
+ Formally objected to by Sam Weinig.
+
+ * heap/HeapBlock.h:
+ (HeapBlock): Try to slightly improve this because we don't want Windows to control our lives.
+
+2012-07-30 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Structures should be swept after all other objects
+ https://bugs.webkit.org/show_bug.cgi?id=92679
+
+ Reviewed by Filip Pizlo.
+
+ In order to get rid of ClassInfo from our objects, we need to be able to safely get the
+ ClassInfo during the destruction of objects. We'd like to get the ClassInfo out of the
+ Structure, but currently it is not safe to do so because the order of destruction of objects
+ is not guaranteed to sweep objects before their corresponding Structure. We can fix this by
+ sweeping Structures after everything else.
+
+ * heap/Heap.cpp:
+ (JSC::Heap::isSafeToSweepStructures): Add a function that checks if it is safe to sweep Structures.
+ If the Heap's IncrementalSweeper member is null, that means we're shutting down this VM and it is
+ safe to sweep structures since we'll always do Structures last anyways due to the ordering of
+ MarkedSpace::forEachBlock.
+ (JSC):
+ (JSC::Heap::didStartVMShutdown): Add this intermediate function to the Heap that ~JSGlobalData now
+ calls rather than calling the two HeapTimer objects individually. This allows the Heap to null out
+ these pointers after it has invalidated them to prevent accidental use-after-free in the sweep()
+ calls during lastChanceToFinalize().
+ * heap/Heap.h:
+ (Heap):
+ * heap/HeapTimer.h:
+ (HeapTimer):
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::structuresCanBeSwept): Determines if it is currently safe to sweep Structures.
+ This decision is based on whether we have gotten to the end of the vector of blocks that need sweeping
+ the first time.
+ (JSC):
+ (JSC::IncrementalSweeper::doSweep): We add a second pass over the vector to sweep Structures after we
+ make our first pass. We now null out the slots as we sweep them so that we can quickly find the
+ Structures during the second pass.
+ (JSC::IncrementalSweeper::startSweeping): Initialize our new Structure sweeping index.
+ (JSC::IncrementalSweeper::willFinishSweeping): Callback that is called by MarkedSpace::sweep to notify
+ the IncrementalSweeper that we are going to sweep all of the remaining blocks in the Heap so it can
+ assume that everything is taken care of in the correct order. Since MarkedSpace::forEachBlock
+ iterates over the Structure blocks after all other blocks, the ordering property for sweeping Structures holds.
+ (JSC::IncrementalSweeper::IncrementalSweeper): Initialize Structure sweeping index.
+ * heap/IncrementalSweeper.h: Add declarations for new stuff.
+ (IncrementalSweeper):
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::tryAllocateHelper): We now check if the current block only contains structures and
+ if so and it isn't safe to sweep Structures according to the Heap, we just return early instead of doing
+ the normal lazy sweep. If this proves to be too much of a waste in the future we can add an extra clause that
+ will sweep some number of other blocks in place of the current block to mitigate the cost of the floating
+ Structure garbage.
+ (JSC::MarkedAllocator::addBlock):
+ * heap/MarkedAllocator.h:
+ (JSC::MarkedAllocator::zapFreeList): When we zap the free list in the MarkedAllocator, the current block is no
+ longer valid to allocate from, so we set the current block to null.
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::sweepHelper): Added a couple assertions to make sure that we weren't trying to sweep Structures
+ at an unsafe time.
+ * heap/MarkedSpace.cpp:
+ (JSC::MarkedSpace::sweep): Notify the IncrementalSweeper that the MarkedSpace will finish all currently remaining sweeping.
+ (JSC):
+ * heap/MarkedSpace.h:
+ (JSC):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::~JSGlobalData): Call the new Heap::didStartVMShutdown.
+
+2012-07-31 Geoffrey Garen <ggaren@apple.com>
+
+ Fix all the other builds I just broke. Maybe fix the Windows build.
+
+ * heap/HeapBlock.h:
+ (HeapBlock): WTF?
+
+2012-07-31 Geoffrey Garen <ggaren@apple.com>
+
+ Maybe fix the Windows build.
+
+ * heap/HeapBlock.h:
+ (HeapBlock): WTF?
+
+2012-07-31 Geoffrey Garen <ggaren@apple.com>
+
+ Maybe fix the Windows build.
+
+ * heap/HeapBlock.h:
+ (HeapBlock): WTF?
+
+2012-07-31 Geoffrey Garen <ggaren@apple.com>
+
+ Removed some public data and casting from the Heap
+ https://bugs.webkit.org/show_bug.cgi?id=92777
+
+ Reviewed by Oliver Hunt.
+
+ * heap/BlockAllocator.cpp:
+ (JSC::BlockAllocator::releaseFreeBlocks):
+ (JSC::BlockAllocator::blockFreeingThreadMain): Use the DeadBlock class
+ since HeapBlock is a template, and not a class, now. Call destroy()
+ instead of monkeying around with DeadBlock's internal data because
+ encapsulation is good.
+
+ * heap/BlockAllocator.h:
+ (DeadBlock): Added a class to represent a dead block, since HeapBlock is
+ a template now, and can't be instantiated directly.
+
+ (JSC::DeadBlock::DeadBlock):
+ (JSC::DeadBlock::create):
+ (BlockAllocator):
+ (JSC::BlockAllocator::allocate):
+ (JSC::BlockAllocator::deallocate): Use the DeadBlock class because
+ encapsulation is good.
+
+ * heap/CopiedBlock.h:
+ (CopiedBlock::destroy): No need for a destroy() function, since we
+ inherit one now.
+
+ (JSC::CopiedBlock::CopiedBlock):
+ (JSC::CopiedBlock::payloadEnd):
+ (JSC::CopiedBlock::capacity): Updated for some encapsulation inside
+ HeapBlock.
+
+ * heap/CopiedSpace.cpp:
+ (JSC::CopiedSpace::~CopiedSpace):
+ (JSC::CopiedSpace::doneCopying):
+ (JSC::CopiedSpace::size):
+ (JSC::CopiedSpace::capacity):
+ (JSC::isBlockListPagedOut): Removed a bunch of casting. This is no longer
+ necessary, now that our list and its nodes have the right type.
+
+ * heap/CopiedSpace.h: Use the right type in our data structures because
+ it improves clarity.
+
+ * heap/CopiedSpaceInlineMethods.h:
+ (JSC::CopiedSpace::startedCopying): Use swap to avoid duplicating it.
+
+ * heap/HeapBlock.h:
+ (HeapBlock): Made this a class template so we can return the right type
+ in linked list operations. Made our data private because encapsulation
+ is good.
+
+ (JSC::HeapBlock::destroy): Since we know our type, we can also eliminate
+ duplicate destroy() functions in our subclasses.
+
+ (JSC::HeapBlock::allocation): Added an accessor so we can hide our data.
+ By using const, this accessor prevents clients from accidentally deleting
+ our allocation.
+
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::isPagedOut):
+ (JSC::MarkedAllocator::tryAllocateHelper):
+ (JSC::MarkedAllocator::removeBlock): Removed a bunch of casting. This is
+ no longer necessary, now that our list and its nodes have the right type.
+
+ * heap/MarkedAllocator.h:
+ (MarkedAllocator):
+ (JSC::MarkedAllocator::reset):
+ (JSC::MarkedAllocator::forEachBlock): Use the right type, do less casting.
+
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::destroy): Removed this function because our parent
+ class provides it for us now.
+
+ (JSC::MarkedBlock::MarkedBlock):
+ * heap/MarkedBlock.h:
+ (MarkedBlock):
+ (JSC::MarkedBlock::capacity): Updated for encapsulation.
+
+2012-07-31 Filip Pizlo <fpizlo@apple.com>
+
+ DFG OSR exit profiling has unusual oversights
+ https://bugs.webkit.org/show_bug.cgi?id=92728
+
+ Reviewed by Geoffrey Garen.
+
+ * dfg/DFGOSRExit.cpp:
+ (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2012-07-31 Chao-ying Fu <fu@mips.com>
+
+ Add MIPS add32 function
+ https://bugs.webkit.org/show_bug.cgi?id=91522
+
+ Reviewed by Oliver Hunt.
+
+ Add isCompactPtrAlignedAddressOffset.
+ Add a new version of add32 that accepts AbsoluteAddress as inputs.
+
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::isCompactPtrAlignedAddressOffset): New.
+ (MacroAssemblerMIPS):
+ (JSC::MacroAssemblerMIPS::add32): Support AbsoluteAddress as inputs.
+
+2012-07-30 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r124123.
+ http://trac.webkit.org/changeset/124123
+ https://bugs.webkit.org/show_bug.cgi?id=92700
+
+ ASSERT crashes terminate webkit Layout tests (Requested by
+ msaboff on #webkit).
+
+ * heap/Heap.cpp:
+ * heap/Heap.h:
+ (Heap):
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::doSweep):
+ (JSC::IncrementalSweeper::startSweeping):
+ (JSC::IncrementalSweeper::IncrementalSweeper):
+ (JSC):
+ * heap/IncrementalSweeper.h:
+ (IncrementalSweeper):
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::tryAllocateHelper):
+ (JSC::MarkedAllocator::addBlock):
+ * heap/MarkedAllocator.h:
+ (JSC::MarkedAllocator::zapFreeList):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::sweepHelper):
+ * heap/MarkedSpace.cpp:
+ * heap/MarkedSpace.h:
+ (JSC::MarkedSpace::sweep):
+ (JSC):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::~JSGlobalData):
+
+2012-07-30 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Structures should be swept after all other objects
+ https://bugs.webkit.org/show_bug.cgi?id=92679
+
+ Reviewed by Filip Pizlo.
+
+ In order to get rid of ClassInfo from our objects, we need to be able to safely get the
+ ClassInfo during the destruction of objects. We'd like to get the ClassInfo out of the
+ Structure, but currently it is not safe to do so because the order of destruction of objects
+ is not guaranteed to sweep objects before their corresponding Structure. We can fix this by
+ sweeping Structures after everything else.
+
+ * heap/Heap.cpp:
+ (JSC::Heap::isSafeToSweepStructures): Add a function that checks if it is safe to sweep Structures.
+ If the Heap's IncrementalSweeper member is null, that means we're shutting down this VM and it is
+ safe to sweep structures since we'll always do Structures last anyways due to the ordering of
+ MarkedSpace::forEachBlock.
+ (JSC):
+ (JSC::Heap::didStartVMShutdown): Add this intermediate function to the Heap that ~JSGlobalData now
+ calls rather than calling the two HeapTimer objects individually. This allows the Heap to null out
+ these pointers after it has invalidated them to prevent accidental use-after-free in the sweep()
+ calls during lastChanceToFinalize().
+ * heap/Heap.h:
+ (Heap):
+ * heap/HeapTimer.h:
+ (HeapTimer):
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::structuresCanBeSwept): Determines if it is currently safe to sweep Structures.
+ This decision is based on whether we have gotten to the end of the vector of blocks that need sweeping
+ the first time.
+ (JSC):
+ (JSC::IncrementalSweeper::doSweep): We add a second pass over the vector to sweep Structures after we
+ make our first pass. We now null out the slots as we sweep them so that we can quickly find the
+ Structures during the second pass.
+ (JSC::IncrementalSweeper::startSweeping): Initialize our new Structure sweeping index.
+ (JSC::IncrementalSweeper::willFinishSweeping): Callback that is called by MarkedSpace::sweep to notify
+ the IncrementalSweeper that we are going to sweep all of the remaining blocks in the Heap so it can
+ assume that everything is taken care of in the correct order. Since MarkedSpace::forEachBlock
+ iterates over the Structure blocks after all other blocks, the ordering property for sweeping Structures holds.
+ (JSC::IncrementalSweeper::IncrementalSweeper): Initialize Structure sweeping index.
+ * heap/IncrementalSweeper.h: Add declarations for new stuff.
+ (IncrementalSweeper):
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::tryAllocateHelper): We now check if the current block only contains structures and
+ if so and it isn't safe to sweep Structures according to the Heap, we just return early instead of doing
+ the normal lazy sweep. If this proves to be too much of a waste in the future we can add an extra clause that
+ will sweep some number of other blocks in place of the current block to mitigate the cost of the floating
+ Structure garbage.
+ (JSC::MarkedAllocator::addBlock):
+ * heap/MarkedAllocator.h:
+ (JSC::MarkedAllocator::zapFreeList): When we zap the free list in the MarkedAllocator, the current block is no
+ longer valid to allocate from, so we set the current block to null.
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::sweepHelper): Added a couple assertions to make sure that we weren't trying to sweep Structures
+ at an unsafe time.
+ * heap/MarkedSpace.cpp:
+ (JSC::MarkedSpace::sweep): Notify the IncrementalSweeper that the MarkedSpace will finish all currently remaining sweeping.
+ (JSC):
+ * heap/MarkedSpace.h:
+ (JSC):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::~JSGlobalData): Call the new Heap::didStartVMShutdown.
2012-07-29 Filip Pizlo <fpizlo@apple.com>
diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index b5f24899f..40d95cb9c 100644
--- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -39,6 +39,7 @@ ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING;
ENABLE_CSP_NEXT = ;
ENABLE_CSS_EXCLUSIONS = ENABLE_CSS_EXCLUSIONS;
ENABLE_CSS_FILTERS = ENABLE_CSS_FILTERS;
+ENABLE_CSS_HIERARCHIES = ;
ENABLE_CSS_IMAGE_ORIENTATION = ;
ENABLE_CSS_IMAGE_RESOLUTION = ;
ENABLE_CSS_REGIONS = ENABLE_CSS_REGIONS;
@@ -133,7 +134,9 @@ ENABLE_WEBGL = ENABLE_WEBGL;
ENABLE_WEB_AUDIO = ENABLE_WEB_AUDIO;
ENABLE_WEB_SOCKETS = ENABLE_WEB_SOCKETS;
ENABLE_WEB_TIMING = ;
+ENABLE_WIDGET_REGION = $(ENABLE_WIDGET_REGION_$(REAL_PLATFORM_NAME));
+ENABLE_WIDGET_REGION_macosx = ENABLE_WIDGET_REGION;
ENABLE_WORKERS = ENABLE_WORKERS;
ENABLE_XSLT = ENABLE_XSLT;
-FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_FLEXBOX) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_HIERARCHIES) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_FLEXBOX) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_QUOTA) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WIDGET_REGION) $(ENABLE_WORKERS) $(ENABLE_XSLT);
diff --git a/Source/JavaScriptCore/Configurations/Version.xcconfig b/Source/JavaScriptCore/Configurations/Version.xcconfig
index daf808e05..b619d3602 100644
--- a/Source/JavaScriptCore/Configurations/Version.xcconfig
+++ b/Source/JavaScriptCore/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 537;
-MINOR_VERSION = 3;
+MINOR_VERSION = 6;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/Source/JavaScriptCore/GNUmakefile.list.am b/Source/JavaScriptCore/GNUmakefile.list.am
index e21ad80d7..ab8b110c2 100644
--- a/Source/JavaScriptCore/GNUmakefile.list.am
+++ b/Source/JavaScriptCore/GNUmakefile.list.am
@@ -227,6 +227,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp \
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp \
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h \
+ Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp \
+ Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h \
Source/JavaScriptCore/dfg/DFGThunks.cpp \
Source/JavaScriptCore/dfg/DFGThunks.h \
Source/JavaScriptCore/dfg/DFGValueRecoveryOverride.h \
@@ -262,6 +264,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/heap/IncrementalSweeper.h \
Source/JavaScriptCore/heap/IncrementalSweeper.cpp \
Source/JavaScriptCore/heap/SlotVisitor.h \
+ Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h \
Source/JavaScriptCore/heap/HandleStack.cpp \
Source/JavaScriptCore/heap/HandleStack.h \
Source/JavaScriptCore/heap/HandleTypes.h \
diff --git a/Source/JavaScriptCore/JavaScriptCore.pri b/Source/JavaScriptCore/JavaScriptCore.pri
index f6580c51f..fad36c974 100644
--- a/Source/JavaScriptCore/JavaScriptCore.pri
+++ b/Source/JavaScriptCore/JavaScriptCore.pri
@@ -32,9 +32,7 @@ INCLUDEPATH += \
$$SOURCE_DIR/ForwardingHeaders \
$$JAVASCRIPTCORE_GENERATED_SOURCES_DIR
-win32-* {
- LIBS += -lwinmm
-}
+win32-*: LIBS += -lwinmm
wince* {
INCLUDEPATH += $$QT.core.sources/../3rdparty/ce-compat
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 5f27859d8..8032ed178 100755
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -81,7 +81,7 @@ EXPORTS
?byteCompile@Yarr@JSC@@YA?AV?$PassOwnPtr@UBytecodePattern@Yarr@JSC@@@WTF@@AAUYarrPattern@12@PAVBumpPointerAllocator@4@@Z
?byteSize@SourceProviderCache@JSC@@QBEIXZ
?calculateDSTOffset@WTF@@YANNN@Z
- ?calculateStringHashAndLengthFromUTF8@Unicode@WTF@@YAIPBD0AAI1@Z
+ ?calculateStringHashAndLengthFromUTF8MaskingTop8Bits@Unicode@WTF@@YAIPBD0AAI1@Z
?calculateUTCOffset@WTF@@YAHXZ
?calculatedFunctionName@DebuggerCallFrame@JSC@@QBE?AVUString@2@XZ
?call@JSC@@YA?AVJSValue@1@PAVExecState@1@V21@W4CallType@1@ABTCallData@1@1ABVArgList@1@@Z
@@ -201,7 +201,6 @@ EXPORTS
?getCallData@JSCell@JSC@@SA?AW4CallType@2@PAV12@AATCallData@2@@Z
?getCallableObjectSlow@JSC@@YAPAVJSCell@1@PAV21@@Z
?getConstructData@JSCell@JSC@@SA?AW4ConstructType@2@PAV12@AATConstructData@2@@Z
- ?getCurrentLocalTime@WTF@@YAXPAUtm@@@Z
?getObject@JSCell@JSC@@QAEPAVJSObject@2@XZ
?getOwnPropertyDescriptor@JSGlobalObject@JSC@@SA_NPAVJSObject@2@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@@Z
?getOwnPropertyDescriptor@JSObject@JSC@@SA_NPAV12@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@@Z
@@ -315,6 +314,7 @@ EXPORTS
?setOrderLowerFirst@Collator@WTF@@QAEX_N@Z
?setPrototype@JSObject@JSC@@QAEXAAVJSGlobalData@2@VJSValue@2@@Z
?setSetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z
+ ?setToCurrentLocalTime@GregorianDateTime@WTF@@QAEXXZ
?setUndefined@PropertyDescriptor@JSC@@QAEXXZ
?setUnwrappedObject@JSGlobalThis@JSC@@IAEXAAVJSGlobalData@2@PAVJSGlobalObject@2@@Z
?setUpStaticFunctionSlot@JSC@@YA_NPAVExecState@1@PBVHashEntry@1@PAVJSObject@1@VPropertyName@1@AAVPropertySlot@1@@Z
@@ -352,8 +352,8 @@ EXPORTS
?toObject@JSCell@JSC@@QBEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z
?toObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z
?toString@JSObject@JSC@@QBEPAVJSString@2@PAVExecState@2@@Z
- ?toStringDecimal@DecimalNumber@WTF@@QBEIPA_WI@Z
- ?toStringExponential@DecimalNumber@WTF@@QBEIPA_WI@Z
+ ?toStringDecimal@DecimalNumber@WTF@@QBEIPAEI@Z
+ ?toStringExponential@DecimalNumber@WTF@@QBEIPAEI@Z
?toStringSlowCase@JSValue@JSC@@ABEPAVJSString@2@PAVExecState@2@@Z
?toThisObject@JSObject@JSC@@SAPAV12@PAVJSCell@2@PAVExecState@2@@Z
?toThisObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 6caa07e6e..add311969 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -138,6 +138,8 @@
0F620177143FCD3F0068B77C /* DFGAbstractValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F620178143FCD440068B77C /* DFGAbstractState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F62016E143FCD2F0068B77C /* DFGAbstractState.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F620179143FCD480068B77C /* DFGAbstractState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */; };
+ 0F63943F15C75F19006A597C /* DFGStructureCheckHoistingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F63943D15C75F14006A597C /* DFGStructureCheckHoistingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F63944015C75F1D006A597C /* DFGStructureCheckHoistingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F63943C15C75F14006A597C /* DFGStructureCheckHoistingPhase.cpp */; };
0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */; };
@@ -885,6 +887,8 @@
0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractValue.h; path = dfg/DFGAbstractValue.h; sourceTree = "<group>"; };
0F620170143FCD2F0068B77C /* DFGBasicBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBasicBlock.h; path = dfg/DFGBasicBlock.h; sourceTree = "<group>"; };
0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessData.h; path = dfg/DFGVariableAccessData.h; sourceTree = "<group>"; };
+ 0F63943C15C75F14006A597C /* DFGStructureCheckHoistingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStructureCheckHoistingPhase.cpp; path = dfg/DFGStructureCheckHoistingPhase.cpp; sourceTree = "<group>"; };
+ 0F63943D15C75F14006A597C /* DFGStructureCheckHoistingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureCheckHoistingPhase.h; path = dfg/DFGStructureCheckHoistingPhase.h; sourceTree = "<group>"; };
0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAdjacencyList.h; path = dfg/DFGAdjacencyList.h; sourceTree = "<group>"; };
0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGEdge.h; path = dfg/DFGEdge.h; sourceTree = "<group>"; };
0F766D1C15A5028D008F363E /* JITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutine.h; sourceTree = "<group>"; };
@@ -2321,6 +2325,8 @@
86EC9DC31328DF82002B2AD7 /* DFGSpeculativeJIT.h */,
86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */,
86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */,
+ 0F63943C15C75F14006A597C /* DFGStructureCheckHoistingPhase.cpp */,
+ 0F63943D15C75F14006A597C /* DFGStructureCheckHoistingPhase.h */,
0FC0979F146B28C700CF2442 /* DFGThunks.cpp */,
0FC097A0146B28C700CF2442 /* DFGThunks.h */,
0F2BDC3F1522801700CD8910 /* DFGValueRecoveryOverride.h */,
@@ -2860,6 +2866,7 @@
0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */,
0F766D4415B2A3C0008F363E /* DFGRegisterSet.h in Headers */,
0F766D4615B3701F008F363E /* DFGScratchRegisterAllocator.h in Headers */,
+ 0F63943F15C75F19006A597C /* DFGStructureCheckHoistingPhase.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3457,6 +3464,7 @@
0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */,
0F766D3415AE2538008F363E /* JumpReplacementWatchpoint.cpp in Sources */,
0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */,
+ 0F63944015C75F1D006A597C /* DFGStructureCheckHoistingPhase.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Source/JavaScriptCore/Target.pri b/Source/JavaScriptCore/Target.pri
index 035656f0c..3d0e41df4 100644
--- a/Source/JavaScriptCore/Target.pri
+++ b/Source/JavaScriptCore/Target.pri
@@ -26,10 +26,6 @@ CONFIG += staticlib
}
}
-wince* {
- SOURCES += $$QT.core.sources/../3rdparty/ce-compat/ce_time.c
-}
-
include(yarr/yarr.pri)
INSTALLDEPS += all
@@ -126,6 +122,7 @@ SOURCES += \
dfg/DFGSpeculativeJIT.cpp \
dfg/DFGSpeculativeJIT32_64.cpp \
dfg/DFGSpeculativeJIT64.cpp \
+ dfg/DFGStructureCheckHoistingPhase.cpp \
dfg/DFGThunks.cpp \
dfg/DFGValueSource.cpp \
dfg/DFGVariableEvent.cpp \
diff --git a/Source/JavaScriptCore/assembler/ARMAssembler.cpp b/Source/JavaScriptCore/assembler/ARMAssembler.cpp
index 362fcc630..533640ea8 100644
--- a/Source/JavaScriptCore/assembler/ARMAssembler.cpp
+++ b/Source/JavaScriptCore/assembler/ARMAssembler.cpp
@@ -46,7 +46,7 @@ void ARMAssembler::patchConstantPoolLoad(void* loadAddr, void* constPoolAddr)
ASSERT(diff <= 0xfff);
*ldr = (*ldr & ~0xfff) | diff;
} else
- *ldr = (*ldr & ~(0xfff | ARMAssembler::DT_UP)) | sizeof(ARMWord);
+ *ldr = (*ldr & ~(0xfff | ARMAssembler::DataTransferUp)) | sizeof(ARMWord);
}
// Handle immediates
@@ -56,7 +56,7 @@ ARMWord ARMAssembler::getOp2(ARMWord imm)
int rol;
if (imm <= 0xff)
- return OP2_IMM | imm;
+ return Op2Immediate | imm;
if ((imm & 0xff000000) == 0) {
imm <<= 8;
@@ -83,9 +83,9 @@ ARMWord ARMAssembler::getOp2(ARMWord imm)
}
if ((imm & 0x00ffffff) == 0)
- return OP2_IMM | (imm >> 24) | (rol << 8);
+ return Op2Immediate | (imm >> 24) | (rol << 8);
- return INVALID_IMM;
+ return InvalidImmediate;
}
int ARMAssembler::genInt(int reg, ARMWord imm, bool positive)
@@ -129,10 +129,10 @@ int ARMAssembler::genInt(int reg, ARMWord imm, bool positive)
ASSERT((imm & 0xff) == 0);
if ((imm & 0xff000000) == 0) {
- imm1 = OP2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8);
- imm2 = OP2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8);
+ imm1 = Op2Immediate | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8);
+ imm2 = Op2Immediate | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8);
} else if (imm & 0xc0000000) {
- imm1 = OP2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
+ imm1 = Op2Immediate | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
imm <<= 8;
rol += 4;
@@ -152,7 +152,7 @@ int ARMAssembler::genInt(int reg, ARMWord imm, bool positive)
}
if ((imm & 0x00ffffff) == 0)
- imm2 = OP2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
+ imm2 = Op2Immediate | (imm >> 24) | ((rol & 0xf) << 8);
else
return 0;
} else {
@@ -166,7 +166,7 @@ int ARMAssembler::genInt(int reg, ARMWord imm, bool positive)
rol += 1;
}
- imm1 = OP2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
+ imm1 = Op2Immediate | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
imm <<= 8;
rol += 4;
@@ -181,7 +181,7 @@ int ARMAssembler::genInt(int reg, ARMWord imm, bool positive)
}
if ((imm & 0x00ffffff) == 0)
- imm2 = OP2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
+ imm2 = Op2Immediate | (imm >> 24) | ((rol & 0xf) << 8);
else
return 0;
}
@@ -203,13 +203,13 @@ ARMWord ARMAssembler::getImm(ARMWord imm, int tmpReg, bool invert)
// Do it by 1 instruction
tmp = getOp2(imm);
- if (tmp != INVALID_IMM)
+ if (tmp != InvalidImmediate)
return tmp;
tmp = getOp2(~imm);
- if (tmp != INVALID_IMM) {
+ if (tmp != InvalidImmediate) {
if (invert)
- return tmp | OP2_INV_IMM;
+ return tmp | Op2InvertedImmediate;
mvn_r(tmpReg, tmp);
return tmpReg;
}
@@ -223,13 +223,13 @@ void ARMAssembler::moveImm(ARMWord imm, int dest)
// Do it by 1 instruction
tmp = getOp2(imm);
- if (tmp != INVALID_IMM) {
+ if (tmp != InvalidImmediate) {
mov_r(dest, tmp);
return;
}
tmp = getOp2(~imm);
- if (tmp != INVALID_IMM) {
+ if (tmp != InvalidImmediate) {
mvn_r(dest, tmp);
return;
}
@@ -241,7 +241,7 @@ ARMWord ARMAssembler::encodeComplexImm(ARMWord imm, int dest)
{
#if WTF_ARM_ARCH_AT_LEAST(7)
ARMWord tmp = getImm16Op2(imm);
- if (tmp != INVALID_IMM) {
+ if (tmp != InvalidImmediate) {
movw_r(dest, tmp);
return dest;
}
@@ -268,7 +268,7 @@ void ARMAssembler::dataTransfer32(DataTransferTypeA transferType, RegisterID src
if (offset <= 0xfff)
dtr_u(transferType, srcDst, base, offset);
else if (offset <= 0xfffff) {
- add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
+ add_r(ARMRegisters::S0, base, Op2Immediate | (offset >> 12) | (10 << 8));
dtr_u(transferType, srcDst, ARMRegisters::S0, (offset & 0xfff));
} else {
moveImm(offset, ARMRegisters::S0);
@@ -278,7 +278,7 @@ void ARMAssembler::dataTransfer32(DataTransferTypeA transferType, RegisterID src
if (offset >= -0xfff)
dtr_d(transferType, srcDst, base, -offset);
else if (offset >= -0xfffff) {
- sub_r(ARMRegisters::S0, base, OP2_IMM | (-offset >> 12) | (10 << 8));
+ sub_r(ARMRegisters::S0, base, Op2Immediate | (-offset >> 12) | (10 << 8));
dtr_d(transferType, srcDst, ARMRegisters::S0, (-offset & 0xfff));
} else {
moveImm(offset, ARMRegisters::S0);
@@ -307,7 +307,7 @@ void ARMAssembler::dataTransfer16(DataTransferTypeB transferType, RegisterID src
if (offset <= 0xff)
dtrh_u(transferType, srcDst, base, getOp2Half(offset));
else if (offset <= 0xffff) {
- add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 8) | (12 << 8));
+ add_r(ARMRegisters::S0, base, Op2Immediate | (offset >> 8) | (12 << 8));
dtrh_u(transferType, srcDst, ARMRegisters::S0, getOp2Half(offset & 0xff));
} else {
moveImm(offset, ARMRegisters::S0);
@@ -317,7 +317,7 @@ void ARMAssembler::dataTransfer16(DataTransferTypeB transferType, RegisterID src
if (offset >= -0xff)
dtrh_d(transferType, srcDst, base, getOp2Half(-offset));
else if (offset >= -0xffff) {
- sub_r(ARMRegisters::S0, base, OP2_IMM | (-offset >> 8) | (12 << 8));
+ sub_r(ARMRegisters::S0, base, Op2Immediate | (-offset >> 8) | (12 << 8));
dtrh_d(transferType, srcDst, ARMRegisters::S0, getOp2Half(-offset & 0xff));
} else {
moveImm(offset, ARMRegisters::S0);
@@ -346,7 +346,7 @@ void ARMAssembler::dataTransferFloat(DataTransferTypeFloat transferType, FPRegis
return;
}
if (offset <= 0x3ffff && offset >= 0) {
- add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 10) | (11 << 8));
+ add_r(ARMRegisters::S0, base, Op2Immediate | (offset >> 10) | (11 << 8));
fdtr_u(transferType, srcDst, ARMRegisters::S0, (offset >> 2) & 0xff);
return;
}
@@ -357,7 +357,7 @@ void ARMAssembler::dataTransferFloat(DataTransferTypeFloat transferType, FPRegis
return;
}
if (offset <= 0x3ffff && offset >= 0) {
- sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 10) | (11 << 8));
+ sub_r(ARMRegisters::S0, base, Op2Immediate | (offset >> 10) | (11 << 8));
fdtr_d(transferType, srcDst, ARMRegisters::S0, (offset >> 2) & 0xff);
return;
}
@@ -392,10 +392,10 @@ PassRefPtr<ExecutableMemoryHandle> ARMAssembler::executableCopy(JSGlobalData& gl
ARMWord* addr = getLdrImmAddress(ldrAddr);
if (*addr != InvalidBranchTarget) {
if (!(iter->m_offset & 1)) {
- intptr_t difference = reinterpret_cast_ptr<ARMWord*>(data + *addr) - (ldrAddr + DefaultPrefetching);
+ intptr_t difference = reinterpret_cast_ptr<ARMWord*>(data + *addr) - (ldrAddr + DefaultPrefetchOffset);
- if ((difference <= BOFFSET_MAX && difference >= BOFFSET_MIN)) {
- *ldrAddr = B | getConditionalField(*ldrAddr) | (difference & BRANCH_MASK);
+ if ((difference <= MaximumBranchOffsetDistance && difference >= MinimumBranchOffsetDistance)) {
+ *ldrAddr = B | getConditionalField(*ldrAddr) | (difference & BranchOffsetMask);
continue;
}
}
diff --git a/Source/JavaScriptCore/assembler/ARMAssembler.h b/Source/JavaScriptCore/assembler/ARMAssembler.h
index 87aed853e..ac918f31e 100644
--- a/Source/JavaScriptCore/assembler/ARMAssembler.h
+++ b/Source/JavaScriptCore/assembler/ARMAssembler.h
@@ -179,52 +179,50 @@ namespace JSC {
};
enum {
- OP2_IMM = (1 << 25),
- OP2_IMM_HALF = (1 << 22),
- OP2_INV_IMM = (1 << 26),
- SET_CC = (1 << 20),
- OP2_OFSREG = (1 << 25),
+ Op2Immediate = (1 << 25),
+ ImmediateForHalfWordTransfer = (1 << 22),
+ Op2InvertedImmediate = (1 << 26),
+ SetConditionalCodes = (1 << 20),
+ Op2IsRegisterArgument = (1 << 25),
// Data transfer flags.
- DT_UP = (1 << 23),
- DT_WB = (1 << 21),
- DT_PRE = (1 << 24),
- DT_LOAD = (1 << 20),
- DT_BYTE = (1 << 22),
+ DataTransferUp = (1 << 23),
+ DataTransferWriteBack = (1 << 21),
+ DataTransferPostUpdate = (1 << 24),
+ DataTransferLoad = (1 << 20),
+ ByteDataTransfer = (1 << 22),
};
enum DataTransferTypeA {
- LoadUint32 = 0x05000000 | DT_LOAD,
- LoadUint8 = 0x05400000 | DT_LOAD,
+ LoadUint32 = 0x05000000 | DataTransferLoad,
+ LoadUint8 = 0x05400000 | DataTransferLoad,
StoreUint32 = 0x05000000,
StoreUint8 = 0x05400000,
};
enum DataTransferTypeB {
- LoadUint16 = 0x010000b0 | DT_LOAD,
- LoadInt16 = 0x010000f0 | DT_LOAD,
- LoadInt8 = 0x010000d0 | DT_LOAD,
+ LoadUint16 = 0x010000b0 | DataTransferLoad,
+ LoadInt16 = 0x010000f0 | DataTransferLoad,
+ LoadInt8 = 0x010000d0 | DataTransferLoad,
StoreUint16 = 0x010000b0,
};
enum DataTransferTypeFloat {
- LoadFloat = 0x0d000a00 | DT_LOAD,
- LoadDouble = 0x0d000b00 | DT_LOAD,
+ LoadFloat = 0x0d000a00 | DataTransferLoad,
+ LoadDouble = 0x0d000b00 | DataTransferLoad,
StoreFloat = 0x0d000a00,
StoreDouble = 0x0d000b00,
};
// Masks of ARM instructions
enum {
- BRANCH_MASK = 0x00ffffff,
- NONARM = 0xf0000000,
- SDT_MASK = 0x0c000000,
- SDT_OFFSET_MASK = 0xfff,
+ BranchOffsetMask = 0x00ffffff,
+ ConditionalFieldMask = 0xf0000000,
+ DataTransferOffsetMask = 0xfff,
};
enum {
- BOFFSET_MIN = -0x00800000,
- BOFFSET_MAX = 0x007fffff,
- SDT = 0x04000000,
+ MinimumBranchOffsetDistance = -0x00800000,
+ MaximumBranchOffsetDistance = 0x007fffff,
};
enum {
@@ -233,19 +231,28 @@ namespace JSC {
padForAlign32 = 0xe12fff7f // 'bkpt 0xffff' instruction.
};
- static const ARMWord INVALID_IMM = 0xf0000000;
+ static const ARMWord InvalidImmediate = 0xf0000000;
static const ARMWord InvalidBranchTarget = 0xffffffff;
- static const int DefaultPrefetching = 2;
+ static const int DefaultPrefetchOffset = 2;
+
+ static const ARMWord BlxInstructionMask = 0x012fff30;
+ static const ARMWord LdrOrAddInstructionMask = 0x0ff00000;
+ static const ARMWord LdrPcImmediateInstructionMask = 0x0f7f0000;
+
+ static const ARMWord AddImmediateInstruction = 0x02800000;
+ static const ARMWord BlxInstruction = 0x012fff30;
+ static const ARMWord LdrImmediateInstruction = 0x05900000;
+ static const ARMWord LdrPcImmediateInstruction = 0x051f0000;
// Instruction formating
- void emitInst(ARMWord op, int rd, int rn, ARMWord op2)
+ void emitInstruction(ARMWord op, int rd, int rn, ARMWord op2)
{
- ASSERT(((op2 & ~OP2_IMM) <= 0xfff) || (((op2 & ~OP2_IMM_HALF) <= 0xfff)));
+ ASSERT(((op2 & ~Op2Immediate) <= 0xfff) || (((op2 & ~ImmediateForHalfWordTransfer) <= 0xfff)));
m_buffer.putInt(op | RN(rn) | RD(rd) | op2);
}
- void emitDoublePrecisionInst(ARMWord op, int dd, int dn, int dm)
+ void emitDoublePrecisionInstruction(ARMWord op, int dd, int dn, int dm)
{
ASSERT((dd >= 0 && dd <= 31) && (dn >= 0 && dn <= 31) && (dm >= 0 && dm <= 31));
m_buffer.putInt(op | ((dd & 0xf) << 12) | ((dd & 0x10) << (22 - 4))
@@ -253,7 +260,7 @@ namespace JSC {
| (dm & 0xf) | ((dm & 0x10) << (5 - 4)));
}
- void emitSinglePrecisionInst(ARMWord op, int sd, int sn, int sm)
+ void emitSinglePrecisionInstruction(ARMWord op, int sd, int sn, int sm)
{
ASSERT((sd >= 0 && sd <= 31) && (sn >= 0 && sn <= 31) && (sm >= 0 && sm <= 31));
m_buffer.putInt(op | ((sd >> 1) << 12) | ((sd & 0x1) << 22)
@@ -263,292 +270,292 @@ namespace JSC {
void and_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | AND, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | AND, rd, rn, op2);
}
void ands_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | AND | SET_CC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | AND | SetConditionalCodes, rd, rn, op2);
}
void eor_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | EOR, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | EOR, rd, rn, op2);
}
void eors_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | EOR | SET_CC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | EOR | SetConditionalCodes, rd, rn, op2);
}
void sub_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | SUB, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | SUB, rd, rn, op2);
}
void subs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | SUB | SET_CC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | SUB | SetConditionalCodes, rd, rn, op2);
}
void rsb_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | RSB, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | RSB, rd, rn, op2);
}
void rsbs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | RSB | SET_CC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | RSB | SetConditionalCodes, rd, rn, op2);
}
void add_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | ADD, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | ADD, rd, rn, op2);
}
void adds_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | ADD | SET_CC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | ADD | SetConditionalCodes, rd, rn, op2);
}
void adc_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | ADC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | ADC, rd, rn, op2);
}
void adcs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | ADC | SET_CC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | ADC | SetConditionalCodes, rd, rn, op2);
}
void sbc_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | SBC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | SBC, rd, rn, op2);
}
void sbcs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | SBC | SET_CC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | SBC | SetConditionalCodes, rd, rn, op2);
}
void rsc_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | RSC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | RSC, rd, rn, op2);
}
void rscs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | RSC | SET_CC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | RSC | SetConditionalCodes, rd, rn, op2);
}
void tst_r(int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | TST | SET_CC, 0, rn, op2);
+ emitInstruction(toARMWord(cc) | TST | SetConditionalCodes, 0, rn, op2);
}
void teq_r(int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | TEQ | SET_CC, 0, rn, op2);
+ emitInstruction(toARMWord(cc) | TEQ | SetConditionalCodes, 0, rn, op2);
}
void cmp_r(int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | CMP | SET_CC, 0, rn, op2);
+ emitInstruction(toARMWord(cc) | CMP | SetConditionalCodes, 0, rn, op2);
}
void cmn_r(int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | CMN | SET_CC, 0, rn, op2);
+ emitInstruction(toARMWord(cc) | CMN | SetConditionalCodes, 0, rn, op2);
}
void orr_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | ORR, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | ORR, rd, rn, op2);
}
void orrs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | ORR | SET_CC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | ORR | SetConditionalCodes, rd, rn, op2);
}
void mov_r(int rd, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | MOV, rd, ARMRegisters::r0, op2);
+ emitInstruction(toARMWord(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);
+ m_buffer.putInt(toARMWord(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);
+ m_buffer.putInt(toARMWord(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);
+ emitInstruction(toARMWord(cc) | MOV | SetConditionalCodes, rd, ARMRegisters::r0, op2);
}
void bic_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | BIC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | BIC, rd, rn, op2);
}
void bics_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | BIC | SET_CC, rd, rn, op2);
+ emitInstruction(toARMWord(cc) | BIC | SetConditionalCodes, rd, rn, op2);
}
void mvn_r(int rd, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | MVN, rd, ARMRegisters::r0, op2);
+ emitInstruction(toARMWord(cc) | MVN, rd, ARMRegisters::r0, op2);
}
void mvns_r(int rd, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | MVN | SET_CC, rd, ARMRegisters::r0, op2);
+ emitInstruction(toARMWord(cc) | MVN | SetConditionalCodes, rd, ARMRegisters::r0, op2);
}
void mul_r(int rd, int rn, int rm, Condition cc = AL)
{
- m_buffer.putInt(static_cast<ARMWord>(cc) | MUL | RN(rd) | RS(rn) | RM(rm));
+ m_buffer.putInt(toARMWord(cc) | MUL | RN(rd) | RS(rn) | RM(rm));
}
void muls_r(int rd, int rn, int rm, Condition cc = AL)
{
- m_buffer.putInt(static_cast<ARMWord>(cc) | MUL | SET_CC | RN(rd) | RS(rn) | RM(rm));
+ m_buffer.putInt(toARMWord(cc) | MUL | SetConditionalCodes | RN(rd) | RS(rn) | RM(rm));
}
void mull_r(int rdhi, int rdlo, int rn, int rm, Condition cc = AL)
{
- m_buffer.putInt(static_cast<ARMWord>(cc) | MULL | RN(rdhi) | RD(rdlo) | RS(rn) | RM(rm));
+ m_buffer.putInt(toARMWord(cc) | MULL | RN(rdhi) | RD(rdlo) | RS(rn) | RM(rm));
}
void vmov_f64_r(int dd, int dm, Condition cc = AL)
{
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VMOV_F64, dd, 0, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VMOV_F64, dd, 0, dm);
}
void vadd_f64_r(int dd, int dn, int dm, Condition cc = AL)
{
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VADD_F64, dd, dn, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VADD_F64, dd, dn, dm);
}
void vdiv_f64_r(int dd, int dn, int dm, Condition cc = AL)
{
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VDIV_F64, dd, dn, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VDIV_F64, dd, dn, dm);
}
void vsub_f64_r(int dd, int dn, int dm, Condition cc = AL)
{
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VSUB_F64, dd, dn, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VSUB_F64, dd, dn, dm);
}
void vmul_f64_r(int dd, int dn, int dm, Condition cc = AL)
{
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VMUL_F64, dd, dn, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VMUL_F64, dd, dn, dm);
}
void vcmp_f64_r(int dd, int dm, Condition cc = AL)
{
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCMP_F64, dd, 0, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VCMP_F64, dd, 0, dm);
}
void vsqrt_f64_r(int dd, int dm, Condition cc = AL)
{
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VSQRT_F64, dd, 0, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VSQRT_F64, dd, 0, dm);
}
void vabs_f64_r(int dd, int dm, Condition cc = AL)
{
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VABS_F64, dd, 0, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VABS_F64, dd, 0, dm);
}
void vneg_f64_r(int dd, int dm, Condition cc = AL)
{
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VNEG_F64, dd, 0, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VNEG_F64, dd, 0, dm);
}
void ldr_imm(int rd, ARMWord imm, Condition cc = AL)
{
- m_buffer.putIntWithConstantInt(static_cast<ARMWord>(cc) | LoadUint32 | DT_UP | RN(ARMRegisters::pc) | RD(rd), imm, true);
+ m_buffer.putIntWithConstantInt(toARMWord(cc) | LoadUint32 | DataTransferUp | RN(ARMRegisters::pc) | RD(rd), imm, true);
}
void ldr_un_imm(int rd, ARMWord imm, Condition cc = AL)
{
- m_buffer.putIntWithConstantInt(static_cast<ARMWord>(cc) | LoadUint32 | DT_UP | RN(ARMRegisters::pc) | RD(rd), imm);
+ m_buffer.putIntWithConstantInt(toARMWord(cc) | LoadUint32 | DataTransferUp | RN(ARMRegisters::pc) | RD(rd), imm);
}
void dtr_u(DataTransferTypeA transferType, int rd, int rb, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | transferType | DT_UP, rd, rb, op2);
+ emitInstruction(toARMWord(cc) | transferType | DataTransferUp, rd, rb, op2);
}
void dtr_ur(DataTransferTypeA transferType, int rd, int rb, int rm, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | transferType | DT_UP | OP2_OFSREG, rd, rb, rm);
+ emitInstruction(toARMWord(cc) | transferType | DataTransferUp | Op2IsRegisterArgument, rd, rb, rm);
}
void dtr_d(DataTransferTypeA transferType, int rd, int rb, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | transferType, rd, rb, op2);
+ emitInstruction(toARMWord(cc) | transferType, rd, rb, op2);
}
void dtr_dr(DataTransferTypeA transferType, int rd, int rb, int rm, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | transferType | OP2_OFSREG, rd, rb, rm);
+ emitInstruction(toARMWord(cc) | transferType | Op2IsRegisterArgument, rd, rb, rm);
}
void dtrh_u(DataTransferTypeB transferType, int rd, int rb, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | transferType | DT_UP, rd, rb, op2);
+ emitInstruction(toARMWord(cc) | transferType | DataTransferUp, rd, rb, op2);
}
void dtrh_ur(DataTransferTypeB transferType, int rd, int rn, int rm, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | transferType | DT_UP, rd, rn, rm);
+ emitInstruction(toARMWord(cc) | transferType | DataTransferUp, rd, rn, rm);
}
void dtrh_d(DataTransferTypeB transferType, int rd, int rb, ARMWord op2, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | transferType, rd, rb, op2);
+ emitInstruction(toARMWord(cc) | transferType, rd, rb, op2);
}
void dtrh_dr(DataTransferTypeB transferType, int rd, int rn, int rm, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | transferType, rd, rn, rm);
+ emitInstruction(toARMWord(cc) | transferType, rd, rn, rm);
}
void fdtr_u(DataTransferTypeFloat type, int rd, int rb, ARMWord op2, Condition cc = AL)
{
ASSERT(op2 <= 0xff && rd <= 15);
/* Only d0-d15 and s0, s2, s4 ... s30 are supported. */
- m_buffer.putInt(static_cast<ARMWord>(cc) | DT_UP | type | (rd << 12) | RN(rb) | op2);
+ m_buffer.putInt(toARMWord(cc) | DataTransferUp | type | (rd << 12) | RN(rb) | op2);
}
void fdtr_d(DataTransferTypeFloat type, int rd, int rb, ARMWord op2, Condition cc = AL)
{
ASSERT(op2 <= 0xff && rd <= 15);
/* Only d0-d15 and s0, s2, s4 ... s30 are supported. */
- m_buffer.putInt(static_cast<ARMWord>(cc) | type | (rd << 12) | RN(rb) | op2);
+ m_buffer.putInt(toARMWord(cc) | type | (rd << 12) | RN(rb) | op2);
}
void push_r(int reg, Condition cc = AL)
{
ASSERT(ARMWord(reg) <= 0xf);
- m_buffer.putInt(static_cast<ARMWord>(cc) | StoreUint32 | DT_WB | RN(ARMRegisters::sp) | RD(reg) | 0x4);
+ m_buffer.putInt(toARMWord(cc) | StoreUint32 | DataTransferWriteBack | RN(ARMRegisters::sp) | RD(reg) | 0x4);
}
void pop_r(int reg, Condition cc = AL)
{
ASSERT(ARMWord(reg) <= 0xf);
- m_buffer.putInt(static_cast<ARMWord>(cc) | (LoadUint32 ^ DT_PRE) | DT_UP | RN(ARMRegisters::sp) | RD(reg) | 0x4);
+ m_buffer.putInt(toARMWord(cc) | (LoadUint32 ^ DataTransferPostUpdate) | DataTransferUp | RN(ARMRegisters::sp) | RD(reg) | 0x4);
}
inline void poke_r(int reg, Condition cc = AL)
@@ -564,65 +571,65 @@ namespace JSC {
void vmov_vfp64_r(int sm, int rt, int rt2, Condition cc = AL)
{
ASSERT(rt != rt2);
- m_buffer.putInt(static_cast<ARMWord>(cc) | VMOV_VFP64 | RN(rt2) | RD(rt) | (sm & 0xf) | ((sm & 0x10) << (5 - 4)));
+ m_buffer.putInt(toARMWord(cc) | VMOV_VFP64 | RN(rt2) | RD(rt) | (sm & 0xf) | ((sm & 0x10) << (5 - 4)));
}
void vmov_arm64_r(int rt, int rt2, int sm, Condition cc = AL)
{
ASSERT(rt != rt2);
- m_buffer.putInt(static_cast<ARMWord>(cc) | VMOV_ARM64 | RN(rt2) | RD(rt) | (sm & 0xf) | ((sm & 0x10) << (5 - 4)));
+ m_buffer.putInt(toARMWord(cc) | VMOV_ARM64 | RN(rt2) | RD(rt) | (sm & 0xf) | ((sm & 0x10) << (5 - 4)));
}
void vmov_vfp32_r(int sn, int rt, Condition cc = AL)
{
ASSERT(rt <= 15);
- emitSinglePrecisionInst(static_cast<ARMWord>(cc) | VMOV_VFP32, rt << 1, sn, 0);
+ emitSinglePrecisionInstruction(toARMWord(cc) | VMOV_VFP32, rt << 1, sn, 0);
}
void vmov_arm32_r(int rt, int sn, Condition cc = AL)
{
ASSERT(rt <= 15);
- emitSinglePrecisionInst(static_cast<ARMWord>(cc) | VMOV_ARM32, rt << 1, sn, 0);
+ emitSinglePrecisionInstruction(toARMWord(cc) | VMOV_ARM32, rt << 1, sn, 0);
}
void vcvt_f64_s32_r(int dd, int sm, Condition cc = AL)
{
ASSERT(!(sm & 0x1)); // sm must be divisible by 2
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_F64_S32, dd, 0, (sm >> 1));
+ emitDoublePrecisionInstruction(toARMWord(cc) | VCVT_F64_S32, dd, 0, (sm >> 1));
}
void vcvt_s32_f64_r(int sd, int dm, Condition cc = AL)
{
ASSERT(!(sd & 0x1)); // sd must be divisible by 2
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_S32_F64, (sd >> 1), 0, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VCVT_S32_F64, (sd >> 1), 0, dm);
}
void vcvt_u32_f64_r(int sd, int dm, Condition cc = AL)
{
ASSERT(!(sd & 0x1)); // sd must be divisible by 2
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_U32_F64, (sd >> 1), 0, dm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VCVT_U32_F64, (sd >> 1), 0, dm);
}
void vcvt_f64_f32_r(int dd, int sm, Condition cc = AL)
{
ASSERT(dd <= 15 && sm <= 15);
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_F64_F32, dd, 0, sm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VCVT_F64_F32, dd, 0, sm);
}
void vcvt_f32_f64_r(int dd, int sm, Condition cc = AL)
{
ASSERT(dd <= 15 && sm <= 15);
- emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_F32_F64, dd, 0, sm);
+ emitDoublePrecisionInstruction(toARMWord(cc) | VCVT_F32_F64, dd, 0, sm);
}
void vmrs_apsr(Condition cc = AL)
{
- m_buffer.putInt(static_cast<ARMWord>(cc) | VMRS_APSR);
+ m_buffer.putInt(toARMWord(cc) | VMRS_APSR);
}
void clz_r(int rd, int rm, Condition cc = AL)
{
- m_buffer.putInt(static_cast<ARMWord>(cc) | CLZ | RD(rd) | RM(rm));
+ m_buffer.putInt(toARMWord(cc) | CLZ | RD(rd) | RM(rm));
}
void bkpt(ARMWord value)
@@ -637,12 +644,12 @@ namespace JSC {
void bx(int rm, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | BX, 0, 0, RM(rm));
+ emitInstruction(toARMWord(cc) | BX, 0, 0, RM(rm));
}
AssemblerLabel blx(int rm, Condition cc = AL)
{
- emitInst(static_cast<ARMWord>(cc) | BLX, 0, 0, RM(rm));
+ emitInstruction(toARMWord(cc) | BLX, 0, 0, RM(rm));
return m_buffer.label();
}
@@ -773,28 +780,28 @@ namespace JSC {
static ARMWord* getLdrImmAddress(ARMWord* insn)
{
// Check for call
- if ((*insn & 0x0f7f0000) != 0x051f0000) {
+ if ((*insn & LdrPcImmediateInstructionMask) != LdrPcImmediateInstruction) {
// Must be BLX
- ASSERT((*insn & 0x012fff30) == 0x012fff30);
+ ASSERT((*insn & BlxInstructionMask) == BlxInstruction);
insn--;
}
// Must be an ldr ..., [pc +/- imm]
- ASSERT((*insn & 0x0f7f0000) == 0x051f0000);
+ ASSERT((*insn & LdrPcImmediateInstructionMask) == LdrPcImmediateInstruction);
- 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));
+ ARMWord addr = reinterpret_cast<ARMWord>(insn) + DefaultPrefetchOffset * sizeof(ARMWord);
+ if (*insn & DataTransferUp)
+ return reinterpret_cast<ARMWord*>(addr + (*insn & DataTransferOffsetMask));
+ return reinterpret_cast<ARMWord*>(addr - (*insn & DataTransferOffsetMask));
}
static ARMWord* getLdrImmAddressOnPool(ARMWord* insn, uint32_t* constPool)
{
// Must be an ldr ..., [pc +/- imm]
- ASSERT((*insn & 0x0f7f0000) == 0x051f0000);
+ ASSERT((*insn & LdrPcImmediateInstructionMask) == LdrPcImmediateInstruction);
if (*insn & 0x1)
- return reinterpret_cast<ARMWord*>(constPool + ((*insn & SDT_OFFSET_MASK) >> 1));
+ return reinterpret_cast<ARMWord*>(constPool + ((*insn & DataTransferOffsetMask) >> 1));
return getLdrImmAddress(insn);
}
@@ -808,8 +815,8 @@ namespace JSC {
static ARMWord patchConstantPoolLoad(ARMWord load, ARMWord value)
{
value = (value << 1) + 1;
- ASSERT(!(value & ~0xfff));
- return (load & ~0xfff) | value;
+ ASSERT(!(value & ~DataTransferOffsetMask));
+ return (load & ~DataTransferOffsetMask) | value;
}
static void patchConstantPoolLoad(void* loadAddr, void* constPoolAddr);
@@ -839,7 +846,7 @@ namespace JSC {
ARMWord* instruction = reinterpret_cast<ARMWord*>(where);
ASSERT((*instruction & 0x0f700000) == LoadUint32);
if (value >= 0)
- *instruction = (*instruction & 0xff7ff000) | DT_UP | value;
+ *instruction = (*instruction & 0xff7ff000) | DataTransferUp | value;
else
*instruction = (*instruction & 0xff7ff000) | -value;
cacheFlush(instruction, sizeof(ARMWord));
@@ -860,7 +867,7 @@ namespace JSC {
{
ARMWord* insn = reinterpret_cast<ARMWord*>(getAbsoluteJumpAddress(m_buffer.data(), from.m_offset));
ARMWord* addr = getLdrImmAddressOnPool(insn, m_buffer.poolAddress());
- *addr = static_cast<ARMWord>(to.m_offset);
+ *addr = toARMWord(to.m_offset);
}
static void linkJump(void* code, AssemblerLabel from, void* to)
@@ -891,13 +898,13 @@ namespace JSC {
static void replaceWithJump(void* instructionStart, void* to)
{
ARMWord* instruction = reinterpret_cast<ARMWord*>(instructionStart) - 1;
- intptr_t difference = reinterpret_cast<intptr_t>(to) - (reinterpret_cast<intptr_t>(instruction) + DefaultPrefetching * sizeof(ARMWord));
+ intptr_t difference = reinterpret_cast<intptr_t>(to) - (reinterpret_cast<intptr_t>(instruction) + DefaultPrefetchOffset * sizeof(ARMWord));
if (!(difference & 1)) {
difference >>= 2;
- if ((difference <= BOFFSET_MAX && difference >= BOFFSET_MIN)) {
+ if ((difference <= MaximumBranchOffsetDistance && difference >= MinimumBranchOffsetDistance)) {
// Direct branch.
- instruction[0] = B | AL | (difference & BRANCH_MASK);
+ instruction[0] = B | AL | (difference & BranchOffsetMask);
cacheFlush(instruction, sizeof(ARMWord));
return;
}
@@ -919,9 +926,9 @@ namespace JSC {
ARMWord* instruction = reinterpret_cast<ARMWord*>(instructionStart);
cacheFlush(instruction, sizeof(ARMWord));
- ASSERT((*instruction & 0x0ff00000) == 0x02800000 || (*instruction & 0x0ff00000) == 0x05900000);
- if ((*instruction & 0x0ff00000) == 0x02800000) {
- *instruction = (*instruction & 0xf00fffff) | 0x05900000;
+ ASSERT((*instruction & LdrOrAddInstructionMask) == AddImmediateInstruction || (*instruction & LdrOrAddInstructionMask) == LdrImmediateInstruction);
+ if ((*instruction & LdrOrAddInstructionMask) == AddImmediateInstruction) {
+ *instruction = (*instruction & ~LdrOrAddInstructionMask) | LdrImmediateInstruction;
cacheFlush(instruction, sizeof(ARMWord));
}
}
@@ -931,9 +938,9 @@ namespace JSC {
ARMWord* instruction = reinterpret_cast<ARMWord*>(instructionStart);
cacheFlush(instruction, sizeof(ARMWord));
- ASSERT((*instruction & 0x0ff00000) == 0x02800000 || (*instruction & 0x0ff00000) == 0x05900000);
- if ((*instruction & 0x0ff00000) == 0x05900000) {
- *instruction = (*instruction & 0xf00fffff) | 0x02800000;
+ ASSERT((*instruction & LdrOrAddInstructionMask) == AddImmediateInstruction || (*instruction & LdrOrAddInstructionMask) == LdrImmediateInstruction);
+ if ((*instruction & LdrOrAddInstructionMask) == LdrImmediateInstruction) {
+ *instruction = (*instruction & ~LdrOrAddInstructionMask) | AddImmediateInstruction;
cacheFlush(instruction, sizeof(ARMWord));
}
}
@@ -965,13 +972,13 @@ namespace JSC {
static ARMWord getOp2Byte(ARMWord imm)
{
ASSERT(imm <= 0xff);
- return OP2_IMM | imm;
+ return Op2Immediate | imm;
}
static ARMWord getOp2Half(ARMWord imm)
{
ASSERT(imm <= 0xff);
- return OP2_IMM_HALF | (imm & 0x0f) | ((imm & 0xf0) << 4);
+ return ImmediateForHalfWordTransfer | (imm & 0x0f) | ((imm & 0xf0) << 4);
}
#if WTF_ARM_ARCH_AT_LEAST(7)
@@ -979,7 +986,7 @@ namespace JSC {
{
if (imm <= 0xffff)
return (imm & 0xf000) << 4 | (imm & 0xfff);
- return INVALID_IMM;
+ return InvalidImmediate;
}
#endif
ARMWord getImm(ARMWord imm, int tmpReg, bool invert = false);
@@ -1000,8 +1007,8 @@ namespace JSC {
static ARMWord placeConstantPoolBarrier(int offset)
{
offset = (offset - sizeof(ARMWord)) >> 2;
- ASSERT((offset <= BOFFSET_MAX && offset >= BOFFSET_MIN));
- return AL | B | (offset & BRANCH_MASK);
+ ASSERT((offset <= MaximumBranchOffsetDistance && offset >= MinimumBranchOffsetDistance));
+ return AL | B | (offset & BranchOffsetMask);
}
#if OS(LINUX) && COMPILER(RVCT)
@@ -1067,7 +1074,17 @@ namespace JSC {
static ARMWord getConditionalField(ARMWord i)
{
- return i & 0xf0000000;
+ return i & ConditionalFieldMask;
+ }
+
+ static ARMWord toARMWord(Condition cc)
+ {
+ return static_cast<ARMWord>(cc);
+ }
+
+ static ARMWord toARMWord(uint32_t u)
+ {
+ return static_cast<ARMWord>(u);
}
int genInt(int reg, ARMWord imm, bool positive);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp b/Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp
index 3408c1230..a251a4376 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp
@@ -87,7 +87,7 @@ void MacroAssemblerARM::load32WithUnalignedHalfWords(BaseIndex address, Register
m_assembler.moveImm(address.offset, ARMRegisters::S0);
m_assembler.add_r(ARMRegisters::S0, ARMRegisters::S0, op2);
m_assembler.dtrh_ur(ARMAssembler::LoadUint16, dest, address.base, ARMRegisters::S0);
- m_assembler.add_r(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::OP2_IMM | 0x2);
+ m_assembler.add_r(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::Op2Immediate | 0x2);
m_assembler.dtrh_ur(ARMAssembler::LoadUint16, ARMRegisters::S0, address.base, ARMRegisters::S0);
}
m_assembler.orr_r(dest, dest, m_assembler.lsl(ARMRegisters::S0, 16));
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
index 530f62b86..85d0ffbcc 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -137,8 +137,8 @@ public:
void and32(TrustedImm32 imm, RegisterID dest)
{
ARMWord w = m_assembler.getImm(imm.m_value, ARMRegisters::S0, true);
- if (w & ARMAssembler::OP2_INV_IMM)
- m_assembler.bics_r(dest, dest, w & ~ARMAssembler::OP2_INV_IMM);
+ if (w & ARMAssembler::Op2InvertedImmediate)
+ m_assembler.bics_r(dest, dest, w & ~ARMAssembler::Op2InvertedImmediate);
else
m_assembler.ands_r(dest, dest, w);
}
@@ -146,8 +146,8 @@ public:
void and32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
ARMWord w = m_assembler.getImm(imm.m_value, ARMRegisters::S0, true);
- if (w & ARMAssembler::OP2_INV_IMM)
- m_assembler.bics_r(dest, src, w & ~ARMAssembler::OP2_INV_IMM);
+ if (w & ARMAssembler::Op2InvertedImmediate)
+ m_assembler.bics_r(dest, src, w & ~ARMAssembler::Op2InvertedImmediate);
else
m_assembler.ands_r(dest, src, w);
}
@@ -555,8 +555,8 @@ public:
Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right, int useConstantPool = 0)
{
- ARMWord tmp = (right.m_value == 0x80000000) ? ARMAssembler::INVALID_IMM : m_assembler.getOp2(-right.m_value);
- if (tmp != ARMAssembler::INVALID_IMM)
+ ARMWord tmp = (right.m_value == 0x80000000) ? ARMAssembler::InvalidImmediate : m_assembler.getOp2(-right.m_value);
+ if (tmp != ARMAssembler::InvalidImmediate)
m_assembler.cmn_r(left, tmp);
else
m_assembler.cmp_r(left, m_assembler.getImm(right.m_value, ARMRegisters::S0));
@@ -617,8 +617,8 @@ public:
{
ASSERT((cond == Zero) || (cond == NonZero));
ARMWord w = m_assembler.getImm(mask.m_value, ARMRegisters::S0, true);
- if (w & ARMAssembler::OP2_INV_IMM)
- m_assembler.bics_r(ARMRegisters::S0, reg, w & ~ARMAssembler::OP2_INV_IMM);
+ if (w & ARMAssembler::Op2InvertedImmediate)
+ m_assembler.bics_r(ARMRegisters::S0, reg, w & ~ARMAssembler::Op2InvertedImmediate);
else
m_assembler.tst_r(reg, w);
return Jump(m_assembler.jmp(ARMCondition(cond)));
@@ -1152,7 +1152,7 @@ public:
m_assembler.bic_r(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Byte(1));
ARMWord w = ARMAssembler::getOp2(0x80000000);
- ASSERT(w != ARMAssembler::INVALID_IMM);
+ ASSERT(w != ARMAssembler::InvalidImmediate);
m_assembler.cmp_r(ARMRegisters::S0, w);
return Jump(m_assembler.jmp(branchType == BranchIfTruncateFailed ? ARMAssembler::EQ : ARMAssembler::NE));
}
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index bc280acec..8b3ce9f03 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -43,6 +43,11 @@ public:
{
}
+ static bool isCompactPtrAlignedAddressOffset(ptrdiff_t value)
+ {
+ return value >= -2147483647 - 1 && value <= 2147483647;
+ }
+
static const Scale ScalePtr = TimesFour;
// For storing immediate number
@@ -189,6 +194,12 @@ public:
add32(dataTempRegister, dest);
}
+ void add32(AbsoluteAddress src, RegisterID dest)
+ {
+ load32(src.m_ptr, dataTempRegister);
+ add32(dataTempRegister, dest);
+ }
+
void add32(RegisterID src, Address dest)
{
if (dest.offset >= -32768 && dest.offset <= 32767 && !m_fixedWidth) {
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 5374a537a..0e2a98bc5 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -1525,7 +1525,8 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
int debugHookID = (++it)->u.operand;
int firstLine = (++it)->u.operand;
int lastLine = (++it)->u.operand;
- dataLog("[%4d] debug\t\t %s, %d, %d", location, debugHookName(debugHookID), firstLine, lastLine);
+ int column = (++it)->u.operand;
+ dataLog("[%4d] debug\t\t %s, %d, %d, %d", location, debugHookName(debugHookID), firstLine, lastLine, column);
dumpBytecodeCommentAndNewLine(location);
break;
}
diff --git a/Source/JavaScriptCore/bytecode/DFGExitProfile.h b/Source/JavaScriptCore/bytecode/DFGExitProfile.h
index d751ce654..e0aeba2bd 100644
--- a/Source/JavaScriptCore/bytecode/DFGExitProfile.h
+++ b/Source/JavaScriptCore/bytecode/DFGExitProfile.h
@@ -38,6 +38,7 @@ enum ExitKind {
BadCache, // We exited because an inline cache was wrong.
Overflow, // We exited because of overflow.
NegativeZero, // We exited because we encountered negative zero.
+ OutOfBounds, // We had an out-of-bounds access to an array.
InadequateCoverage, // We exited because we ended up in code that didn't have profiling coverage.
ArgumentsEscaped, // We exited because arguments escaped but we didn't expect them to.
Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h
index 14cefb9d9..4308e79df 100644
--- a/Source/JavaScriptCore/bytecode/Opcode.h
+++ b/Source/JavaScriptCore/bytecode/Opcode.h
@@ -194,7 +194,7 @@ namespace JSC {
macro(op_throw, 2) \
macro(op_throw_reference_error, 2) \
\
- macro(op_debug, 4) \
+ macro(op_debug, 5) \
macro(op_profile_will_call, 2) \
macro(op_profile_did_call, 2) \
\
diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.cpp b/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
index 02d0f7e77..399ab29c8 100644
--- a/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
+++ b/Source/JavaScriptCore/bytecode/SpeculatedType.cpp
@@ -226,9 +226,6 @@ SpeculatedType speculationFromClassInfo(const ClassInfo* classInfo)
if (classInfo == &JSArray::s_info)
return SpecArray;
- if (classInfo == &JSString::s_info)
- return SpecString;
-
if (classInfo == &Arguments::s_info)
return SpecArguments; // Cannot distinguish between MyArguments and ForeignArguments at this stage. That happens in the flow analysis.
@@ -269,6 +266,8 @@ SpeculatedType speculationFromClassInfo(const ClassInfo* classInfo)
SpeculatedType speculationFromStructure(Structure* structure)
{
+ if (structure->typeInfo().type() == StringType)
+ return SpecString;
return speculationFromClassInfo(structure->classInfo());
}
diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.h b/Source/JavaScriptCore/bytecode/SpeculatedType.h
index 91fb4fe4d..4ecc53776 100644
--- a/Source/JavaScriptCore/bytecode/SpeculatedType.h
+++ b/Source/JavaScriptCore/bytecode/SpeculatedType.h
@@ -243,6 +243,11 @@ inline bool isOtherSpeculation(SpeculatedType value)
return value == SpecOther;
}
+inline bool isOtherOrEmptySpeculation(SpeculatedType value)
+{
+ return !value || value == SpecOther;
+}
+
inline bool isEmptySpeculation(SpeculatedType value)
{
return value == SpecEmpty;
diff --git a/Source/JavaScriptCore/bytecode/ValueRecovery.h b/Source/JavaScriptCore/bytecode/ValueRecovery.h
index ebca661d0..1be5201ea 100644
--- a/Source/JavaScriptCore/bytecode/ValueRecovery.h
+++ b/Source/JavaScriptCore/bytecode/ValueRecovery.h
@@ -76,6 +76,9 @@ public:
{
}
+ bool isSet() const { return m_technique != DontKnow; }
+ bool operator!() const { return !isSet(); }
+
static ValueRecovery alreadyInRegisterFile()
{
ValueRecovery result;
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 33f282c66..14a69b530 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -1249,7 +1249,7 @@ ResolveResult BytecodeGenerator::resolve(const Identifier& property)
if (!currentScope->isVariableObject()) {
flags |= ResolveResult::DynamicFlag;
break;
- }
+ }
JSSymbolTableObject* currentVariableObject = jsCast<JSSymbolTableObject*>(currentScope);
SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.impl());
@@ -2083,7 +2083,7 @@ void BytecodeGenerator::emitPopScope()
m_dynamicScopeDepth--;
}
-void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
+void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine, int column)
{
#if ENABLE(DEBUG_WITH_BREAKPOINT)
if (debugHookID != DidReachBreakpoint)
@@ -2096,6 +2096,7 @@ void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, in
instructions().append(debugHookID);
instructions().append(firstLine);
instructions().append(lastLine);
+ instructions().append(column);
}
void BytecodeGenerator::pushFinallyContext(StatementNode* finallyBlock)
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 52fd7e83c..490991fa7 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -506,7 +506,7 @@ namespace JSC {
RegisterID* emitPushScope(RegisterID* scope);
void emitPopScope();
- void emitDebugHook(DebugHookID, int firstLine, int lastLine);
+ void emitDebugHook(DebugHookID, int firstLine, int lastLine, int column);
int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; }
bool hasFinaliser() { return m_finallyDepth != 0; }
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index d243e8ce0..249f822e2 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -202,18 +202,21 @@ bool ArrayNode::isSimpleArray() const
return true;
}
-ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData, int lineNumber) const
+ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData, int lineNumber, int columnNumber) const
{
ASSERT(!m_elision && !m_optional);
ElementNode* ptr = m_element;
if (!ptr)
return 0;
- ArgumentListNode* head = new (globalData) ArgumentListNode(lineNumber, ptr->value());
+ JSTokenLocation location;
+ location.line = lineNumber;
+ location.column = columnNumber;
+ ArgumentListNode* head = new (globalData) ArgumentListNode(location, ptr->value());
ArgumentListNode* tail = head;
ptr = ptr->next();
for (; ptr; ptr = ptr->next()) {
ASSERT(!ptr->elision());
- tail = new (globalData) ArgumentListNode(lineNumber, tail, ptr->value());
+ tail = new (globalData) ArgumentListNode(location, tail, ptr->value());
}
return head;
}
@@ -536,7 +539,7 @@ RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator,
if (m_args->m_listNode->m_next) {
ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
ASSERT(!m_args->m_listNode->m_next->m_next);
- m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.globalData(), 0);
+ m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.globalData(), 0, 0);
RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
CallArguments callArguments(generator, m_args);
generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
@@ -1385,7 +1388,7 @@ RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID
RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
return generator.emitNode(m_next);
}
@@ -1428,7 +1431,7 @@ RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
return dst;
}
@@ -1436,7 +1439,7 @@ RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, Regis
RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine());
+ generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine(), column());
return dst;
}
@@ -1445,7 +1448,7 @@ RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, Re
RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
ASSERT(m_expr);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
return generator.emitNode(dst, m_expr);
}
@@ -1454,7 +1457,7 @@ RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, Regist
RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
ASSERT(m_expr);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
return generator.emitNode(m_expr);
}
@@ -1462,7 +1465,7 @@ RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, Registe
RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
RefPtr<Label> afterThen = generator.newLabel();
@@ -1486,7 +1489,7 @@ RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
RefPtr<Label> beforeElse = generator.newLabel();
RefPtr<Label> afterElse = generator.newLabel();
@@ -1522,12 +1525,12 @@ RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
RefPtr<Label> topOfLoop = generator.newLabel();
generator.emitLabel(topOfLoop.get());
generator.emitLoopHint();
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
-
+ generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), column());
+
RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
generator.emitLabel(scope->continueTarget());
- generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
+ generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), column());
if (m_expr->hasConditionContextCodegen())
generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
else {
@@ -1546,7 +1549,7 @@ RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
RefPtr<Label> topOfLoop = generator.newLabel();
- generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
+ generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), m_expr->columnNo());
if (m_expr->hasConditionContextCodegen())
generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), true);
else {
@@ -1560,7 +1563,7 @@ RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
generator.emitNode(dst, m_statement);
generator.emitLabel(scope->continueTarget());
- generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
if (m_expr->hasConditionContextCodegen())
generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
@@ -1581,7 +1584,7 @@ RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
if (m_expr1)
generator.emitNode(generator.ignoredResult(), m_expr1);
@@ -1602,7 +1605,7 @@ RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
generator.emitLabel(scope->continueTarget());
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
if (m_expr3)
generator.emitNode(generator.ignoredResult(), m_expr3);
@@ -1629,7 +1632,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
if (!m_lexpr->isLocation())
return emitThrowReferenceError(generator, "Left side of for-in statement is not a reference.");
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
if (m_init)
generator.emitNode(generator.ignoredResult(), m_init);
@@ -1692,7 +1695,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
generator.emitLabel(scope->continueTarget());
generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get());
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
generator.emitLabel(scope->breakTarget());
return dst;
}
@@ -1702,7 +1705,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
// ECMA 12.7
RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
LabelScope* scope = generator.continueTarget(m_ident);
ASSERT(scope);
@@ -1716,7 +1719,7 @@ RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
// ECMA 12.8
RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
LabelScope* scope = generator.breakTarget(m_ident);
ASSERT(scope);
@@ -1729,7 +1732,7 @@ RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
ASSERT(generator.codeType() == FunctionCode);
if (dst == generator.ignoredResult())
@@ -1745,7 +1748,7 @@ RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
generator.emitJumpScopes(l0.get(), 0);
generator.emitLabel(l0.get());
}
- generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
+ generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), column());
return generator.emitReturn(r0);
}
@@ -1753,7 +1756,7 @@ RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
RefPtr<RegisterID> scope = generator.newTemporary();
generator.emitNode(scope.get(), m_expr); // scope must be protected until popped
@@ -1918,7 +1921,7 @@ RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, Re
RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
@@ -1933,7 +1936,7 @@ RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
ASSERT(!generator.breakTarget(m_name));
@@ -1948,7 +1951,7 @@ RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
if (dst == generator.ignoredResult())
dst = 0;
@@ -1965,7 +1968,7 @@ 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.
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
RefPtr<Label> tryStartLabel = generator.newLabel();
if (m_finallyBlock)
@@ -2022,13 +2025,13 @@ inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, Regi
RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
+ 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());
+ generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine(), column());
generator.emitEnd(dstRegister.get());
return 0;
}
@@ -2037,13 +2040,13 @@ RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine());
+ 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());
+ generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine(), column());
generator.emitEnd(dstRegister.get());
return 0;
}
@@ -2052,7 +2055,7 @@ RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
+ generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine(), column());
emitStatementsBytecode(generator, generator.ignoredResult());
StatementNode* singleStatement = this->singleStatement();
@@ -2068,7 +2071,7 @@ RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, Registe
// If there is no return we must automatically insert one.
if (!returnNode) {
RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
- generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
+ generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), column());
generator.emitReturn(r0);
return 0;
}
diff --git a/Source/JavaScriptCore/debugger/Debugger.h b/Source/JavaScriptCore/debugger/Debugger.h
index a23732918..bc743677e 100644
--- a/Source/JavaScriptCore/debugger/Debugger.h
+++ b/Source/JavaScriptCore/debugger/Debugger.h
@@ -42,14 +42,16 @@ namespace JSC {
virtual void detach(JSGlobalObject*);
virtual void sourceParsed(ExecState*, SourceProvider*, int errorLineNumber, const UString& errorMessage) = 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) = 0;
+ virtual void exception(const DebuggerCallFrame&, intptr_t, int, int, bool) = 0;
+ virtual void atStatement(const DebuggerCallFrame&, intptr_t, int, int) = 0;
+ virtual void callEvent(const DebuggerCallFrame&, intptr_t, int, int) = 0;
+ virtual void returnEvent(const DebuggerCallFrame&, intptr_t, int, int) = 0;
+
+ virtual void willExecuteProgram(const DebuggerCallFrame&, intptr_t, int, int) = 0;
+ virtual void didExecuteProgram(const DebuggerCallFrame&, intptr_t, int, int) = 0;
+ virtual void didReachBreakpoint(const DebuggerCallFrame&, intptr_t, int, int) = 0;
+
void recompileAllJSFunctions(JSGlobalData*);
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index 01996f132..4f02ee793 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -950,7 +950,8 @@ bool AbstractState::execute(unsigned indexInBlock)
}
case PutByVal:
- case PutByValAlias: {
+ case PutByValAlias:
+ case PutByValSafe: {
node.setCanExit(true);
Edge child1 = m_graph.varArgChild(node, 0);
@@ -966,7 +967,7 @@ bool AbstractState::execute(unsigned indexInBlock)
|| m_graph[child1].shouldSpeculateArguments()
#endif
) {
- ASSERT(node.op() == PutByVal);
+ ASSERT(node.op() == PutByVal || node.op() == PutByValSafe);
clobberWorld(node.codeOrigin, indexInBlock);
forNode(nodeIndex).makeTop();
break;
@@ -1055,7 +1056,7 @@ bool AbstractState::execute(unsigned indexInBlock)
ASSERT(m_graph[child1].shouldSpeculateArray());
forNode(child1).filter(SpecArray);
forNode(child2).filter(SpecInt32);
- if (node.op() == PutByVal)
+ if (node.op() == PutByValSafe)
clobberWorld(node.codeOrigin, indexInBlock);
break;
}
@@ -1335,7 +1336,7 @@ bool AbstractState::execute(unsigned indexInBlock)
case PutScopedVar:
node.setCanExit(false);
- clobberStructures(indexInBlock);
+ clobberCapturedVars(node.codeOrigin);
break;
case GetById:
@@ -1415,7 +1416,8 @@ bool AbstractState::execute(unsigned indexInBlock)
forNode(nodeIndex).set(SpecInt32);
break;
- case CheckStructure: {
+ case CheckStructure:
+ case ForwardCheckStructure: {
// FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
AbstractValue& value = forNode(node.child1());
node.setCanExit(
@@ -1431,6 +1433,7 @@ bool AbstractState::execute(unsigned indexInBlock)
AbstractValue& value = forNode(node.child1());
ASSERT(value.isClear() || isCellSpeculation(value.m_type)); // Value could be clear if we've proven must-exit due to a speculation statically known to be bad.
value.filter(node.structure());
+ m_haveStructures = true;
node.setCanExit(true);
break;
}
@@ -1609,6 +1612,12 @@ bool AbstractState::execute(unsigned indexInBlock)
inline void AbstractState::clobberWorld(const CodeOrigin& codeOrigin, unsigned indexInBlock)
{
+ clobberCapturedVars(codeOrigin);
+ clobberStructures(indexInBlock);
+}
+
+inline void AbstractState::clobberCapturedVars(const CodeOrigin& codeOrigin)
+{
if (codeOrigin.inlineCallFrame) {
const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
for (size_t i = capturedVars.size(); i--;) {
@@ -1624,7 +1633,6 @@ inline void AbstractState::clobberWorld(const CodeOrigin& codeOrigin, unsigned i
for (size_t i = m_variables.numberOfArguments(); i--;)
m_variables.argument(i).makeTop();
}
- clobberStructures(indexInBlock);
}
inline void AbstractState::clobberStructures(unsigned indexInBlock)
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.h b/Source/JavaScriptCore/dfg/DFGAbstractState.h
index 95cadecbb..d2bc1a551 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.h
@@ -217,6 +217,7 @@ public:
private:
void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
+ void clobberCapturedVars(const CodeOrigin&);
void clobberStructures(unsigned indexInBlock);
bool mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, NodeIndex);
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractValue.h b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
index f81af4ecf..402fd0fcd 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractValue.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.h
@@ -317,13 +317,14 @@ struct AbstractValue {
{
m_type = SpecNone;
m_structure.clear();
+ m_unclobberedStructure.clear();
m_value = JSValue();
checkConsistency();
}
bool isClear() const
{
- bool result = m_type == SpecNone && m_structure.isClear();
+ bool result = m_type == SpecNone && m_structure.isClear() && m_unclobberedStructure.isClear();
if (result)
ASSERT(!m_value);
return result;
@@ -333,6 +334,7 @@ struct AbstractValue {
{
m_type = SpecTop;
m_structure.makeTop();
+ m_unclobberedStructure.makeTop();
m_value = JSValue();
checkConsistency();
}
@@ -353,7 +355,7 @@ struct AbstractValue {
bool isTop() const
{
- return m_type == SpecTop && m_structure.isTop();
+ return m_type == SpecTop && m_structure.isTop() && m_unclobberedStructure.isTop();
}
bool valueIsTop() const
@@ -383,8 +385,11 @@ struct AbstractValue {
// it may change in the future - for example between when we compile
// the code and when we run it.
m_structure.makeTop();
- } else
+ m_unclobberedStructure.makeTop(); // FIXME: Consider not clobbering this.
+ } else {
m_structure.clear();
+ m_unclobberedStructure.clear();
+ }
m_type = speculationFromValue(value);
m_value = value;
@@ -397,6 +402,9 @@ struct AbstractValue {
m_structure.clear();
m_structure.add(structure);
+ m_unclobberedStructure.clear();
+ m_unclobberedStructure.add(structure);
+
m_type = speculationFromStructure(structure);
m_value = JSValue();
@@ -405,10 +413,13 @@ struct AbstractValue {
void set(SpeculatedType type)
{
- if (type & SpecCell)
+ if (type & SpecCell) {
m_structure.makeTop();
- else
+ m_unclobberedStructure.makeTop();
+ } else {
m_structure.clear();
+ m_unclobberedStructure.clear();
+ }
m_type = type;
m_value = JSValue();
checkConsistency();
@@ -418,6 +429,7 @@ struct AbstractValue {
{
return m_type == other.m_type
&& m_structure == other.m_structure
+ && m_unclobberedStructure == other.m_unclobberedStructure
&& m_value == other.m_value;
}
bool operator!=(const AbstractValue& other) const
@@ -437,6 +449,7 @@ struct AbstractValue {
} else {
result |= mergeSpeculation(m_type, other.m_type);
result |= m_structure.addAll(other.m_structure);
+ result |= m_unclobberedStructure.addAll(other.m_unclobberedStructure);
if (m_value != other.m_value) {
result |= !!m_value;
m_value = JSValue();
@@ -451,8 +464,10 @@ struct AbstractValue {
{
mergeSpeculation(m_type, type);
- if (type & SpecCell)
+ if (type & SpecCell) {
m_structure.makeTop();
+ m_unclobberedStructure.makeTop();
+ }
m_value = JSValue();
checkConsistency();
@@ -462,6 +477,7 @@ struct AbstractValue {
{
m_type &= other.speculationFromStructures();
m_structure.filter(other);
+ m_unclobberedStructure.filter(other);
// It's possible that prior to the above two statements we had (Foo, TOP), where
// Foo is a SpeculatedType that is disjoint with the passed StructureSet. In that
@@ -469,6 +485,7 @@ struct AbstractValue {
// sure that new information gleaned from the SpeculatedType needs to be fed back
// into the information gleaned from the StructureSet.
m_structure.filter(m_type);
+ m_unclobberedStructure.filter(m_type);
if (!!m_value && !validateIgnoringValue(m_value))
clear();
@@ -487,6 +504,7 @@ struct AbstractValue {
// to ensure that the structure filtering does the right thing is to filter on
// the new type (None) rather than the one passed (Array).
m_structure.filter(m_type);
+ m_unclobberedStructure.filter(m_type);
if (!!m_value && !validateIgnoringValue(m_value))
clear();
@@ -523,8 +541,8 @@ struct AbstractValue {
if (isTop())
return true;
- if (!!m_value)
- return m_value == value;
+ if (!!m_value && m_value != value)
+ return false;
if (mergeSpeculations(m_type, speculationFromValue(value)) != m_type)
return false;
@@ -545,10 +563,39 @@ struct AbstractValue {
return true;
}
+ bool validateForEntry(JSValue value) const
+ {
+ if (isTop())
+ return true;
+
+ if (!!m_value && m_value != value)
+ return false;
+
+ if (mergeSpeculations(m_type, speculationFromValue(value)) != m_type)
+ return false;
+
+ if (value.isEmpty()) {
+ ASSERT(m_type & SpecEmpty);
+ return true;
+ }
+
+ if (m_unclobberedStructure.isTop())
+ return true;
+
+ if (!!value && value.isCell()) {
+ ASSERT(m_type & SpecCell);
+ return m_unclobberedStructure.contains(value.asCell()->structure());
+ }
+
+ return true;
+ }
+
void checkConsistency() const
{
- if (!(m_type & SpecCell))
+ if (!(m_type & SpecCell)) {
ASSERT(m_structure.isClear());
+ ASSERT(m_unclobberedStructure.isClear());
+ }
if (isClear())
ASSERT(!m_value);
@@ -566,12 +613,15 @@ struct AbstractValue {
{
fprintf(out, "(%s, ", speculationToString(m_type));
m_structure.dump(out);
+ dataLog(", ");
+ m_unclobberedStructure.dump(out);
if (!!m_value)
fprintf(out, ", %s", m_value.description());
fprintf(out, ")");
}
StructureAbstractValue m_structure;
+ StructureAbstractValue m_unclobberedStructure;
SpeculatedType m_type;
JSValue m_value;
};
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index e4e94e90b..b7f48aa4b 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -257,6 +257,8 @@ private:
}
VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
+ variableAccessData->mergeStructureCheckHoistingFailed(
+ m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
NodeIndex nodeIndex = addToGraph(SetLocal, OpInfo(variableAccessData), value);
m_currentBlock->variablesAtTail.local(operand) = nodeIndex;
}
@@ -299,7 +301,8 @@ private:
// We're getting an argument in the first basic block; link
// the GetLocal to the SetArgument.
ASSERT(nodePtr->local() == static_cast<VirtualRegister>(operand));
- nodeIndex = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(nodePtr->variableAccessData()), nodeIndex));
+ VariableAccessData* variable = nodePtr->variableAccessData();
+ nodeIndex = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable), nodeIndex));
m_currentBlock->variablesAtTail.argument(argument) = nodeIndex;
return nodeIndex;
}
@@ -340,6 +343,8 @@ private:
flushDirect(operand);
VariableAccessData* variableAccessData = newVariableAccessData(operand, isCaptured);
+ variableAccessData->mergeStructureCheckHoistingFailed(
+ m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
NodeIndex nodeIndex = addToGraph(SetLocal, OpInfo(variableAccessData), value);
m_currentBlock->variablesAtTail.argument(argument) = nodeIndex;
}
@@ -1723,7 +1728,11 @@ bool ByteCodeParser::parseBlock(unsigned limit)
if (m_currentBlock == m_graph.m_blocks[0].get() && !m_inlineStackTop->m_inlineCallFrame) {
m_graph.m_arguments.resize(m_numArguments);
for (unsigned argument = 0; argument < m_numArguments; ++argument) {
- NodeIndex setArgument = addToGraph(SetArgument, OpInfo(newVariableAccessData(argumentToOperand(argument), m_codeBlock->argumentIsCaptured(argument))));
+ VariableAccessData* variable = newVariableAccessData(
+ argumentToOperand(argument), m_codeBlock->argumentIsCaptured(argument));
+ variable->mergeStructureCheckHoistingFailed(
+ m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache));
+ NodeIndex setArgument = addToGraph(SetArgument, OpInfo(variable));
m_graph.m_arguments[argument] = setArgument;
m_currentBlock->variablesAtHead.setArgumentFirstTime(argument, setArgument);
m_currentBlock->variablesAtTail.setArgumentFirstTime(argument, setArgument);
@@ -2152,10 +2161,14 @@ bool ByteCodeParser::parseBlock(unsigned limit)
NodeIndex property = get(currentInstruction[2].u.operand);
NodeIndex value = get(currentInstruction[3].u.operand);
+ bool makeSafe =
+ m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex)
+ || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, OutOfBounds);
+
addVarArgChild(base);
addVarArgChild(property);
addVarArgChild(value);
- addToGraph(Node::VarArg, PutByVal, OpInfo(0), OpInfo(0));
+ addToGraph(Node::VarArg, makeSafe ? PutByValSafe : PutByVal, OpInfo(0), OpInfo(0));
NEXT_OPCODE(op_put_by_val);
}
@@ -2222,7 +2235,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
case op_get_by_id:
case op_get_by_id_out_of_line: {
- SpeculatedType prediction = getPredictionWithoutOSRExit();
+ SpeculatedType prediction = getPrediction();
NodeIndex base = get(currentInstruction[2].u.operand);
unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
@@ -3010,6 +3023,7 @@ void ByteCodeParser::fixVariableAccessSpeculations()
VariableAccessData* data = &m_graph.m_variableAccessData[i];
data->find()->predict(data->nonUnifiedPrediction());
data->find()->mergeIsCaptured(data->isCaptured());
+ data->find()->mergeStructureCheckHoistingFailed(data->structureCheckHoistingFailed());
}
}
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
index 4532214ee..e9b1e0d8b 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
@@ -284,7 +284,8 @@ private:
return index;
break;
case PutByVal:
- case PutByValAlias: {
+ case PutByValAlias:
+ case PutByValSafe: {
if (!m_graph.byValIsPure(node))
return NoNode;
if (m_graph.varArgChild(node, 0) == child1 && canonicalize(m_graph.varArgChild(node, 1)) == canonicalize(child2))
@@ -337,6 +338,7 @@ private:
Node& node = m_graph[index];
switch (node.op()) {
case CheckStructure:
+ case ForwardCheckStructure:
if (node.child1() == child1
&& structureSet.isSupersetOf(node.structureSet()))
return true;
@@ -362,6 +364,7 @@ private:
case PutByVal:
case PutByValAlias:
+ case PutByValSafe:
if (m_graph.byValIsPure(node)) {
// If PutByVal speculates that it's accessing an array with an
// integer index, then it's impossible for it to cause a structure
@@ -389,6 +392,7 @@ private:
Node& node = m_graph[index];
switch (node.op()) {
case CheckStructure:
+ case ForwardCheckStructure:
if (node.child1() == child1
&& node.structureSet().containsOnly(structure))
return true;
@@ -404,6 +408,7 @@ private:
case PutByVal:
case PutByValAlias:
+ case PutByValSafe:
if (m_graph.byValIsPure(node)) {
// If PutByVal speculates that it's accessing an array with an
// integer index, then it's impossible for it to cause a structure
@@ -437,6 +442,7 @@ private:
break;
switch (node.op()) {
case CheckStructure:
+ case ForwardCheckStructure:
return NoNode;
case PhantomPutStructure:
@@ -507,6 +513,7 @@ private:
case PutByVal:
case PutByValAlias:
+ case PutByValSafe:
if (m_graph.byValIsPure(node)) {
// If PutByVal speculates that it's accessing an array with an
// integer index, then it's impossible for it to cause a structure
@@ -551,6 +558,7 @@ private:
case PutByVal:
case PutByValAlias:
case GetByVal:
+ case PutByValSafe:
if (m_graph.byValIsPure(node)) {
// If PutByVal speculates that it's accessing an array with an
// integer index, then it's impossible for it to cause a structure
@@ -603,6 +611,7 @@ private:
case PutByVal:
case PutByValAlias:
+ case PutByValSafe:
if (m_graph.byValIsPure(node)) {
// If PutByVal speculates that it's accessing an array with an
// integer index, then it's impossible for it to cause a structure
@@ -643,15 +652,6 @@ private:
// change the property storage pointer.
break;
- case PutByValAlias:
- // PutByValAlias can't change the indexed storage pointer
- break;
-
- case PutByVal:
- if (isFixedIndexedStorageObjectSpeculation(m_graph[m_graph.varArgChild(node, 0)].prediction()) && m_graph.byValIsPure(node))
- break;
- return NoNode;
-
default:
if (m_graph.clobbersWorld(index))
return NoNode;
@@ -673,7 +673,7 @@ private:
return NoNode;
}
- NodeIndex getLocalLoadElimination(VirtualRegister local, NodeIndex& relevantLocalOp)
+ NodeIndex getLocalLoadElimination(VirtualRegister local, NodeIndex& relevantLocalOp, bool careAboutClobbering)
{
relevantLocalOp = NoNode;
@@ -703,7 +703,7 @@ private:
break;
default:
- if (m_graph.clobbersWorld(index))
+ if (careAboutClobbering && m_graph.clobbersWorld(index))
return NoNode;
break;
}
@@ -944,13 +944,15 @@ private:
case GetLocal: {
VariableAccessData* variableAccessData = node.variableAccessData();
- if (!variableAccessData->isCaptured())
+ if (m_fixpointState == FixpointNotConverged && !variableAccessData->isCaptured())
break;
NodeIndex relevantLocalOp;
- NodeIndex possibleReplacement = getLocalLoadElimination(variableAccessData->local(), relevantLocalOp);
- ASSERT(relevantLocalOp == NoNode
- || m_graph[relevantLocalOp].op() == GetLocalUnlinked
- || m_graph[relevantLocalOp].variableAccessData() == variableAccessData);
+ NodeIndex possibleReplacement = getLocalLoadElimination(variableAccessData->local(), relevantLocalOp, variableAccessData->isCaptured());
+ if (relevantLocalOp == NoNode)
+ break;
+ if (m_graph[relevantLocalOp].op() != GetLocalUnlinked
+ && m_graph[relevantLocalOp].variableAccessData() != variableAccessData)
+ break;
NodeIndex phiIndex = node.child1().index();
if (!setReplacement(possibleReplacement))
break;
@@ -980,7 +982,7 @@ private:
case GetLocalUnlinked: {
NodeIndex relevantLocalOpIgnored;
- m_changed |= setReplacement(getLocalLoadElimination(node.unlinkedLocal(), relevantLocalOpIgnored));
+ m_changed |= setReplacement(getLocalLoadElimination(node.unlinkedLocal(), relevantLocalOpIgnored, true));
break;
}
@@ -1093,7 +1095,8 @@ private:
setReplacement(getByValLoadElimination(node.child1().index(), node.child2().index()));
break;
- case PutByVal: {
+ case PutByVal:
+ case PutByValSafe: {
Edge child1 = m_graph.varArgChild(node, 0);
Edge child2 = m_graph.varArgChild(node, 1);
if (isActionableMutableArraySpeculation(m_graph[child1].prediction())
@@ -1108,6 +1111,7 @@ private:
}
case CheckStructure:
+ case ForwardCheckStructure:
if (checkStructureLoadElimination(node.structureSet(), node.child1().index()))
eliminate();
break;
diff --git a/Source/JavaScriptCore/dfg/DFGDriver.cpp b/Source/JavaScriptCore/dfg/DFGDriver.cpp
index f160b6d35..ddad4f864 100644
--- a/Source/JavaScriptCore/dfg/DFGDriver.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDriver.cpp
@@ -38,6 +38,7 @@
#include "DFGJITCompiler.h"
#include "DFGPredictionPropagationPhase.h"
#include "DFGRedundantPhiEliminationPhase.h"
+#include "DFGStructureCheckHoistingPhase.h"
#include "DFGValidate.h"
#include "DFGVirtualRegisterAllocationPhase.h"
#include "Options.h"
@@ -101,7 +102,10 @@ inline bool compile(CompileMode compileMode, ExecState* exec, CodeBlock* codeBlo
dfg.resetExitStates();
performFixup(dfg);
}
+ bool shouldRedoCFA = performStructureCheckHoisting(dfg);
performCSE(dfg, FixpointConverged);
+ if (shouldRedoCFA)
+ performCFA(dfg);
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLog("DFG optimization fixpoint converged in %u iterations.\n", cnt);
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index a1954d7e0..4e3cd5782 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -314,7 +314,8 @@ private:
break;
}
- case PutByVal: {
+ case PutByVal:
+ case PutByValSafe: {
Edge child1 = m_graph.varArgChild(node, 0);
Edge child2 = m_graph.varArgChild(node, 1);
Edge child3 = m_graph.varArgChild(node, 2);
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index c7a4d94d2..9ae0648b8 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -207,7 +207,7 @@ void Graph::dump(const char* prefix, NodeIndex nodeIndex)
hasPrinted = !!node.child1();
}
- if (node.flags()) {
+ if (strlen(nodeFlagsAsString(node.flags()))) {
dataLog("%s%s", hasPrinted ? ", " : "", nodeFlagsAsString(node.flags()));
hasPrinted = true;
}
@@ -287,13 +287,15 @@ void Graph::dump(const char* prefix, NodeIndex nodeIndex)
dataLog("%sF:#%u", hasPrinted ? ", " : "", node.notTakenBlockIndex());
hasPrinted = true;
}
+ dataLog("%sbc#%u", hasPrinted ? ", " : "", node.codeOrigin.bytecodeIndex);
+ hasPrinted = true;
(void)hasPrinted;
dataLog(")");
if (!skipped) {
if (node.hasVariableAccessData())
- dataLog(" predicting %s, double ratio %lf%s", speculationToString(node.variableAccessData()->prediction()), node.variableAccessData()->doubleVoteRatio(), node.variableAccessData()->shouldUseDoubleFormat() ? ", forcing double" : "");
+ dataLog(" predicting %s%s", speculationToString(node.variableAccessData()->prediction()), node.variableAccessData()->shouldUseDoubleFormat() ? ", forcing double" : "");
else if (node.hasHeapPrediction())
dataLog(" predicting %s", speculationToString(node.getHeapPrediction()));
}
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index 3e6539353..fdb78cf9b 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -479,6 +479,15 @@ public:
SpeculatedType prediction = at(varArgChild(node, 0)).prediction();
if (!isActionableMutableArraySpeculation(prediction))
return false;
+ return true;
+ }
+
+ case PutByValSafe: {
+ if (!at(varArgChild(node, 1)).shouldSpeculateInteger())
+ return false;
+ SpeculatedType prediction = at(varArgChild(node, 0)).prediction();
+ if (!isActionableMutableArraySpeculation(prediction))
+ return false;
if (isArraySpeculation(prediction))
return false;
return true;
@@ -524,6 +533,7 @@ public:
return !isPredictedNumerical(node);
case GetByVal:
case PutByVal:
+ case PutByValSafe:
case PutByValAlias:
return !byValIsPure(node);
default:
@@ -568,6 +578,42 @@ public:
return node.children.child(index);
}
+ void vote(Edge edge, unsigned ballot)
+ {
+ switch (at(edge).op()) {
+ case ValueToInt32:
+ case UInt32ToNumber:
+ edge = at(edge).child1();
+ break;
+ default:
+ break;
+ }
+
+ if (at(edge).op() == GetLocal)
+ at(edge).variableAccessData()->vote(ballot);
+ }
+
+ void vote(Node& node, unsigned ballot)
+ {
+ if (node.flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node.firstChild();
+ childIdx < node.firstChild() + node.numChildren();
+ childIdx++)
+ vote(m_varArgChildren[childIdx], ballot);
+ return;
+ }
+
+ if (!node.child1())
+ return;
+ vote(node.child1(), ballot);
+ if (!node.child2())
+ return;
+ vote(node.child2(), ballot);
+ if (!node.child3())
+ return;
+ vote(node.child3(), ballot);
+ }
+
JSGlobalData& m_globalData;
CodeBlock* m_codeBlock;
CodeBlock* m_profiledBlock;
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index e72bd5e36..60cdd4b50 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -245,6 +245,13 @@ struct Node {
children.reset();
}
+ void convertToStructureTransitionWatchpoint()
+ {
+ ASSERT(m_op == CheckStructure);
+ m_opInfo = bitwise_cast<uintptr_t>(structureSet().singletonStructure());
+ m_op = StructureTransitionWatchpoint;
+ }
+
JSCell* weakConstant()
{
ASSERT(op() == WeakJSConstant);
@@ -651,7 +658,13 @@ struct Node {
bool hasStructureSet()
{
- return op() == CheckStructure;
+ switch (op()) {
+ case CheckStructure:
+ case ForwardCheckStructure:
+ return true;
+ default:
+ return false;
+ }
}
StructureSet& structureSet()
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index 0ca0039b9..7657663a9 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -113,12 +113,14 @@ namespace JSC { namespace DFG {
/* opcodes use VarArgs beause they may have up to 4 children. */\
macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
macro(PutByVal, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
+ macro(PutByValSafe, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
macro(GetById, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
macro(GetByIdFlush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
macro(PutById, NodeMustGenerate | NodeClobbersWorld) \
macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \
macro(CheckStructure, NodeMustGenerate) \
+ macro(ForwardCheckStructure, NodeMustGenerate) \
/* Transition watchpoints are a contract between the party setting the watchpoint */\
/* and the runtime system, where the party promises that the child object once had */\
/* the structure being watched, and the runtime system in turn promises that the */\
diff --git a/Source/JavaScriptCore/dfg/DFGOSREntry.cpp b/Source/JavaScriptCore/dfg/DFGOSREntry.cpp
index 9a7bc96cc..97061bfb2 100644
--- a/Source/JavaScriptCore/dfg/DFGOSREntry.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSREntry.cpp
@@ -99,7 +99,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
else
value = exec->argument(argument - 1);
- if (!entry->m_expectedValues.argument(argument).validate(value)) {
+ if (!entry->m_expectedValues.argument(argument).validateForEntry(value)) {
#if ENABLE(JIT_VERBOSE_OSR)
dataLog(" OSR failed because argument %zu is %s, expected ", argument, value.description());
entry->m_expectedValues.argument(argument).dump(WTF::dataFile());
@@ -119,7 +119,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
}
continue;
}
- if (!entry->m_expectedValues.local(local).validate(exec->registers()[local].jsValue())) {
+ if (!entry->m_expectedValues.local(local).validateForEntry(exec->registers()[local].jsValue())) {
#if ENABLE(JIT_VERBOSE_OSR)
dataLog(" OSR failed because variable %zu is %s, expected ", local, exec->registers()[local].jsValue().description());
entry->m_expectedValues.local(local).dump(WTF::dataFile());
diff --git a/Source/JavaScriptCore/dfg/DFGOSRExit.cpp b/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
index e9b02b2e3..b3701722e 100644
--- a/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
@@ -64,7 +64,7 @@ bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, Code
} else
exitSite = FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind);
- return baselineCodeBlockForOriginAndBaselineCodeBlock(m_codeOrigin, profiledCodeBlock)->addFrequentExitSite(exitSite);
+ return baselineCodeBlockForOriginAndBaselineCodeBlock(m_codeOriginForExitProfile, profiledCodeBlock)->addFrequentExitSite(exitSite);
}
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 94479d6d0..882e1cd02 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -423,12 +423,15 @@ EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecStat
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue baseValue = JSValue::decode(base);
PropertySlot slot(baseValue);
JSValue result = baseValue.get(exec, *propertyName, slot);
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
- dfgBuildGetByIDList(exec, baseValue, *propertyName, slot, stubInfo);
+ if (accessType == static_cast<AccessType>(stubInfo.accessType))
+ dfgBuildGetByIDList(exec, baseValue, *propertyName, slot, stubInfo);
return JSValue::encode(result);
}
@@ -439,12 +442,15 @@ EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(Exe
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue baseValue = JSValue::decode(base);
PropertySlot slot(baseValue);
JSValue result = baseValue.get(exec, *propertyName, slot);
-
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
- dfgBuildGetByIDProtoList(exec, baseValue, *propertyName, slot, stubInfo);
+
+ if (accessType == static_cast<AccessType>(stubInfo.accessType))
+ dfgBuildGetByIDProtoList(exec, baseValue, *propertyName, slot, stubInfo);
return JSValue::encode(result);
}
@@ -455,15 +461,19 @@ EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue baseValue = JSValue::decode(base);
PropertySlot slot(baseValue);
JSValue result = baseValue.get(exec, *propertyName, slot);
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
- if (stubInfo.seen)
- dfgRepatchGetByID(exec, baseValue, *propertyName, slot, stubInfo);
- else
- stubInfo.seen = true;
+ if (accessType == static_cast<AccessType>(stubInfo.accessType)) {
+ if (stubInfo.seen)
+ dfgRepatchGetByID(exec, baseValue, *propertyName, slot, stubInfo);
+ else
+ stubInfo.seen = true;
+ }
return JSValue::encode(result);
}
@@ -645,13 +655,18 @@ void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* ex
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue value = JSValue::decode(encodedValue);
JSValue baseValue(base);
PutPropertySlot slot(true);
baseValue.put(exec, *propertyName, value, slot);
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (accessType != static_cast<AccessType>(stubInfo.accessType))
+ return;
+
if (stubInfo.seen)
dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
else
@@ -664,13 +679,18 @@ void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState*
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue value = JSValue::decode(encodedValue);
JSValue baseValue(base);
PutPropertySlot slot(false);
baseValue.put(exec, *propertyName, value, slot);
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (accessType != static_cast<AccessType>(stubInfo.accessType))
+ return;
+
if (stubInfo.seen)
dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
else
@@ -683,13 +703,18 @@ void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecSta
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue value = JSValue::decode(encodedValue);
PutPropertySlot slot(true);
ASSERT(base->isObject());
asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (accessType != static_cast<AccessType>(stubInfo.accessType))
+ return;
+
if (stubInfo.seen)
dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
else
@@ -702,13 +727,18 @@ void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(Exec
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue value = JSValue::decode(encodedValue);
PutPropertySlot slot(false);
ASSERT(base->isObject());
asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (accessType != static_cast<AccessType>(stubInfo.accessType))
+ return;
+
if (stubInfo.seen)
dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
else
@@ -721,13 +751,18 @@ void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* e
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue value = JSValue::decode(encodedValue);
JSValue baseValue(base);
PutPropertySlot slot(true);
baseValue.put(exec, *propertyName, value, slot);
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (accessType != static_cast<AccessType>(stubInfo.accessType))
+ return;
+
dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
}
@@ -737,13 +772,18 @@ void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue value = JSValue::decode(encodedValue);
JSValue baseValue(base);
PutPropertySlot slot(false);
baseValue.put(exec, *propertyName, value, slot);
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (accessType != static_cast<AccessType>(stubInfo.accessType))
+ return;
+
dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
}
@@ -753,13 +793,18 @@ void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecSt
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue value = JSValue::decode(encodedValue);
PutPropertySlot slot(true);
ASSERT(base->isObject());
asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (accessType != static_cast<AccessType>(stubInfo.accessType))
+ return;
+
dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
}
@@ -769,13 +814,18 @@ void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(Exe
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
+ StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue value = JSValue::decode(encodedValue);
PutPropertySlot slot(false);
ASSERT(base->isObject());
asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
- StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
+ if (accessType != static_cast<AccessType>(stubInfo.accessType))
+ return;
+
dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
}
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index 2e4f8094c..94f69abc2 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -637,6 +637,7 @@ private:
}
case PutByVal:
+ case PutByValSafe:
changed |= m_graph[m_graph.varArgChild(node, 0)].mergeFlags(NodeUsedAsValue);
changed |= m_graph[m_graph.varArgChild(node, 1)].mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);
changed |= m_graph[m_graph.varArgChild(node, 2)].mergeFlags(NodeUsedAsValue);
@@ -672,6 +673,7 @@ private:
case ForceOSRExit:
case SetArgument:
case CheckStructure:
+ case ForwardCheckStructure:
case StructureTransitionWatchpoint:
case CheckFunction:
case PutStructure:
@@ -746,42 +748,6 @@ private:
propagate(m_graph[m_compileIndex]);
}
- void vote(Edge nodeUse, VariableAccessData::Ballot ballot)
- {
- switch (m_graph[nodeUse].op()) {
- case ValueToInt32:
- case UInt32ToNumber:
- nodeUse = m_graph[nodeUse].child1();
- break;
- default:
- break;
- }
-
- if (m_graph[nodeUse].op() == GetLocal)
- m_graph[nodeUse].variableAccessData()->vote(ballot);
- }
-
- void vote(Node& node, VariableAccessData::Ballot ballot)
- {
- if (node.flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node.firstChild();
- childIdx < node.firstChild() + node.numChildren();
- childIdx++)
- vote(m_graph.m_varArgChildren[childIdx], ballot);
- return;
- }
-
- if (!node.child1())
- return;
- vote(node.child1(), ballot);
- if (!node.child2())
- return;
- vote(node.child2(), ballot);
- if (!node.child3())
- return;
- vote(node.child3(), ballot);
- }
-
void doRoundOfDoubleVoting()
{
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
@@ -798,16 +764,16 @@ private:
SpeculatedType left = m_graph[node.child1()].prediction();
SpeculatedType right = m_graph[node.child2()].prediction();
- VariableAccessData::Ballot ballot;
+ DoubleBallot ballot;
if (isNumberSpeculation(left) && isNumberSpeculation(right)
&& !m_graph.addShouldSpeculateInteger(node))
- ballot = VariableAccessData::VoteDouble;
+ ballot = VoteDouble;
else
- ballot = VariableAccessData::VoteValue;
+ ballot = VoteValue;
- vote(node.child1(), ballot);
- vote(node.child2(), ballot);
+ m_graph.vote(node.child1(), ballot);
+ m_graph.vote(node.child2(), ballot);
break;
}
@@ -815,16 +781,16 @@ private:
SpeculatedType left = m_graph[node.child1()].prediction();
SpeculatedType right = m_graph[node.child2()].prediction();
- VariableAccessData::Ballot ballot;
+ DoubleBallot ballot;
if (isNumberSpeculation(left) && isNumberSpeculation(right)
&& !m_graph.mulShouldSpeculateInteger(node))
- ballot = VariableAccessData::VoteDouble;
+ ballot = VoteDouble;
else
- ballot = VariableAccessData::VoteValue;
+ ballot = VoteValue;
- vote(node.child1(), ballot);
- vote(node.child2(), ballot);
+ m_graph.vote(node.child1(), ballot);
+ m_graph.vote(node.child2(), ballot);
break;
}
@@ -835,46 +801,46 @@ private:
SpeculatedType left = m_graph[node.child1()].prediction();
SpeculatedType right = m_graph[node.child2()].prediction();
- VariableAccessData::Ballot ballot;
+ DoubleBallot ballot;
if (isNumberSpeculation(left) && isNumberSpeculation(right)
&& !(Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child1()])
&& node.canSpeculateInteger()))
- ballot = VariableAccessData::VoteDouble;
+ ballot = VoteDouble;
else
- ballot = VariableAccessData::VoteValue;
+ ballot = VoteValue;
- vote(node.child1(), ballot);
- vote(node.child2(), ballot);
+ m_graph.vote(node.child1(), ballot);
+ m_graph.vote(node.child2(), ballot);
break;
}
case ArithAbs:
- VariableAccessData::Ballot ballot;
+ DoubleBallot ballot;
if (!(m_graph[node.child1()].shouldSpeculateInteger()
&& node.canSpeculateInteger()))
- ballot = VariableAccessData::VoteDouble;
+ ballot = VoteDouble;
else
- ballot = VariableAccessData::VoteValue;
+ ballot = VoteValue;
- vote(node.child1(), ballot);
+ m_graph.vote(node.child1(), ballot);
break;
case ArithSqrt:
- vote(node.child1(), VariableAccessData::VoteDouble);
+ m_graph.vote(node.child1(), VoteDouble);
break;
case SetLocal: {
SpeculatedType prediction = m_graph[node.child1()].prediction();
if (isDoubleSpeculation(prediction))
- node.variableAccessData()->vote(VariableAccessData::VoteDouble);
+ node.variableAccessData()->vote(VoteDouble);
else if (!isNumberSpeculation(prediction) || isInt32Speculation(prediction))
- node.variableAccessData()->vote(VariableAccessData::VoteValue);
+ node.variableAccessData()->vote(VoteValue);
break;
}
default:
- vote(node, VariableAccessData::VoteValue);
+ m_graph.vote(node, VoteValue);
break;
}
}
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 179ad45fa..f17e2d7e4 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -56,6 +56,163 @@ SpeculativeJIT::~SpeculativeJIT()
WTF::deleteAllValues(m_slowPathGenerators);
}
+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail)
+{
+ if (!m_compileOkay)
+ return;
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(nodeIndex), jumpToFail, this, m_stream->size()));
+}
+
+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail)
+{
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ speculationCheck(kind, jsValueSource, nodeUse.index(), jumpToFail);
+}
+
+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::JumpList& jumpsToFail)
+{
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ Vector<MacroAssembler::Jump, 16> jumpVector = jumpsToFail.jumps();
+ for (unsigned i = 0; i < jumpVector.size(); ++i)
+ speculationCheck(kind, jsValueSource, nodeIndex, jumpVector[i]);
+}
+
+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::JumpList& jumpsToFail)
+{
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ speculationCheck(kind, jsValueSource, nodeUse.index(), jumpsToFail);
+}
+
+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
+{
+ if (!m_compileOkay)
+ return;
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ m_jit.codeBlock()->appendSpeculationRecovery(recovery);
+ m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(nodeIndex), jumpToFail, this, m_stream->size(), m_jit.codeBlock()->numberOfSpeculationRecoveries()));
+}
+
+void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
+{
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ speculationCheck(kind, jsValueSource, nodeUse.index(), jumpToFail, recovery);
+}
+
+JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex)
+{
+ if (!m_compileOkay)
+ return 0;
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ OSRExit& exit = m_jit.codeBlock()->osrExit(
+ m_jit.codeBlock()->appendOSRExit(
+ OSRExit(kind, jsValueSource,
+ m_jit.graph().methodOfGettingAValueProfileFor(nodeIndex),
+ JITCompiler::Jump(), this, m_stream->size())));
+ exit.m_watchpointIndex = m_jit.codeBlock()->appendWatchpoint(
+ JumpReplacementWatchpoint(m_jit.watchpointLabel()));
+ return &m_jit.codeBlock()->watchpoint(exit.m_watchpointIndex);
+}
+
+JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind)
+{
+ return speculationWatchpoint(kind, JSValueSource(), NoNode);
+}
+
+void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
+{
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ speculationCheck(kind, jsValueSource, nodeIndex, jumpToFail);
+
+#if !ASSERT_DISABLED
+ if (!valueRecovery) {
+ // Check that the preceding node was a SetLocal with the same code origin.
+ Node* setLocal = &at(m_jit.graph().m_blocks[m_block]->at(m_indexInBlock - 1));
+ ASSERT(setLocal->op() == SetLocal);
+ ASSERT(setLocal->codeOrigin == at(m_compileIndex).codeOrigin);
+ }
+#endif
+
+ unsigned setLocalIndexInBlock = m_indexInBlock + 1;
+
+ Node* setLocal = &at(m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock));
+ bool hadInt32ToDouble = false;
+
+ if (setLocal->op() == Int32ToDouble) {
+ setLocal = &at(m_jit.graph().m_blocks[m_block]->at(++setLocalIndexInBlock));
+ hadInt32ToDouble = true;
+ }
+ if (setLocal->op() == Flush || setLocal->op() == Phantom)
+ setLocal = &at(m_jit.graph().m_blocks[m_block]->at(++setLocalIndexInBlock));
+
+ if (!!valueRecovery) {
+ if (hadInt32ToDouble)
+ ASSERT(at(setLocal->child1()).child1() == m_compileIndex);
+ else
+ ASSERT(setLocal->child1() == m_compileIndex);
+ }
+ ASSERT(setLocal->op() == SetLocal);
+ ASSERT(setLocal->codeOrigin == at(m_compileIndex).codeOrigin);
+
+ Node* nextNode = &at(m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock + 1));
+ ASSERT(nextNode->codeOrigin != at(m_compileIndex).codeOrigin);
+
+ OSRExit& exit = m_jit.codeBlock()->lastOSRExit();
+ exit.m_codeOrigin = nextNode->codeOrigin;
+
+ if (!valueRecovery)
+ return;
+ exit.m_lastSetOperand = setLocal->local();
+ exit.m_valueRecoveryOverride = adoptRef(
+ new ValueRecoveryOverride(setLocal->local(), valueRecovery));
+}
+
+void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& valueRecovery)
+{
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ Vector<MacroAssembler::Jump, 16> jumpVector = jumpsToFail.jumps();
+ for (unsigned i = 0; i < jumpVector.size(); ++i)
+ forwardSpeculationCheck(kind, jsValueSource, nodeIndex, jumpVector[i], valueRecovery);
+}
+
+void SpeculativeJIT::speculationCheckWithConditionalDirection(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, bool isForward)
+{
+ if (isForward)
+ forwardSpeculationCheck(kind, jsValueSource, nodeIndex, jumpToFail);
+ else
+ speculationCheck(kind, jsValueSource, nodeIndex, jumpToFail);
+}
+
+void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, NodeIndex nodeIndex)
+{
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+#if DFG_ENABLE(DEBUG_VERBOSE)
+ dataLog("SpeculativeJIT was terminated.\n");
+#endif
+ if (!m_compileOkay)
+ return;
+ speculationCheck(kind, jsValueRegs, nodeIndex, m_jit.jump());
+ m_compileOkay = false;
+}
+
+void SpeculativeJIT::terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, Edge nodeUse)
+{
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+ terminateSpeculativeExecution(kind, jsValueRegs, nodeUse.index());
+}
+
+void SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection(ExitKind kind, JSValueRegs jsValueRegs, NodeIndex nodeIndex, bool isForward)
+{
+ ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
+#if DFG_ENABLE(DEBUG_VERBOSE)
+ dataLog("SpeculativeJIT was terminated.\n");
+#endif
+ if (!m_compileOkay)
+ return;
+ speculationCheckWithConditionalDirection(kind, jsValueRegs, nodeIndex, m_jit.jump(), isForward);
+ m_compileOkay = false;
+}
+
void SpeculativeJIT::addSlowPathGenerator(PassOwnPtr<SlowPathGenerator> slowPathGenerator)
{
m_slowPathGenerators.append(slowPathGenerator.leakPtr());
@@ -2902,7 +3059,7 @@ void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
ASSERT_NOT_REACHED();
} else if (at(node.child1()).prediction() == SpecString) {
if (!isStringSpeculation(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info)));
+ speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), storageReg);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
index f43323afd..96f2fec0a 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
@@ -306,7 +306,7 @@ public:
GPRReg fillSpeculateInt(NodeIndex, DataFormat& returnFormat);
GPRReg fillSpeculateIntStrict(NodeIndex);
FPRReg fillSpeculateDouble(NodeIndex);
- GPRReg fillSpeculateCell(NodeIndex);
+ GPRReg fillSpeculateCell(NodeIndex, bool isForwardSpeculation = false);
GPRReg fillSpeculateBoolean(NodeIndex);
GeneratedOperandType checkGeneratedTypeForToInt32(NodeIndex);
@@ -2163,130 +2163,33 @@ public:
#endif
// Add a speculation check without additional recovery.
- void speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail)
- {
- if (!m_compileOkay)
- return;
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(nodeIndex), jumpToFail, this, m_stream->size()));
- }
- void speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail)
- {
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- speculationCheck(kind, jsValueSource, nodeUse.index(), jumpToFail);
- }
+ void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail);
+ void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail);
// Add a set of speculation checks without additional recovery.
- void speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::JumpList& jumpsToFail)
- {
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- Vector<MacroAssembler::Jump, 16> jumpVector = jumpsToFail.jumps();
- for (unsigned i = 0; i < jumpVector.size(); ++i)
- speculationCheck(kind, jsValueSource, nodeIndex, jumpVector[i]);
- }
- void speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::JumpList& jumpsToFail)
- {
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- speculationCheck(kind, jsValueSource, nodeUse.index(), jumpsToFail);
- }
+ void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::JumpList& jumpsToFail);
+ void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::JumpList& jumpsToFail);
// Add a speculation check with additional recovery.
- void speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
- {
- if (!m_compileOkay)
- return;
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- m_jit.codeBlock()->appendSpeculationRecovery(recovery);
- m_jit.codeBlock()->appendOSRExit(OSRExit(kind, jsValueSource, m_jit.graph().methodOfGettingAValueProfileFor(nodeIndex), jumpToFail, this, m_stream->size(), m_jit.codeBlock()->numberOfSpeculationRecoveries()));
- }
- void speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::Jump jumpToFail, const SpeculationRecovery& recovery)
- {
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- speculationCheck(kind, jsValueSource, nodeUse.index(), jumpToFail, recovery);
- }
+ void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
+ void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
// Use this like you would use speculationCheck(), except that you don't pass it a jump
// (because you don't have to execute a branch; that's kind of the whole point), and you
// must register the returned Watchpoint with something relevant. In general, this should
// be used with extreme care. Use speculationCheck() unless you've got an amazing reason
// not to.
- JumpReplacementWatchpoint* speculationWatchpoint(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex)
- {
- if (!m_compileOkay)
- return 0;
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- OSRExit& exit = m_jit.codeBlock()->osrExit(
- m_jit.codeBlock()->appendOSRExit(
- OSRExit(kind, jsValueSource,
- m_jit.graph().methodOfGettingAValueProfileFor(nodeIndex),
- JITCompiler::Jump(), this, m_stream->size())));
- exit.m_watchpointIndex = m_jit.codeBlock()->appendWatchpoint(
- JumpReplacementWatchpoint(m_jit.watchpointLabel()));
- return &m_jit.codeBlock()->watchpoint(exit.m_watchpointIndex);
- }
+ JumpReplacementWatchpoint* speculationWatchpoint(ExitKind, JSValueSource, NodeIndex);
// The default for speculation watchpoints is that they're uncounted, because the
// act of firing a watchpoint invalidates it. So, future recompilations will not
// attempt to set this watchpoint again.
- JumpReplacementWatchpoint* speculationWatchpoint()
- {
- return speculationWatchpoint(UncountableWatchpoint, JSValueSource(), NoNode);
- }
- void forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& valueRecovery)
- {
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- speculationCheck(kind, jsValueSource, nodeIndex, jumpToFail);
-
- unsigned setLocalIndexInBlock = m_indexInBlock + 1;
-
- Node* setLocal = &at(m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock));
- bool hadInt32ToDouble = false;
-
- if (setLocal->op() == Int32ToDouble) {
- setLocal = &at(m_jit.graph().m_blocks[m_block]->at(++setLocalIndexInBlock));
- hadInt32ToDouble = true;
- }
- if (setLocal->op() == Flush || setLocal->op() == Phantom)
- setLocal = &at(m_jit.graph().m_blocks[m_block]->at(++setLocalIndexInBlock));
-
- if (hadInt32ToDouble)
- ASSERT(at(setLocal->child1()).child1() == m_compileIndex);
- else
- ASSERT(setLocal->child1() == m_compileIndex);
- ASSERT(setLocal->op() == SetLocal);
- ASSERT(setLocal->codeOrigin == at(m_compileIndex).codeOrigin);
-
- Node* nextNode = &at(m_jit.graph().m_blocks[m_block]->at(setLocalIndexInBlock + 1));
- ASSERT(nextNode->codeOrigin != at(m_compileIndex).codeOrigin);
-
- OSRExit& exit = m_jit.codeBlock()->lastOSRExit();
- exit.m_codeOrigin = nextNode->codeOrigin;
- exit.m_lastSetOperand = setLocal->local();
-
- exit.m_valueRecoveryOverride = adoptRef(
- new ValueRecoveryOverride(setLocal->local(), valueRecovery));
- }
- void forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& valueRecovery)
- {
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- Vector<MacroAssembler::Jump, 16> jumpVector = jumpsToFail.jumps();
- for (unsigned i = 0; i < jumpVector.size(); ++i)
- forwardSpeculationCheck(kind, jsValueSource, nodeIndex, jumpVector[i], valueRecovery);
- }
-
+ JumpReplacementWatchpoint* speculationWatchpoint(ExitKind = UncountableWatchpoint);
+ // Note: not specifying the valueRecovery argument (leaving it as ValueRecovery()) implies
+ // that you've ensured that there exists a MovHint prior to your use of forwardSpeculationCheck().
+ void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& = ValueRecovery());
+ void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& = ValueRecovery());
+ void speculationCheckWithConditionalDirection(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, bool isForward);
// Called when we statically determine that a speculation will fail.
- void terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, NodeIndex nodeIndex)
- {
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLog("SpeculativeJIT was terminated.\n");
-#endif
- if (!m_compileOkay)
- return;
- speculationCheck(kind, jsValueRegs, nodeIndex, m_jit.jump());
- m_compileOkay = false;
- }
- void terminateSpeculativeExecution(ExitKind kind, JSValueRegs jsValueRegs, Edge nodeUse)
- {
- ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes);
- terminateSpeculativeExecution(kind, jsValueRegs, nodeUse.index());
- }
+ void terminateSpeculativeExecution(ExitKind, JSValueRegs, NodeIndex);
+ void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);
+ void terminateSpeculativeExecutionWithConditionalDirection(ExitKind, JSValueRegs, NodeIndex, bool isForward);
template<bool strict>
GPRReg fillSpeculateIntInternal(NodeIndex, DataFormat& returnFormat);
@@ -2912,10 +2815,11 @@ private:
class SpeculateCellOperand {
public:
- explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge use)
+ explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge use, bool isForwardSpeculation = false)
: m_jit(jit)
, m_index(use.index())
, m_gprOrInvalid(InvalidGPRReg)
+ , m_isForwardSpeculation(isForwardSpeculation)
{
ASSERT(m_jit);
ASSERT(use.useKind() != DoubleUse);
@@ -2937,7 +2841,7 @@ public:
GPRReg gpr()
{
if (m_gprOrInvalid == InvalidGPRReg)
- m_gprOrInvalid = m_jit->fillSpeculateCell(index());
+ m_gprOrInvalid = m_jit->fillSpeculateCell(index(), m_isForwardSpeculation);
return m_gprOrInvalid;
}
@@ -2950,6 +2854,7 @@ private:
SpeculativeJIT* m_jit;
NodeIndex m_index;
GPRReg m_gprOrInvalid;
+ bool m_isForwardSpeculation;
};
class SpeculateBooleanOperand {
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index 6209da485..bf3503d6d 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -1284,13 +1284,13 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex)
}
}
-GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
+GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, bool isForwardSpeculation)
{
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLog("SpecCell@%d ", nodeIndex);
#endif
if (isKnownNotCell(nodeIndex)) {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
+ terminateSpeculativeExecutionWithConditionalDirection(Uncountable, JSValueRegs(), NoNode, isForwardSpeculation);
return allocate();
}
@@ -1314,7 +1314,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
ASSERT((info.spillFormat() & DataFormatJS) || info.spillFormat() == DataFormatCell);
if (!isCellSpeculation(type))
- speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::CellTag)));
+ speculationCheckWithConditionalDirection(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::CellTag)), isForwardSpeculation);
GPRReg gpr = allocate();
m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
@@ -1335,7 +1335,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
m_gprs.lock(tagGPR);
m_gprs.lock(payloadGPR);
if (!isCellSpeculation(type))
- speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag)));
+ speculationCheckWithConditionalDirection(BadType, JSValueRegs(tagGPR, payloadGPR), nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag)), isForwardSpeculation);
m_gprs.unlock(tagGPR);
m_gprs.release(tagGPR);
m_gprs.release(payloadGPR);
@@ -2483,7 +2483,8 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- case PutByVal: {
+ case PutByVal:
+ case PutByValSafe: {
Edge child1 = m_jit.graph().varArgChild(node, 0);
Edge child2 = m_jit.graph().varArgChild(node, 1);
Edge child3 = m_jit.graph().varArgChild(node, 2);
@@ -2599,12 +2600,14 @@ void SpeculativeJIT::compile(Node& node)
if (!isArraySpeculation(m_state.forNode(child1).m_type))
speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), child1, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
+ MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
+ if (node.op() == PutByVal)
+ speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
+
base.use();
property.use();
value.use();
- MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
-
// Get the array storage.
GPRReg storageReg = scratchReg;
m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
@@ -2626,12 +2629,14 @@ void SpeculativeJIT::compile(Node& node)
m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
- addSlowPathGenerator(
- slowPathCall(
- beyondArrayBounds, this,
- m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
- NoResult, baseReg, propertyReg, valueTagReg, valuePayloadReg));
-
+ if (node.op() == PutByValSafe) {
+ addSlowPathGenerator(
+ slowPathCall(
+ beyondArrayBounds, this,
+ m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
+ NoResult, baseReg, propertyReg, valueTagReg, valuePayloadReg));
+ }
+
noResult(m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -2990,7 +2995,7 @@ void SpeculativeJIT::compile(Node& node)
m_jit.move(op1PayloadGPR, resultPayloadGPR);
} else {
MacroAssembler::Jump alreadyPrimitive = m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag));
- MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1PayloadGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info));
+ MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1PayloadGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
alreadyPrimitive.link(&m_jit);
m_jit.move(op1TagGPR, resultTagGPR);
@@ -3174,7 +3179,7 @@ void SpeculativeJIT::compile(Node& node)
GPRReg thisValueGPR = thisValue.gpr();
if (!isObjectSpeculation(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueSource::unboxedCell(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR, JSCell::classInfoOffset()), JITCompiler::TrustedImmPtr(&JSString::s_info)));
+ speculationCheck(BadType, JSValueSource::unboxedCell(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
GPRTemporary result(this, thisValue);
GPRReg resultGPR = result.gpr();
@@ -3418,7 +3423,7 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resultGPR = result.gpr();
if (!isStringSpeculation(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info)));
+ speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
@@ -3470,7 +3475,8 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- case CheckStructure: {
+ case CheckStructure:
+ case ForwardCheckStructure: {
AbstractValue& value = m_state.forNode(node.child1());
if (value.m_structure.isSubsetOf(node.structureSet())
&& isCellSpeculation(value.m_type)) {
@@ -3478,13 +3484,19 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node.child1(), node.op() == ForwardCheckStructure);
ASSERT(node.structureSet().size());
- if (node.structureSet().size() == 1)
- speculationCheck(BadCache, JSValueRegs(), NoNode, m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), node.structureSet()[0]));
- else {
+ if (node.structureSet().size() == 1) {
+ speculationCheckWithConditionalDirection(
+ BadCache, JSValueRegs(), NoNode,
+ m_jit.branchWeakPtr(
+ JITCompiler::NotEqual,
+ JITCompiler::Address(base.gpr(), JSCell::structureOffset()),
+ node.structureSet()[0]),
+ node.op() == ForwardCheckStructure);
+ } else {
GPRTemporary structure(this);
m_jit.loadPtr(JITCompiler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr());
@@ -3494,7 +3506,11 @@ void SpeculativeJIT::compile(Node& node)
for (size_t i = 0; i < node.structureSet().size() - 1; ++i)
done.append(m_jit.branchWeakPtr(JITCompiler::Equal, structure.gpr(), node.structureSet()[i]));
- speculationCheck(BadCache, JSValueRegs(), NoNode, m_jit.branchWeakPtr(JITCompiler::NotEqual, structure.gpr(), node.structureSet().last()));
+ speculationCheckWithConditionalDirection(
+ BadCache, JSValueRegs(), NoNode,
+ m_jit.branchWeakPtr(
+ JITCompiler::NotEqual, structure.gpr(), node.structureSet().last()),
+ node.op() == ForwardCheckStructure);
done.link(&m_jit);
}
@@ -3505,7 +3521,7 @@ void SpeculativeJIT::compile(Node& node)
case StructureTransitionWatchpoint: {
m_jit.addWeakReference(node.structure());
- node.structure()->addTransitionWatchpoint(speculationWatchpoint());
+ node.structure()->addTransitionWatchpoint(speculationWatchpoint(BadCache));
#if !ASSERT_DISABLED
SpeculateCellOperand op1(this, node.child1());
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 39f4a0740..5541113f2 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -1326,7 +1326,7 @@ FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex)
}
}
-GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
+GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex, bool isForwardSpeculation)
{
#if DFG_ENABLE(DEBUG_VERBOSE)
dataLog("SpecCell@%d ", nodeIndex);
@@ -1339,7 +1339,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
switch (info.registerFormat()) {
case DataFormatNone: {
if (info.spillFormat() == DataFormatInteger || info.spillFormat() == DataFormatDouble) {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
+ terminateSpeculativeExecutionWithConditionalDirection(Uncountable, JSValueRegs(), NoNode, isForwardSpeculation);
return allocate();
}
@@ -1353,7 +1353,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
return gpr;
}
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
+ terminateSpeculativeExecutionWithConditionalDirection(Uncountable, JSValueRegs(), NoNode, isForwardSpeculation);
return gpr;
}
ASSERT(info.spillFormat() & DataFormatJS);
@@ -1362,7 +1362,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
info.fillJSValue(*m_stream, gpr, DataFormatJS);
if (!isCellSpeculation(type))
- speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));
+ speculationCheckWithConditionalDirection(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), isForwardSpeculation);
info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
return gpr;
}
@@ -1378,7 +1378,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
GPRReg gpr = info.gpr();
m_gprs.lock(gpr);
if (!isCellSpeculation(type))
- speculationCheck(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));
+ speculationCheckWithConditionalDirection(BadType, JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister), isForwardSpeculation);
info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
return gpr;
}
@@ -1389,7 +1389,7 @@ GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
case DataFormatDouble:
case DataFormatJSBoolean:
case DataFormatBoolean: {
- terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
+ terminateSpeculativeExecutionWithConditionalDirection(Uncountable, JSValueRegs(), NoNode, isForwardSpeculation);
return allocate();
}
@@ -1578,7 +1578,7 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(
// We know that within this branch, rightChild must not be a cell. Check if that is enough to
// prove that it is either null or undefined.
- if (!isOtherSpeculation(m_state.forNode(rightChild).m_type & ~SpecCell)) {
+ if (!isOtherOrEmptySpeculation(m_state.forNode(rightChild).m_type & ~SpecCell)) {
m_jit.move(op2GPR, resultGPR);
m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
@@ -1649,7 +1649,7 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(
// We know that within this branch, rightChild must not be a cell. Check if that is enough to
// prove that it is either null or undefined.
- if (isOtherSpeculation(m_state.forNode(rightChild).m_type & ~SpecCell))
+ if (isOtherOrEmptySpeculation(m_state.forNode(rightChild).m_type & ~SpecCell))
rightNotCell.link(&m_jit);
else {
jump(notTaken, ForceJump);
@@ -2508,7 +2508,8 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- case PutByVal: {
+ case PutByVal:
+ case PutByValSafe: {
Edge child1 = m_jit.graph().varArgChild(node, 0);
Edge child2 = m_jit.graph().varArgChild(node, 1);
Edge child3 = m_jit.graph().varArgChild(node, 2);
@@ -2675,13 +2676,15 @@ void SpeculativeJIT::compile(Node& node)
// If we have predicted the base to be type array, we can skip the check.
if (!isArraySpeculation(m_state.forNode(child1).m_type))
speculationCheck(BadType, JSValueRegs(baseReg), child1, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
+
+ MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
+ if (node.op() == PutByVal)
+ speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds);
base.use();
property.use();
value.use();
- MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
-
// Get the array storage.
GPRReg storageReg = scratchReg;
m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
@@ -2702,11 +2705,13 @@ void SpeculativeJIT::compile(Node& node)
// Store the value to the array.
m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
- addSlowPathGenerator(
- slowPathCall(
- beyondArrayBounds, this,
- m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
- NoResult, baseReg, propertyReg, valueReg));
+ if (node.op() == PutByValSafe) {
+ addSlowPathGenerator(
+ slowPathCall(
+ beyondArrayBounds, this,
+ m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
+ NoResult, baseReg, propertyReg, valueReg));
+ }
noResult(m_compileIndex, UseChildrenCalledExplicitly);
break;
@@ -3043,7 +3048,7 @@ void SpeculativeJIT::compile(Node& node)
m_jit.move(op1GPR, resultGPR);
else {
MacroAssembler::Jump alreadyPrimitive = m_jit.branchTestPtr(MacroAssembler::NonZero, op1GPR, GPRInfo::tagMaskRegister);
- MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info));
+ MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
alreadyPrimitive.link(&m_jit);
m_jit.move(op1GPR, resultGPR);
@@ -3208,7 +3213,7 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resultGPR = result.gpr();
if (!isObjectSpeculation(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueRegs(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR, JSCell::classInfoOffset()), JITCompiler::TrustedImmPtr(&JSString::s_info)));
+ speculationCheck(BadType, JSValueRegs(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
m_jit.move(thisValueGPR, resultGPR);
@@ -3435,7 +3440,7 @@ void SpeculativeJIT::compile(Node& node)
GPRReg resultGPR = result.gpr();
if (!isStringSpeculation(m_state.forNode(node.child1()).m_type))
- speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info)));
+ speculationCheck(BadType, JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
@@ -3485,7 +3490,8 @@ void SpeculativeJIT::compile(Node& node)
noResult(m_compileIndex);
break;
}
- case CheckStructure: {
+ case CheckStructure:
+ case ForwardCheckStructure: {
AbstractValue& value = m_state.forNode(node.child1());
if (value.m_structure.isSubsetOf(node.structureSet())
&& isCellSpeculation(value.m_type)) {
@@ -3493,13 +3499,19 @@ void SpeculativeJIT::compile(Node& node)
break;
}
- SpeculateCellOperand base(this, node.child1());
+ SpeculateCellOperand base(this, node.child1(), node.op() == ForwardCheckStructure);
ASSERT(node.structureSet().size());
- if (node.structureSet().size() == 1)
- speculationCheck(BadCache, JSValueRegs(), NoNode, m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), node.structureSet()[0]));
- else {
+ if (node.structureSet().size() == 1) {
+ speculationCheckWithConditionalDirection(
+ BadCache, JSValueRegs(), NoNode,
+ m_jit.branchWeakPtr(
+ JITCompiler::NotEqual,
+ JITCompiler::Address(base.gpr(), JSCell::structureOffset()),
+ node.structureSet()[0]),
+ node.op() == ForwardCheckStructure);
+ } else {
GPRTemporary structure(this);
m_jit.loadPtr(JITCompiler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr());
@@ -3509,7 +3521,11 @@ void SpeculativeJIT::compile(Node& node)
for (size_t i = 0; i < node.structureSet().size() - 1; ++i)
done.append(m_jit.branchWeakPtr(JITCompiler::Equal, structure.gpr(), node.structureSet()[i]));
- speculationCheck(BadCache, JSValueRegs(), NoNode, m_jit.branchWeakPtr(JITCompiler::NotEqual, structure.gpr(), node.structureSet().last()));
+ speculationCheckWithConditionalDirection(
+ BadCache, JSValueRegs(), NoNode,
+ m_jit.branchWeakPtr(
+ JITCompiler::NotEqual, structure.gpr(), node.structureSet().last()),
+ node.op() == ForwardCheckStructure);
done.link(&m_jit);
}
@@ -3520,7 +3536,7 @@ void SpeculativeJIT::compile(Node& node)
case StructureTransitionWatchpoint: {
m_jit.addWeakReference(node.structure());
- node.structure()->addTransitionWatchpoint(speculationWatchpoint());
+ node.structure()->addTransitionWatchpoint(speculationWatchpoint(BadCache));
#if !ASSERT_DISABLED
SpeculateCellOperand op1(this, node.child1());
diff --git a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
new file mode 100644
index 000000000..e86c57dff
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2012 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 "DFGStructureCheckHoistingPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlock.h"
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include <wtf/HashMap.h>
+
+namespace JSC { namespace DFG {
+
+enum CheckBallot { VoteOther, VoteStructureCheck };
+
+class StructureCheckHoistingPhase : public Phase {
+public:
+ StructureCheckHoistingPhase(Graph& graph)
+ : Phase(graph, "structure check hoisting")
+ {
+ }
+
+ bool run()
+ {
+ for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
+ VariableAccessData* variable = &m_graph.m_variableAccessData[i];
+ if (!variable->isRoot())
+ continue;
+ variable->clearVotes();
+ }
+
+ // Identify the set of variables that are always subject to the same structure
+ // checks. For now, only consider monomorphic structure checks (one structure).
+
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
+ NodeIndex nodeIndex = block->at(indexInBlock);
+ Node& node = m_graph[nodeIndex];
+ if (!node.shouldGenerate())
+ continue;
+ switch (node.op()) {
+ case CheckStructure: {
+ Node& child = m_graph[node.child1()];
+ if (child.op() != GetLocal)
+ break;
+ VariableAccessData* variable = child.variableAccessData();
+ variable->vote(VoteStructureCheck);
+ if (variable->isCaptured() || variable->structureCheckHoistingFailed())
+ break;
+ if (!isCellSpeculation(variable->prediction()))
+ break;
+ noticeStructureCheck(variable, node.structureSet());
+ break;
+ }
+
+ case ForwardCheckStructure:
+ // We currently rely on the fact that we're the only ones who would
+ // insert this node.
+ ASSERT_NOT_REACHED();
+ break;
+
+ case GetByOffset:
+ case PutByOffset:
+ case PutStructure:
+ case StructureTransitionWatchpoint:
+ case AllocatePropertyStorage:
+ case ReallocatePropertyStorage:
+ case GetPropertyStorage:
+ // Don't count these uses.
+ break;
+
+ default:
+ m_graph.vote(node, VoteOther);
+ break;
+ }
+ }
+ }
+
+ // Disable structure hoisting on variables that appear to mostly be used in
+ // contexts where it doesn't make sense.
+
+ for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
+ VariableAccessData* variable = &m_graph.m_variableAccessData[i];
+ if (!variable->isRoot())
+ continue;
+ if (variable->voteRatio() >= Options::structureCheckVoteRatioForHoisting())
+ continue;
+ HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
+ if (iter == m_map.end())
+ continue;
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ dataLog("Zeroing the structure to hoist for %s because the ratio is %lf.\n",
+ m_graph.nameOfVariableAccessData(variable), variable->voteRatio());
+#endif
+ iter->second.m_structure = 0;
+ }
+
+ // Identify the set of variables that are live across a structure clobber.
+
+ Operands<VariableAccessData*> live(
+ m_graph.m_blocks[0]->variablesAtTail.numberOfArguments(),
+ m_graph.m_blocks[0]->variablesAtTail.numberOfLocals());
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ ASSERT(live.numberOfArguments() == block->variablesAtTail.numberOfArguments());
+ ASSERT(live.numberOfLocals() == block->variablesAtTail.numberOfLocals());
+ for (unsigned i = live.size(); i--;) {
+ NodeIndex indexAtTail = block->variablesAtTail[i];
+ VariableAccessData* variable;
+ if (indexAtTail == NoNode)
+ variable = 0;
+ else
+ variable = m_graph[indexAtTail].variableAccessData();
+ live[i] = variable;
+ }
+ for (unsigned indexInBlock = block->size(); indexInBlock--;) {
+ NodeIndex nodeIndex = block->at(indexInBlock);
+ Node& node = m_graph[nodeIndex];
+ if (!node.shouldGenerate())
+ continue;
+ switch (node.op()) {
+ case GetLocal:
+ case Flush:
+ // This is a birth.
+ live.operand(node.local()) = node.variableAccessData();
+ break;
+
+ case SetLocal:
+ case SetArgument:
+ ASSERT(live.operand(node.local())); // Must be live.
+ ASSERT(live.operand(node.local()) == node.variableAccessData()); // Must have the variable we expected.
+ // This is a death.
+ live.operand(node.local()) = 0;
+ break;
+
+ // Use the CFA's notion of what clobbers the world.
+ case ValueAdd:
+ if (m_graph.addShouldSpeculateInteger(node))
+ break;
+ if (Node::shouldSpeculateNumber(m_graph[node.child1()], m_graph[node.child2()]))
+ break;
+ clobber(live);
+ break;
+
+ case CompareLess:
+ case CompareLessEq:
+ case CompareGreater:
+ case CompareGreaterEq:
+ case CompareEq: {
+ Node& left = m_graph[node.child1()];
+ Node& right = m_graph[node.child2()];
+ if (Node::shouldSpeculateInteger(left, right))
+ break;
+ if (Node::shouldSpeculateNumber(left, right))
+ break;
+ if (node.op() == CompareEq) {
+ if ((m_graph.isConstant(node.child1().index())
+ && m_graph.valueOfJSConstant(node.child1().index()).isNull())
+ || (m_graph.isConstant(node.child2().index())
+ && m_graph.valueOfJSConstant(node.child2().index()).isNull()))
+ break;
+
+ if (Node::shouldSpeculateFinalObject(left, right))
+ break;
+ if (Node::shouldSpeculateArray(left, right))
+ break;
+ if (left.shouldSpeculateFinalObject() && right.shouldSpeculateFinalObjectOrOther())
+ break;
+ if (right.shouldSpeculateFinalObject() && left.shouldSpeculateFinalObjectOrOther())
+ break;
+ if (left.shouldSpeculateArray() && right.shouldSpeculateArrayOrOther())
+ break;
+ if (right.shouldSpeculateArray() && left.shouldSpeculateArrayOrOther())
+ break;
+ }
+ clobber(live);
+ break;
+ }
+
+ case GetByVal:
+ if (!node.prediction() || !m_graph[node.child1()].prediction() || !m_graph[node.child2()].prediction())
+ break;
+ if (!isActionableArraySpeculation(m_graph[node.child1()].prediction()) || !m_graph[node.child2()].shouldSpeculateInteger())
+ clobber(live);
+ break;
+
+ case PutByVal:
+ case PutByValAlias: {
+ Edge child1 = m_graph.varArgChild(node, 0);
+ Edge child2 = m_graph.varArgChild(node, 1);
+
+ if (!m_graph[child1].prediction() || !m_graph[child2].prediction())
+ break;
+ if (!m_graph[child2].shouldSpeculateInteger() || !isActionableMutableArraySpeculation(m_graph[child1].prediction())) {
+ clobber(live);
+ break;
+ }
+ if (node.op() == PutByValAlias)
+ break;
+ if (m_graph[child1].shouldSpeculateArguments())
+ break;
+ if (m_graph[child1].shouldSpeculateInt8Array())
+ break;
+ if (m_graph[child1].shouldSpeculateInt16Array())
+ break;
+ if (m_graph[child1].shouldSpeculateInt32Array())
+ break;
+ if (m_graph[child1].shouldSpeculateUint8Array())
+ break;
+ if (m_graph[child1].shouldSpeculateUint8ClampedArray())
+ break;
+ if (m_graph[child1].shouldSpeculateUint16Array())
+ break;
+ if (m_graph[child1].shouldSpeculateUint32Array())
+ break;
+ if (m_graph[child1].shouldSpeculateFloat32Array())
+ break;
+ if (m_graph[child1].shouldSpeculateFloat64Array())
+ break;
+ clobber(live);
+ break;
+ }
+
+ case GetMyArgumentsLengthSafe:
+ case GetMyArgumentByValSafe:
+ case GetById:
+ case GetByIdFlush:
+ case PutStructure:
+ case PhantomPutStructure:
+ case PutById:
+ case PutByIdDirect:
+ case Call:
+ case Construct:
+ case Resolve:
+ case ResolveBase:
+ case ResolveBaseStrictPut:
+ case ResolveGlobal:
+ clobber(live);
+ break;
+
+ default:
+ ASSERT(node.op() != Phi);
+ break;
+ }
+ }
+ }
+
+ bool changed = false;
+
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ for (HashMap<VariableAccessData*, CheckData>::iterator it = m_map.begin();
+ it != m_map.end(); ++it) {
+ if (!it->second.m_structure) {
+ dataLog("Not hoisting checks for %s because of heuristics.\n", m_graph.nameOfVariableAccessData(it->first));
+ continue;
+ }
+ if (it->second.m_isClobbered && !it->second.m_structure->transitionWatchpointSetIsStillValid()) {
+ dataLog("Not hoisting checks for %s because the structure is clobbered and has an invalid watchpoint set.\n", m_graph.nameOfVariableAccessData(it->first));
+ continue;
+ }
+ dataLog("Hoisting checks for %s\n", m_graph.nameOfVariableAccessData(it->first));
+ }
+#endif // DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+
+ // Make changes:
+ // 1) If a variable's live range does not span a clobber, then inject structure
+ // checks before the SetLocal.
+ // 2) If a variable's live range spans a clobber but is watchpointable, then
+ // inject structure checks before the SetLocal and replace all other structure
+ // checks on that variable with structure transition watchpoints.
+
+ InsertionSet<NodeIndex> insertionSet;
+ for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
+ BasicBlock* block = m_graph.m_blocks[blockIndex].get();
+ if (!block)
+ continue;
+ for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
+ NodeIndex nodeIndex = block->at(indexInBlock);
+ Node& node = m_graph[nodeIndex];
+ // Be careful not to use 'node' after appending to the graph. In those switch
+ // cases where we need to append, we first carefully extract everything we need
+ // from the node, before doing any appending.
+ if (!node.shouldGenerate())
+ continue;
+ switch (node.op()) {
+ case SetArgument: {
+ ASSERT(!blockIndex);
+ // Insert a GetLocal and a CheckStructure immediately following this
+ // SetArgument, if the variable was a candidate for structure hoisting.
+ // If the basic block previously only had the SetArgument as its
+ // variable-at-tail, then replace it with this GetLocal.
+ VariableAccessData* variable = node.variableAccessData();
+ HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
+ if (iter == m_map.end())
+ break;
+ if (!iter->second.m_structure)
+ break;
+ if (iter->second.m_isClobbered && !iter->second.m_structure->transitionWatchpointSetIsStillValid())
+ break;
+
+ node.ref();
+
+ CodeOrigin codeOrigin = node.codeOrigin;
+
+ Node getLocal(GetLocal, codeOrigin, OpInfo(variable), nodeIndex);
+ getLocal.predict(variable->prediction());
+ getLocal.ref();
+ NodeIndex getLocalIndex = m_graph.size();
+ m_graph.append(getLocal);
+ insertionSet.append(indexInBlock + 1, getLocalIndex);
+
+ Node checkStructure(CheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(iter->second.m_structure)), getLocalIndex);
+ checkStructure.ref();
+ NodeIndex checkStructureIndex = m_graph.size();
+ m_graph.append(checkStructure);
+ insertionSet.append(indexInBlock + 1, checkStructureIndex);
+
+ if (block->variablesAtTail.operand(variable->local()) == nodeIndex)
+ block->variablesAtTail.operand(variable->local()) = getLocalIndex;
+
+ changed = true;
+ break;
+ }
+
+ case SetLocal: {
+ VariableAccessData* variable = node.variableAccessData();
+ HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
+ if (iter == m_map.end())
+ break;
+ if (!iter->second.m_structure)
+ break;
+ if (iter->second.m_isClobbered && !iter->second.m_structure->transitionWatchpointSetIsStillValid())
+ break;
+
+ // First insert a dead SetLocal to tell OSR that the child's value should
+ // be dropped into this bytecode variable if the CheckStructure decides
+ // to exit.
+
+ CodeOrigin codeOrigin = node.codeOrigin;
+ NodeIndex child1 = node.child1().index();
+
+ Node setLocal(SetLocal, codeOrigin, OpInfo(variable), child1);
+ NodeIndex setLocalIndex = m_graph.size();
+ m_graph.append(setLocal);
+ insertionSet.append(indexInBlock, setLocalIndex);
+ m_graph[child1].ref();
+ // Use a ForwardCheckStructure to indicate that we should exit to the
+ // next bytecode instruction rather than reexecuting the current one.
+ Node checkStructure(ForwardCheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(iter->second.m_structure)), child1);
+ checkStructure.ref();
+ NodeIndex checkStructureIndex = m_graph.size();
+ m_graph.append(checkStructure);
+ insertionSet.append(indexInBlock, checkStructureIndex);
+ changed = true;
+ break;
+ }
+
+ case CheckStructure: {
+ Node& child = m_graph[node.child1()];
+ if (child.op() != GetLocal)
+ break;
+ HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(child.variableAccessData());
+ if (iter == m_map.end())
+ break;
+ if (!iter->second.m_structure)
+ break;
+ if (!iter->second.m_isClobbered) {
+ node.setOpAndDefaultFlags(Phantom);
+ ASSERT(node.refCount() == 1);
+ break;
+ }
+ if (!iter->second.m_structure->transitionWatchpointSetIsStillValid())
+ break;
+ ASSERT(iter->second.m_structure == node.structureSet().singletonStructure());
+ node.convertToStructureTransitionWatchpoint();
+ changed = true;
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ insertionSet.execute(*block);
+ }
+
+ return changed;
+ }
+
+private:
+ void noticeStructureCheck(VariableAccessData* variable, Structure* structure)
+ {
+ HashMap<VariableAccessData*, CheckData>::AddResult result =
+ m_map.add(variable, CheckData(structure, false));
+ if (result.isNewEntry)
+ return;
+ if (result.iterator->second.m_structure == structure)
+ return;
+ result.iterator->second.m_structure = 0;
+ }
+
+ void noticeStructureCheck(VariableAccessData* variable, const StructureSet& set)
+ {
+ if (set.size() != 1) {
+ noticeStructureCheck(variable, 0);
+ return;
+ }
+ noticeStructureCheck(variable, set.singletonStructure());
+ }
+
+ void noticeClobber(VariableAccessData* variable)
+ {
+ HashMap<VariableAccessData*, CheckData>::iterator iter =
+ m_map.find(variable);
+ if (iter == m_map.end())
+ return;
+ iter->second.m_isClobbered = true;
+ }
+
+ void clobber(const Operands<VariableAccessData*>& live)
+ {
+ for (size_t i = live.size(); i--;) {
+ VariableAccessData* variable = live[i];
+ if (!variable)
+ continue;
+ noticeClobber(variable);
+ }
+ }
+
+ struct CheckData {
+ Structure* m_structure;
+ bool m_isClobbered;
+
+ CheckData()
+ : m_structure(0)
+ , m_isClobbered(false)
+ {
+ }
+
+ CheckData(Structure* structure, bool isClobbered)
+ : m_structure(structure)
+ , m_isClobbered(isClobbered)
+ {
+ }
+ };
+
+ HashMap<VariableAccessData*, CheckData> m_map;
+};
+
+bool performStructureCheckHoisting(Graph& graph)
+{
+ SamplingRegion samplingRegion("DFG Structure Check Hoisting Phase");
+ return runPhase<StructureCheckHoistingPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+
diff --git a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h
new file mode 100644
index 000000000..1e6462a92
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 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 DFGStructureCheckHoistingPhase_h
+#define DFGStructureCheckHoistingPhase_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Hoists CheckStructure on variables to assignments to those variables, if either of
+// the following is true:
+// A) The structure's transition watchpoint set is valid.
+// B) The span of code within which the variable is live has no effects that might
+// clobber the structure.
+
+bool performStructureCheckHoisting(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGStructureCheckHoistingPhase_h
+
diff --git a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
index e734e6387..6d8e89799 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
+++ b/Source/JavaScriptCore/dfg/DFGVariableAccessData.h
@@ -37,10 +37,10 @@
namespace JSC { namespace DFG {
+enum DoubleBallot { VoteValue, VoteDouble };
+
class VariableAccessData : public UnionFind<VariableAccessData> {
public:
- enum Ballot { VoteValue, VoteDouble };
-
VariableAccessData()
: m_local(static_cast<VirtualRegister>(std::numeric_limits<int>::min()))
, m_prediction(SpecNone)
@@ -49,6 +49,7 @@ public:
, m_doubleFormatState(EmptyDoubleFormatState)
, m_isCaptured(false)
, m_isArgumentsAlias(false)
+ , m_structureCheckHoistingFailed(false)
{
clearVotes();
}
@@ -61,6 +62,7 @@ public:
, m_doubleFormatState(EmptyDoubleFormatState)
, m_isCaptured(isCaptured)
, m_isArgumentsAlias(false)
+ , m_structureCheckHoistingFailed(false)
{
clearVotes();
}
@@ -90,6 +92,20 @@ public:
return m_isCaptured;
}
+ bool mergeStructureCheckHoistingFailed(bool failed)
+ {
+ bool newFailed = m_structureCheckHoistingFailed | failed;
+ if (newFailed == m_structureCheckHoistingFailed)
+ return false;
+ m_structureCheckHoistingFailed = newFailed;
+ return true;
+ }
+
+ bool structureCheckHoistingFailed()
+ {
+ return m_structureCheckHoistingFailed;
+ }
+
bool mergeIsArgumentsAlias(bool isArgumentsAlias)
{
bool newIsArgumentsAlias = m_isArgumentsAlias | isArgumentsAlias;
@@ -136,20 +152,20 @@ public:
void clearVotes()
{
ASSERT(find() == this);
- m_votes[VoteValue] = 0;
- m_votes[VoteDouble] = 0;
+ m_votes[0] = 0;
+ m_votes[1] = 0;
}
- void vote(Ballot ballot)
+ void vote(unsigned ballot)
{
- ASSERT(static_cast<unsigned>(ballot) < 2);
+ ASSERT(ballot < 2);
m_votes[ballot]++;
}
- double doubleVoteRatio()
+ double voteRatio()
{
ASSERT(find() == this);
- return static_cast<double>(m_votes[VoteDouble]) / m_votes[VoteValue];
+ return static_cast<double>(m_votes[1]) / m_votes[0];
}
bool shouldUseDoubleFormatAccordingToVote()
@@ -176,7 +192,7 @@ public:
// If the variable has been voted to become a double, then make it a
// double.
- if (doubleVoteRatio() >= Options::doubleVoteRatioForDoubleFormat())
+ if (voteRatio() >= Options::doubleVoteRatioForDoubleFormat())
return true;
return false;
@@ -250,11 +266,12 @@ private:
SpeculatedType m_argumentAwarePrediction;
NodeFlags m_flags;
- float m_votes[2];
+ float m_votes[2]; // Used primarily for double voting but may be reused for other purposes.
DoubleFormatState m_doubleFormatState;
bool m_isCaptured;
bool m_isArgumentsAlias;
+ bool m_structureCheckHoistingFailed;
};
} } // namespace JSC::DFG
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.cpp b/Source/JavaScriptCore/heap/BlockAllocator.cpp
index fc4f8a4c6..690fd83c4 100644
--- a/Source/JavaScriptCore/heap/BlockAllocator.cpp
+++ b/Source/JavaScriptCore/heap/BlockAllocator.cpp
@@ -55,7 +55,7 @@ BlockAllocator::~BlockAllocator()
void BlockAllocator::releaseFreeBlocks()
{
while (true) {
- HeapBlock* block;
+ DeadBlock* block;
{
SpinLockHolder locker(&m_freeBlockLock);
if (!m_numberOfFreeBlocks)
@@ -70,7 +70,7 @@ void BlockAllocator::releaseFreeBlocks()
if (!block)
break;
- block->m_allocation.deallocate();
+ DeadBlock::destroy(block).deallocate();
}
}
@@ -121,7 +121,7 @@ void BlockAllocator::blockFreeingThreadMain()
size_t desiredNumberOfFreeBlocks = currentNumberOfFreeBlocks / 2;
while (!m_blockFreeingThreadShouldQuit) {
- HeapBlock* block;
+ DeadBlock* block;
{
SpinLockHolder locker(&m_freeBlockLock);
if (m_numberOfFreeBlocks <= desiredNumberOfFreeBlocks)
@@ -136,7 +136,7 @@ void BlockAllocator::blockFreeingThreadMain()
if (!block)
break;
- block->m_allocation.deallocate();
+ DeadBlock::destroy(block).deallocate();
}
}
}
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.h b/Source/JavaScriptCore/heap/BlockAllocator.h
index 7a99d2edd..042e65d92 100644
--- a/Source/JavaScriptCore/heap/BlockAllocator.h
+++ b/Source/JavaScriptCore/heap/BlockAllocator.h
@@ -38,6 +38,24 @@ namespace JSC {
// Simple allocator to reduce VM cost by holding onto blocks of memory for
// short periods of time and then freeing them on a secondary thread.
+class DeadBlock : public HeapBlock<DeadBlock> {
+public:
+ static DeadBlock* create(const PageAllocationAligned&);
+
+private:
+ DeadBlock(const PageAllocationAligned&);
+};
+
+inline DeadBlock::DeadBlock(const PageAllocationAligned& allocation)
+ : HeapBlock<DeadBlock>(allocation)
+{
+}
+
+inline DeadBlock* DeadBlock::create(const PageAllocationAligned& allocation)
+{
+ return new(NotNull, allocation.base()) DeadBlock(allocation);
+}
+
class BlockAllocator {
public:
BlockAllocator();
@@ -55,7 +73,7 @@ private:
void releaseFreeBlocks();
- DoublyLinkedList<HeapBlock> m_freeBlocks;
+ DoublyLinkedList<DeadBlock> m_freeBlocks;
size_t m_numberOfFreeBlocks;
bool m_isCurrentlyAllocating;
bool m_blockFreeingThreadShouldQuit;
@@ -73,12 +91,12 @@ inline PageAllocationAligned BlockAllocator::allocate()
if (m_numberOfFreeBlocks) {
ASSERT(!m_freeBlocks.isEmpty());
m_numberOfFreeBlocks--;
- return m_freeBlocks.removeHead()->m_allocation;
+ return DeadBlock::destroy(m_freeBlocks.removeHead());
}
}
ASSERT(m_freeBlocks.isEmpty());
- PageAllocationAligned allocation = PageAllocationAligned::allocate(HeapBlock::s_blockSize, HeapBlock::s_blockSize, OSAllocator::JSGCHeapPages);
+ PageAllocationAligned allocation = PageAllocationAligned::allocate(DeadBlock::s_blockSize, DeadBlock::s_blockSize, OSAllocator::JSGCHeapPages);
if (!static_cast<bool>(allocation))
CRASH();
return allocation;
@@ -87,8 +105,7 @@ inline PageAllocationAligned BlockAllocator::allocate()
inline void BlockAllocator::deallocate(PageAllocationAligned allocation)
{
SpinLockHolder locker(&m_freeBlockLock);
- HeapBlock* heapBlock = new(NotNull, allocation.base()) HeapBlock(allocation);
- m_freeBlocks.push(heapBlock);
+ m_freeBlocks.push(DeadBlock::create(allocation));
m_numberOfFreeBlocks++;
}
diff --git a/Source/JavaScriptCore/heap/CopiedBlock.h b/Source/JavaScriptCore/heap/CopiedBlock.h
index 6717a6835..ad5dbb46b 100644
--- a/Source/JavaScriptCore/heap/CopiedBlock.h
+++ b/Source/JavaScriptCore/heap/CopiedBlock.h
@@ -34,13 +34,12 @@ namespace JSC {
class CopiedSpace;
-class CopiedBlock : public HeapBlock {
+class CopiedBlock : public HeapBlock<CopiedBlock> {
friend class CopiedSpace;
friend class CopiedAllocator;
public:
static CopiedBlock* create(const PageAllocationAligned&);
static CopiedBlock* createNoZeroFill(const PageAllocationAligned&);
- static PageAllocationAligned destroy(CopiedBlock*);
// The payload is the region of the block that is usable for allocations.
char* payload();
@@ -93,17 +92,8 @@ inline void CopiedBlock::zeroFillWilderness()
#endif
}
-inline PageAllocationAligned CopiedBlock::destroy(CopiedBlock* block)
-{
- PageAllocationAligned allocation;
- swap(allocation, block->m_allocation);
-
- block->~CopiedBlock();
- return allocation;
-}
-
inline CopiedBlock::CopiedBlock(const PageAllocationAligned& allocation)
- : HeapBlock(allocation)
+ : HeapBlock<CopiedBlock>(allocation)
, m_remaining(payloadCapacity())
, m_isPinned(false)
{
@@ -117,7 +107,7 @@ inline char* CopiedBlock::payload()
inline char* CopiedBlock::payloadEnd()
{
- return reinterpret_cast<char*>(this) + m_allocation.size();
+ return reinterpret_cast<char*>(this) + allocation().size();
}
inline size_t CopiedBlock::payloadCapacity()
@@ -162,7 +152,7 @@ inline size_t CopiedBlock::size()
inline size_t CopiedBlock::capacity()
{
- return m_allocation.size();
+ return allocation().size();
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp
index 147dfa4b3..bf87a305c 100644
--- a/Source/JavaScriptCore/heap/CopiedSpace.cpp
+++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp
@@ -44,13 +44,13 @@ CopiedSpace::CopiedSpace(Heap* heap)
CopiedSpace::~CopiedSpace()
{
while (!m_toSpace->isEmpty())
- m_heap->blockAllocator().deallocate(CopiedBlock::destroy(static_cast<CopiedBlock*>(m_toSpace->removeHead())));
+ m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_toSpace->removeHead()));
while (!m_fromSpace->isEmpty())
- m_heap->blockAllocator().deallocate(CopiedBlock::destroy(static_cast<CopiedBlock*>(m_fromSpace->removeHead())));
+ m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_fromSpace->removeHead()));
while (!m_oversizeBlocks.isEmpty())
- CopiedBlock::destroy(static_cast<CopiedBlock*>(m_oversizeBlocks.removeHead())).deallocate();
+ CopiedBlock::destroy(m_oversizeBlocks.removeHead()).deallocate();
}
void CopiedSpace::init()
@@ -193,7 +193,7 @@ void CopiedSpace::doneCopying()
ASSERT(m_inCopyingPhase);
m_inCopyingPhase = false;
while (!m_fromSpace->isEmpty()) {
- CopiedBlock* block = static_cast<CopiedBlock*>(m_fromSpace->removeHead());
+ CopiedBlock* block = m_fromSpace->removeHead();
if (block->m_isPinned) {
block->m_isPinned = false;
// We don't add the block to the blockSet because it was never removed.
@@ -207,9 +207,9 @@ void CopiedSpace::doneCopying()
m_heap->blockAllocator().deallocate(CopiedBlock::destroy(block));
}
- CopiedBlock* curr = static_cast<CopiedBlock*>(m_oversizeBlocks.head());
+ CopiedBlock* curr = m_oversizeBlocks.head();
while (curr) {
- CopiedBlock* next = static_cast<CopiedBlock*>(curr->next());
+ CopiedBlock* next = curr->next();
if (!curr->m_isPinned) {
m_oversizeBlocks.remove(curr);
m_blockSet.remove(curr);
@@ -224,20 +224,20 @@ void CopiedSpace::doneCopying()
if (!m_toSpace->head())
allocateBlock();
else
- m_allocator.setCurrentBlock(static_cast<CopiedBlock*>(m_toSpace->head()));
+ m_allocator.setCurrentBlock(m_toSpace->head());
}
size_t CopiedSpace::size()
{
size_t calculatedSize = 0;
- for (CopiedBlock* block = static_cast<CopiedBlock*>(m_toSpace->head()); block; block = static_cast<CopiedBlock*>(block->next()))
+ for (CopiedBlock* block = m_toSpace->head(); block; block = block->next())
calculatedSize += block->size();
- for (CopiedBlock* block = static_cast<CopiedBlock*>(m_fromSpace->head()); block; block = static_cast<CopiedBlock*>(block->next()))
+ for (CopiedBlock* block = m_fromSpace->head(); block; block = block->next())
calculatedSize += block->size();
- for (CopiedBlock* block = static_cast<CopiedBlock*>(m_oversizeBlocks.head()); block; block = static_cast<CopiedBlock*>(block->next()))
+ for (CopiedBlock* block = m_oversizeBlocks.head(); block; block = block->next())
calculatedSize += block->size();
return calculatedSize;
@@ -247,22 +247,22 @@ size_t CopiedSpace::capacity()
{
size_t calculatedCapacity = 0;
- for (CopiedBlock* block = static_cast<CopiedBlock*>(m_toSpace->head()); block; block = static_cast<CopiedBlock*>(block->next()))
+ for (CopiedBlock* block = m_toSpace->head(); block; block = block->next())
calculatedCapacity += block->capacity();
- for (CopiedBlock* block = static_cast<CopiedBlock*>(m_fromSpace->head()); block; block = static_cast<CopiedBlock*>(block->next()))
+ for (CopiedBlock* block = m_fromSpace->head(); block; block = block->next())
calculatedCapacity += block->capacity();
- for (CopiedBlock* block = static_cast<CopiedBlock*>(m_oversizeBlocks.head()); block; block = static_cast<CopiedBlock*>(block->next()))
+ for (CopiedBlock* block = m_oversizeBlocks.head(); block; block = block->next())
calculatedCapacity += block->capacity();
return calculatedCapacity;
}
-static bool isBlockListPagedOut(double deadline, DoublyLinkedList<HeapBlock>* list)
+static bool isBlockListPagedOut(double deadline, DoublyLinkedList<CopiedBlock>* list)
{
unsigned itersSinceLastTimeCheck = 0;
- HeapBlock* current = list->head();
+ CopiedBlock* current = list->head();
while (current) {
current = current->next();
++itersSinceLastTimeCheck;
diff --git a/Source/JavaScriptCore/heap/CopiedSpace.h b/Source/JavaScriptCore/heap/CopiedSpace.h
index be3a331e8..ec394ca8f 100644
--- a/Source/JavaScriptCore/heap/CopiedSpace.h
+++ b/Source/JavaScriptCore/heap/CopiedSpace.h
@@ -44,7 +44,6 @@ namespace JSC {
class Heap;
class CopiedBlock;
-class HeapBlock;
class CopiedSpace {
friend class SlotVisitor;
@@ -101,12 +100,12 @@ private:
SpinLock m_toSpaceLock;
- DoublyLinkedList<HeapBlock>* m_toSpace;
- DoublyLinkedList<HeapBlock>* m_fromSpace;
+ DoublyLinkedList<CopiedBlock>* m_toSpace;
+ DoublyLinkedList<CopiedBlock>* m_fromSpace;
- DoublyLinkedList<HeapBlock> m_blocks1;
- DoublyLinkedList<HeapBlock> m_blocks2;
- DoublyLinkedList<HeapBlock> m_oversizeBlocks;
+ DoublyLinkedList<CopiedBlock> m_blocks1;
+ DoublyLinkedList<CopiedBlock> m_blocks2;
+ DoublyLinkedList<CopiedBlock> m_oversizeBlocks;
bool m_inCopyingPhase;
@@ -116,7 +115,7 @@ private:
static const size_t s_maxAllocationSize = 32 * KB;
static const size_t s_initialBlockNum = 16;
- static const size_t s_blockMask = ~(HeapBlock::s_blockSize - 1);
+ static const size_t s_blockMask = ~(CopiedBlock::s_blockSize - 1);
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h
index e2af41ad8..790a302de 100644
--- a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h
+++ b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h
@@ -95,9 +95,7 @@ inline void CopiedSpace::pinIfNecessary(void* opaquePointer)
inline void CopiedSpace::startedCopying()
{
- DoublyLinkedList<HeapBlock>* temp = m_fromSpace;
- m_fromSpace = m_toSpace;
- m_toSpace = temp;
+ std::swap(m_fromSpace, m_toSpace);
m_blockFilter.reset();
m_allocator.resetCurrentBlock();
diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp
index 377132765..669178804 100644
--- a/Source/JavaScriptCore/heap/Heap.cpp
+++ b/Source/JavaScriptCore/heap/Heap.cpp
@@ -830,4 +830,18 @@ void Heap::addCompiledCode(ExecutableBase* executable)
m_compiledCode.append(executable);
}
+bool Heap::isSafeToSweepStructures()
+{
+ return !m_sweeper || m_sweeper->structuresCanBeSwept();
+}
+
+void Heap::didStartVMShutdown()
+{
+ m_activityCallback->didStartVMShutdown();
+ m_activityCallback = 0;
+ m_sweeper->didStartVMShutdown();
+ m_sweeper = 0;
+ lastChanceToFinalize();
+}
+
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h
index 595e937ce..f3474f2ea 100644
--- a/Source/JavaScriptCore/heap/Heap.h
+++ b/Source/JavaScriptCore/heap/Heap.h
@@ -168,6 +168,8 @@ namespace JSC {
void didAbandon(size_t);
bool isPagedOut(double deadline);
+ bool isSafeToSweepStructures();
+ void didStartVMShutdown();
private:
friend class CodeBlock;
diff --git a/Source/JavaScriptCore/heap/HeapBlock.h b/Source/JavaScriptCore/heap/HeapBlock.h
index 3cd3c6322..a63b7ebe1 100644
--- a/Source/JavaScriptCore/heap/HeapBlock.h
+++ b/Source/JavaScriptCore/heap/HeapBlock.h
@@ -34,22 +34,42 @@ namespace JSC {
enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
-class HeapBlock : public DoublyLinkedListNode<HeapBlock> {
+#if COMPILER(GCC)
+#define CLASS_IF_GCC class
+#else
+#define CLASS_IF_GCC
+#endif
+
+template<typename T>
+class HeapBlock : public DoublyLinkedListNode<T> {
+ friend CLASS_IF_GCC DoublyLinkedListNode<T>;
public:
+ static const size_t s_blockSize = 64 * KB;
+
+ static PageAllocationAligned destroy(HeapBlock* block)
+ {
+ static_cast<T*>(block)->~T();
+
+ PageAllocationAligned allocation;
+ std::swap(allocation, block->m_allocation);
+ return allocation;
+ }
+
HeapBlock(const PageAllocationAligned& allocation)
- : DoublyLinkedListNode<HeapBlock>()
+ : DoublyLinkedListNode<T>()
+ , m_allocation(allocation)
, m_prev(0)
, m_next(0)
- , m_allocation(allocation)
{
ASSERT(m_allocation);
}
- HeapBlock* m_prev;
- HeapBlock* m_next;
+ const PageAllocationAligned allocation() const { return m_allocation; }
+
+private:
PageAllocationAligned m_allocation;
-
- static const size_t s_blockSize = 64 * KB;
+ T* m_prev;
+ T* m_next;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
index 49222c545..f284d8b57 100644
--- a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
+++ b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
@@ -51,6 +51,7 @@ void IncrementalSweeper::doWork()
IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop)
: HeapTimer(heap->globalData(), runLoop)
, m_currentBlockToSweepIndex(0)
+ , m_structuresCanBeSwept(false)
{
}
@@ -72,12 +73,7 @@ void IncrementalSweeper::cancelTimer()
void IncrementalSweeper::doSweep(double sweepBeginTime)
{
while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) {
- MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++];
- if (!block->needsSweeping())
- continue;
-
- block->sweep();
- m_globalData->heap.objectSpace().freeOrShrinkBlock(block);
+ sweepNextBlock();
CFTimeInterval elapsedTime = WTF::monotonicallyIncreasingTime() - sweepBeginTime;
if (elapsedTime < sweepTimeSlice)
@@ -91,17 +87,48 @@ void IncrementalSweeper::doSweep(double sweepBeginTime)
cancelTimer();
}
+void IncrementalSweeper::sweepNextBlock()
+{
+ while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) {
+ MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++];
+ if (block->onlyContainsStructures())
+ m_structuresCanBeSwept = true;
+ else
+ ASSERT(!m_structuresCanBeSwept);
+
+ if (!block->needsSweeping())
+ continue;
+
+ block->sweep();
+ m_globalData->heap.objectSpace().freeOrShrinkBlock(block);
+ return;
+ }
+}
+
void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>& blockSnapshot)
{
- WTF::copyToVector(blockSnapshot, m_blocksToSweep);
+ m_blocksToSweep.resize(blockSnapshot.size());
+ CopyFunctor functor(m_blocksToSweep);
+ m_globalData->heap.objectSpace().forEachBlock(functor);
m_currentBlockToSweepIndex = 0;
+ m_structuresCanBeSwept = false;
scheduleTimer();
}
+void IncrementalSweeper::willFinishSweeping()
+{
+ m_currentBlockToSweepIndex = 0;
+ m_structuresCanBeSwept = true;
+ m_blocksToSweep.clear();
+ if (m_globalData)
+ cancelTimer();
+}
+
#else
IncrementalSweeper::IncrementalSweeper(JSGlobalData* globalData)
: HeapTimer(globalData)
+ , m_structuresCanBeSwept(false)
{
}
@@ -116,8 +143,23 @@ IncrementalSweeper* IncrementalSweeper::create(Heap* heap)
void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>&)
{
+ m_structuresCanBeSwept = false;
}
-
+
+void IncrementalSweeper::willFinishSweeping()
+{
+ m_structuresCanBeSwept = true;
+}
+
+void IncrementalSweeper::sweepNextBlock()
+{
+}
+
#endif
+bool IncrementalSweeper::structuresCanBeSwept()
+{
+ return m_structuresCanBeSwept;
+}
+
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.h b/Source/JavaScriptCore/heap/IncrementalSweeper.h
index eedfa7f6f..c8005b071 100644
--- a/Source/JavaScriptCore/heap/IncrementalSweeper.h
+++ b/Source/JavaScriptCore/heap/IncrementalSweeper.h
@@ -36,12 +36,28 @@
namespace JSC {
class Heap;
-
+
+struct CopyFunctor : public MarkedBlock::VoidFunctor {
+ CopyFunctor(Vector<MarkedBlock*>& blocks)
+ : m_index(0)
+ , m_blocks(blocks)
+ {
+ }
+
+ void operator()(MarkedBlock* block) { m_blocks[m_index++] = block; }
+
+ size_t m_index;
+ Vector<MarkedBlock*>& m_blocks;
+};
+
class IncrementalSweeper : public HeapTimer {
public:
static IncrementalSweeper* create(Heap*);
void startSweeping(const HashSet<MarkedBlock*>& blockSnapshot);
virtual void doWork();
+ void sweepNextBlock();
+ bool structuresCanBeSwept();
+ void willFinishSweeping();
private:
#if USE(CF)
@@ -58,6 +74,7 @@ private:
IncrementalSweeper(JSGlobalData*);
#endif
+ bool m_structuresCanBeSwept;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
index 8e0c57b6a..537a34e48 100644
--- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp
+++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp
@@ -142,7 +142,7 @@ MachineThreads::MachineThreads(Heap* heap)
MachineThreads::~MachineThreads()
{
if (m_threadSpecific)
- ThreadSpecificKeyDelete(m_threadSpecific);
+ threadSpecificKeyDelete(m_threadSpecific);
MutexLocker registeredThreadsLock(m_registeredThreadsMutex);
for (Thread* t = m_registeredThreads; t;) {
@@ -179,17 +179,17 @@ void MachineThreads::makeUsableFromMultipleThreads()
if (m_threadSpecific)
return;
- ThreadSpecificKeyCreate(&m_threadSpecific, removeThread);
+ threadSpecificKeyCreate(&m_threadSpecific, removeThread);
}
void MachineThreads::addCurrentThread()
{
ASSERT(!m_heap->globalData()->exclusiveThread || m_heap->globalData()->exclusiveThread == currentThread());
- if (!m_threadSpecific || ThreadSpecificGet(m_threadSpecific))
+ if (!m_threadSpecific || threadSpecificGet(m_threadSpecific))
return;
- ThreadSpecificSet(m_threadSpecific, this);
+ threadSpecificSet(m_threadSpecific, this);
Thread* thread = new Thread(getCurrentPlatformThread(), wtfThreadData().stack().origin());
MutexLocker lock(m_registeredThreadsMutex);
diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.cpp b/Source/JavaScriptCore/heap/MarkedAllocator.cpp
index 465e3a72a..20b556969 100644
--- a/Source/JavaScriptCore/heap/MarkedAllocator.cpp
+++ b/Source/JavaScriptCore/heap/MarkedAllocator.cpp
@@ -3,6 +3,7 @@
#include "GCActivityCallback.h"
#include "Heap.h"
+#include "IncrementalSweeper.h"
#include "JSGlobalData.h"
#include <wtf/CurrentTime.h>
@@ -11,7 +12,7 @@ namespace JSC {
bool MarkedAllocator::isPagedOut(double deadline)
{
unsigned itersSinceLastTimeCheck = 0;
- HeapBlock* block = m_blockList.head();
+ MarkedBlock* block = m_blockList.head();
while (block) {
block = block->next();
++itersSinceLastTimeCheck;
@@ -29,7 +30,18 @@ bool MarkedAllocator::isPagedOut(double deadline)
inline void* MarkedAllocator::tryAllocateHelper()
{
if (!m_freeList.head) {
- for (MarkedBlock*& block = m_blocksToSweep; block; block = static_cast<MarkedBlock*>(block->next())) {
+ if (m_onlyContainsStructures && !m_heap->isSafeToSweepStructures()) {
+ if (m_currentBlock) {
+ m_currentBlock->didConsumeFreeList();
+ m_currentBlock = 0;
+ }
+ // We sweep another random block here so that we can make progress
+ // toward being able to sweep Structures.
+ m_heap->sweeper()->sweepNextBlock();
+ return 0;
+ }
+
+ for (MarkedBlock*& block = m_blocksToSweep; block; block = block->next()) {
m_freeList = block->sweep(MarkedBlock::SweepToFreeList);
if (m_freeList.head) {
m_currentBlock = block;
@@ -104,7 +116,6 @@ MarkedBlock* MarkedAllocator::allocateBlock()
void MarkedAllocator::addBlock(MarkedBlock* block)
{
ASSERT(!m_currentBlock);
- ASSERT(!m_blocksToSweep);
ASSERT(!m_freeList.head);
m_blockList.append(block);
@@ -115,11 +126,11 @@ void MarkedAllocator::addBlock(MarkedBlock* block)
void MarkedAllocator::removeBlock(MarkedBlock* block)
{
if (m_currentBlock == block) {
- m_currentBlock = static_cast<MarkedBlock*>(m_currentBlock->next());
+ m_currentBlock = m_currentBlock->next();
m_freeList = MarkedBlock::FreeList();
}
if (m_blocksToSweep == block)
- m_blocksToSweep = static_cast<MarkedBlock*>(m_blocksToSweep->next());
+ m_blocksToSweep = m_blocksToSweep->next();
m_blockList.remove(block);
}
diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.h b/Source/JavaScriptCore/heap/MarkedAllocator.h
index 47bae9451..c1c431194 100644
--- a/Source/JavaScriptCore/heap/MarkedAllocator.h
+++ b/Source/JavaScriptCore/heap/MarkedAllocator.h
@@ -47,7 +47,7 @@ private:
MarkedBlock::FreeList m_freeList;
MarkedBlock* m_currentBlock;
MarkedBlock* m_blocksToSweep;
- DoublyLinkedList<HeapBlock> m_blockList;
+ DoublyLinkedList<MarkedBlock> m_blockList;
size_t m_cellSize;
bool m_cellsNeedDestruction;
bool m_onlyContainsStructures;
@@ -90,7 +90,7 @@ inline void MarkedAllocator::reset()
{
m_currentBlock = 0;
m_freeList = MarkedBlock::FreeList();
- m_blocksToSweep = static_cast<MarkedBlock*>(m_blockList.head());
+ m_blocksToSweep = m_blockList.head();
}
inline void MarkedAllocator::zapFreeList()
@@ -101,15 +101,16 @@ inline void MarkedAllocator::zapFreeList()
}
m_currentBlock->zapFreeList(m_freeList);
+ m_currentBlock = 0;
m_freeList = MarkedBlock::FreeList();
}
template <typename Functor> inline void MarkedAllocator::forEachBlock(Functor& functor)
{
- HeapBlock* next;
- for (HeapBlock* block = m_blockList.head(); block; block = next) {
+ MarkedBlock* next;
+ for (MarkedBlock* block = m_blockList.head(); block; block = next) {
next = block->next();
- functor(static_cast<MarkedBlock*>(block));
+ functor(block);
}
}
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.cpp b/Source/JavaScriptCore/heap/MarkedBlock.cpp
index 8ede87927..95ea2f414 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.cpp
+++ b/Source/JavaScriptCore/heap/MarkedBlock.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "MarkedBlock.h"
+#include "IncrementalSweeper.h"
#include "JSCell.h"
#include "JSObject.h"
#include "ScopeChain.h"
@@ -37,17 +38,8 @@ MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, Heap*
return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize, cellsNeedDestruction, onlyContainsStructures);
}
-PageAllocationAligned MarkedBlock::destroy(MarkedBlock* block)
-{
- PageAllocationAligned allocation;
- swap(allocation, block->m_allocation);
-
- block->~MarkedBlock();
- return allocation;
-}
-
MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures)
- : HeapBlock(allocation)
+ : HeapBlock<MarkedBlock>(allocation)
, m_atomsPerCell((cellSize + atomSize - 1) / atomSize)
, m_endAtom(atomsPerBlock - m_atomsPerCell + 1)
, m_cellsNeedDestruction(cellsNeedDestruction)
@@ -69,10 +61,6 @@ inline void MarkedBlock::callDestructor(JSCell* cell)
m_heap->m_destroyedTypeCounts.countVPtr(vptr);
#endif
-#if !ASSERT_DISABLED || ENABLE(GC_VALIDATION)
- cell->clearStructure();
-#endif
-
cell->methodTable()->destroy(cell);
cell->zap();
}
@@ -140,10 +128,12 @@ MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode)
ASSERT_NOT_REACHED();
return FreeList();
case Marked:
+ ASSERT(!m_onlyContainsStructures || heap()->isSafeToSweepStructures());
return sweepMode == SweepToFreeList
? specializedSweep<Marked, SweepToFreeList, destructorCallNeeded>()
: specializedSweep<Marked, SweepOnly, destructorCallNeeded>();
case Zapped:
+ ASSERT(!m_onlyContainsStructures || heap()->isSafeToSweepStructures());
return sweepMode == SweepToFreeList
? specializedSweep<Zapped, SweepToFreeList, destructorCallNeeded>()
: specializedSweep<Zapped, SweepOnly, destructorCallNeeded>();
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h
index ff7840632..ab2abd753 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.h
+++ b/Source/JavaScriptCore/heap/MarkedBlock.h
@@ -67,8 +67,7 @@ namespace JSC {
// size is equal to the difference between the cell size and the object
// size.
- class MarkedBlock : public HeapBlock {
- friend class WTF::DoublyLinkedListNode<MarkedBlock>;
+ class MarkedBlock : public HeapBlock<MarkedBlock> {
public:
// Ensure natural alignment for native types whilst recognizing that the smallest
// object the heap will commonly allocate is four words.
@@ -114,7 +113,6 @@ namespace JSC {
};
static MarkedBlock* create(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures);
- static PageAllocationAligned destroy(MarkedBlock*);
static bool isAtomAligned(const void*);
static MarkedBlock* blockFor(const void*);
@@ -336,7 +334,7 @@ namespace JSC {
inline size_t MarkedBlock::capacity()
{
- return m_allocation.size();
+ return allocation().size();
}
inline size_t MarkedBlock::atomNumber(const void* p)
diff --git a/Source/JavaScriptCore/heap/MarkedSpace.cpp b/Source/JavaScriptCore/heap/MarkedSpace.cpp
index a9e9ef64d..cd6be001c 100644
--- a/Source/JavaScriptCore/heap/MarkedSpace.cpp
+++ b/Source/JavaScriptCore/heap/MarkedSpace.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "MarkedSpace.h"
+#include "IncrementalSweeper.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
#include "JSObject.h"
@@ -108,6 +109,12 @@ void MarkedSpace::lastChanceToFinalize()
forEachBlock<LastChanceToFinalize>();
}
+void MarkedSpace::sweep()
+{
+ m_heap->sweeper()->willFinishSweeping();
+ forEachBlock<Sweep>();
+}
+
void MarkedSpace::resetAllocators()
{
for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) {
diff --git a/Source/JavaScriptCore/heap/MarkedSpace.h b/Source/JavaScriptCore/heap/MarkedSpace.h
index d2a0688f1..d5dae3584 100644
--- a/Source/JavaScriptCore/heap/MarkedSpace.h
+++ b/Source/JavaScriptCore/heap/MarkedSpace.h
@@ -235,11 +235,6 @@ inline void MarkedSpace::clearMarks()
forEachBlock<ClearMarks>();
}
-inline void MarkedSpace::sweep()
-{
- forEachBlock<Sweep>();
-}
-
inline size_t MarkedSpace::objectCount()
{
return forEachBlock<MarkCount>();
diff --git a/Source/JavaScriptCore/heap/WeakSetInlines.h b/Source/JavaScriptCore/heap/WeakSetInlines.h
index c1c87b380..76337fda7 100644
--- a/Source/JavaScriptCore/heap/WeakSetInlines.h
+++ b/Source/JavaScriptCore/heap/WeakSetInlines.h
@@ -49,9 +49,6 @@ inline void WeakBlock::finalize(WeakImpl* weakImpl)
WeakHandleOwner* weakHandleOwner = weakImpl->weakHandleOwner();
if (!weakHandleOwner)
return;
-#if !ASSERT_DISABLED || ENABLE(GC_VALIDATION)
- weakImpl->jsValue().asCell()->clearStructure();
-#endif
weakHandleOwner->finalize(Handle<Unknown>::wrapSlot(&const_cast<JSValue&>(weakImpl->jsValue())), weakImpl->context());
}
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index 3edb8589e..51f22bedd 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -730,9 +730,9 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
if (callFrame->callee())
- debugger->returnEvent(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine());
+ debugger->returnEvent(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine(), 0);
else
- debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine());
+ debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->lastLine(), 0);
}
// If this call frame created an activation or an 'arguments' object, tear it off.
@@ -1055,7 +1055,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
- debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), hasHandler);
+ debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), 0, hasHandler);
}
// Calculate an exception handler vPC, unwinding call frames as necessary.
@@ -1643,7 +1643,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
return checkedReturn(result);
}
-NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine)
+NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine, int column)
{
Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
if (!debugger)
@@ -1651,22 +1651,22 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
switch (debugHookID) {
case DidEnterCallFrame:
- debugger->callEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
+ debugger->callEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine, column);
return;
case WillLeaveCallFrame:
- debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
+ debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine, column);
return;
case WillExecuteStatement:
- debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
+ debugger->atStatement(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine, column);
return;
case WillExecuteProgram:
- debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine);
+ debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), firstLine, column);
return;
case DidExecuteProgram:
- debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
+ debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine, column);
return;
case DidReachBreakpoint:
- debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine);
+ debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerExecutable()->sourceID(), lastLine, column);
return;
}
}
@@ -5245,7 +5245,7 @@ skip_id_custom_self:
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_debug) {
- /* debug debugHookID(n) firstLine(n) lastLine(n)
+ /* debug debugHookID(n) firstLine(n) lastLine(n) column(n)
Notifies the debugger of the current state of execution. This opcode
is only generated while the debugger is attached.
@@ -5253,8 +5253,10 @@ skip_id_custom_self:
int debugHookID = vPC[1].u.operand;
int firstLine = vPC[2].u.operand;
int lastLine = vPC[3].u.operand;
+ int column = vPC[4].u.operand;
- debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
+
+ debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
vPC += OPCODE_LENGTH(op_debug);
NEXT_INSTRUCTION();
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h
index 8663bf8ec..f4ccd995c 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.h
+++ b/Source/JavaScriptCore/interpreter/Interpreter.h
@@ -240,7 +240,7 @@ namespace JSC {
SamplingTool* sampler() { return m_sampler.get(); }
NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
- NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
+ NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine, int column);
static const UString getTraceLine(CallFrame*, StackFrameCodeType, const UString&, int);
JS_EXPORT_PRIVATE static void getStackTrace(JSGlobalData*, Vector<StackFrame>& results);
static void addStackTraceIfNecessary(CallFrame*, JSObject* error);
diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h
index 32bc1837d..e68ecbe78 100644
--- a/Source/JavaScriptCore/jit/JITInlineMethods.h
+++ b/Source/JavaScriptCore/jit/JITInlineMethods.h
@@ -84,7 +84,7 @@ ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHea
ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures)
{
- failures.append(branchPtr(NotEqual, Address(src, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ failures.append(branchPtr(NotEqual, Address(src, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
failures.append(branch32(NotEqual, MacroAssembler::Address(src, ThunkHelpers::jsStringLengthOffset()), TrustedImm32(1)));
loadPtr(MacroAssembler::Address(src, ThunkHelpers::jsStringValueOffset()), dst);
failures.append(branchTest32(Zero, dst));
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index c0af6f9e9..0d24961b8 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -50,7 +50,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl
// Check eax is a string
Jump string_failureCases1 = emitJumpIfNotJSCell(regT0);
- Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info));
+ Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(globalData->stringStructure.get()));
// Checks out okay! - get the length from the Ustring.
load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), regT0);
@@ -647,7 +647,7 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
emitGetVirtualRegister(src, regT0);
Jump isImm = emitJumpIfNotJSCell(regT0);
- addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
isImm.link(this);
if (dst != src)
@@ -1158,6 +1158,7 @@ void JIT::emit_op_debug(Instruction* currentInstruction)
stubCall.addArgument(TrustedImm32(currentInstruction[1].u.operand));
stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand));
stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
+ stubCall.addArgument(TrustedImm32(currentInstruction[4].u.operand));
stubCall.call();
#endif
}
@@ -1260,7 +1261,7 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
loadPtr(Address(regT1, JSCell::structureOffset()), regT0);
emitValueProfilingSite();
}
- addSlowCase(branchPtr(Equal, Address(regT1, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ addSlowCase(branchPtr(Equal, Address(regT1, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
}
void JIT::emit_op_create_this(Instruction* currentInstruction)
diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
index 095ea57d3..eec9df36f 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -48,7 +48,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl
// regT0 holds payload, regT1 holds tag
Jump string_failureCases1 = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
- Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info));
+ Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(globalData->stringStructure.get()));
// Checks out okay! - get the length from the Ustring.
load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), regT2);
@@ -732,7 +732,7 @@ void JIT::emit_op_to_primitive(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
Jump isImm = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
- addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
isImm.link(this);
if (dst != src)
@@ -1008,8 +1008,8 @@ void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>:
genericCase.append(getSlowCase(iter)); // tags not equal
linkSlowCase(iter); // tags equal and JSCell
- genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
- genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
+ genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
// String case.
JITStubCall stubCallEqStrings(this, cti_op_eq_strings);
@@ -1056,8 +1056,8 @@ void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>
genericCase.append(getSlowCase(iter)); // tags not equal
linkSlowCase(iter); // tags equal and JSCell
- genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
- genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ genericCase.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
+ genericCase.append(branchPtr(NotEqual, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
// String case.
JITStubCall stubCallEqStrings(this, cti_op_eq_strings);
@@ -1093,8 +1093,8 @@ void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqTy
// Jump to a slow case if both are strings.
Jump notCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
- Jump firstNotString = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info));
- addSlowCase(branchPtr(Equal, Address(regT2, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ Jump firstNotString = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get()));
+ addSlowCase(branchPtr(Equal, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
notCell.link(this);
firstNotString.link(this);
@@ -1478,6 +1478,7 @@ 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();
#endif
}
@@ -1556,7 +1557,7 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
move(regT3, regT1);
emitValueProfilingSite();
}
- addSlowCase(branchPtr(Equal, Address(regT2, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ addSlowCase(branchPtr(Equal, Address(regT2, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get())));
}
void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index 86078fbc3..dfb2dc8ec 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -56,7 +56,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
{
JSInterfaceJIT jit;
JumpList failures;
- failures.append(jit.branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ failures.append(jit.branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(globalData->stringStructure.get())));
// Load string length to regT2, and start the process of loading the data pointer into regT0
jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT2);
@@ -132,7 +132,7 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
linkSlowCaseIfNotJSCell(iter, base); // base cell check
Jump nonCell = jump();
linkSlowCase(iter); // base array check
- Jump notString = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info));
+ Jump notString = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get()));
emitNakedCall(CodeLocationLabel(m_globalData->getCTIStub(stringGetByValStubGenerator).code()));
Jump failed = branchTestPtr(Zero, regT0);
emitPutVirtualRegister(dst, regT0);
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 365ecd20a..b506f4ecb 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -161,7 +161,7 @@ JIT::CodeRef JIT::stringGetByValStubGenerator(JSGlobalData* globalData)
{
JSInterfaceJIT jit;
JumpList failures;
- failures.append(jit.branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ failures.append(jit.branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(globalData->stringStructure.get())));
// Load string length to regT1, and start the process of loading the data pointer into regT0
jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT1);
@@ -234,7 +234,7 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas
Jump nonCell = jump();
linkSlowCase(iter); // base array check
- Jump notString = branchPtr(NotEqual, Address(regT0, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info));
+ Jump notString = branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(m_globalData->stringStructure.get()));
emitNakedCall(m_globalData->getCTIStub(stringGetByValStubGenerator).code());
Jump failed = branchTestPtr(Zero, regT0);
emitStore(dst, regT1, regT0);
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index 0f03a0a4a..8b8546994 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -1430,15 +1430,19 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
+ CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+ AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
+
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
- CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
- StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
- if (!stubInfo->seenOnce())
- stubInfo->setSeen();
- else
- JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
+ if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
+ if (!stubInfo->seenOnce())
+ stubInfo->setSeen();
+ else
+ JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
+ }
CHECK_FOR_EXCEPTION_AT_END();
}
@@ -1449,18 +1453,22 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
+ CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+ AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
+
PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
JSValue baseValue = stackFrame.args[0].jsValue();
ASSERT(baseValue.isObject());
asObject(baseValue)->putDirect(callFrame->globalData(), ident, stackFrame.args[2].jsValue(), slot);
- CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
- StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
- if (!stubInfo->seenOnce())
- stubInfo->setSeen();
- else
- JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
+ if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
+ if (!stubInfo->seenOnce())
+ stubInfo->setSeen();
+ else
+ JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
+ }
CHECK_FOR_EXCEPTION_AT_END();
}
@@ -1521,14 +1529,18 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
+ CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
+ MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
+ StructureStubInfo& stubInfo = codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue baseValue = stackFrame.args[0].jsValue();
PropertySlot slot(baseValue);
JSValue result = baseValue.get(callFrame, ident, slot);
CHECK_FOR_EXCEPTION();
-
- CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
- MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
- StructureStubInfo& stubInfo = codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+
+ if (accessType != static_cast<AccessType>(stubInfo.accessType))
+ return JSValue::encode(result);
if (!methodCallLinkInfo.seenOnce()) {
methodCallLinkInfo.setSeen();
@@ -1595,14 +1607,18 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_update)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
+ CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
+ MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
+ StructureStubInfo& stubInfo = codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+ AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
+
JSValue baseValue = stackFrame.args[0].jsValue();
PropertySlot slot(baseValue);
JSValue result = baseValue.get(callFrame, ident, slot);
CHECK_FOR_EXCEPTION();
-
- CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
- MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
- StructureStubInfo& stubInfo = codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+
+ if (accessType != static_cast<AccessType>(stubInfo.accessType))
+ return JSValue::encode(result);
ASSERT(methodCallLinkInfo.seenOnce());
@@ -1684,12 +1700,17 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
+ CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+ AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
+
JSValue baseValue = stackFrame.args[0].jsValue();
PropertySlot slot(baseValue);
JSValue result = baseValue.get(callFrame, ident, slot);
+
+ if (accessType != static_cast<AccessType>(stubInfo->accessType))
+ return JSValue::encode(result);
- CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
- StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
if (!stubInfo->seenOnce())
stubInfo->setSeen();
else
@@ -1706,9 +1727,16 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+ AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
+
JSValue baseValue = stackFrame.args[0].jsValue();
PropertySlot slot(baseValue);
JSValue result = baseValue.get(callFrame, ident, slot);
+
+ if (accessType != static_cast<AccessType>(stubInfo->accessType))
+ return JSValue::encode(result);
CHECK_FOR_EXCEPTION();
@@ -1717,9 +1745,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
&& !baseValue.asCell()->structure()->isUncacheableDictionary()
&& slot.slotBase() == baseValue) {
- CodeBlock* codeBlock = callFrame->codeBlock();
- StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
-
ASSERT(slot.slotBase().isObject());
PolymorphicAccessStructureList* polymorphicStructureList;
@@ -1813,20 +1838,26 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
CallFrame* callFrame = stackFrame.callFrame;
const Identifier& propertyName = stackFrame.args[1].identifier();
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+ AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
+
JSValue baseValue = stackFrame.args[0].jsValue();
PropertySlot slot(baseValue);
JSValue result = baseValue.get(callFrame, propertyName, slot);
CHECK_FOR_EXCEPTION();
- if (!baseValue.isCell() || !slot.isCacheable() || baseValue.asCell()->structure()->isDictionary() || baseValue.asCell()->structure()->typeInfo().prohibitsPropertyCaching()) {
+ if (accessType != static_cast<AccessType>(stubInfo->accessType)
+ || !baseValue.isCell()
+ || !slot.isCacheable()
+ || baseValue.asCell()->structure()->isDictionary()
+ || baseValue.asCell()->structure()->typeInfo().prohibitsPropertyCaching()) {
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
return JSValue::encode(result);
}
Structure* structure = baseValue.asCell()->structure();
- CodeBlock* codeBlock = callFrame->codeBlock();
- StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
ASSERT(slot.slotBase().isObject());
JSObject* slotBaseObject = asObject(slot.slotBase());
@@ -3403,8 +3434,9 @@ 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);
+ stackFrame.globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
}
DEFINE_STUB_FUNCTION(void*, vm_throw)
diff --git a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
index e17b45d94..0fe606476 100644
--- a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
+++ b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h
@@ -55,10 +55,10 @@ namespace JSC {
m_failures.append(emitLoadJSCell(src, dst));
}
- void loadJSStringArgument(int argument, RegisterID dst)
+ void loadJSStringArgument(JSGlobalData& globalData, int argument, RegisterID dst)
{
loadCellArgument(argument, dst);
- m_failures.append(branchPtr(NotEqual, Address(dst, JSCell::classInfoOffset()), TrustedImmPtr(&JSString::s_info)));
+ m_failures.append(branchPtr(NotEqual, Address(dst, JSCell::structureOffset()), TrustedImmPtr(globalData.stringStructure.get())));
}
void loadInt32Argument(int argument, RegisterID dst, Jump& failTarget)
diff --git a/Source/JavaScriptCore/jit/ThunkGenerators.cpp b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
index c6431c22d..cbfc1eb0f 100644
--- a/Source/JavaScriptCore/jit/ThunkGenerators.cpp
+++ b/Source/JavaScriptCore/jit/ThunkGenerators.cpp
@@ -35,10 +35,10 @@
namespace JSC {
-static void stringCharLoad(SpecializedThunkJIT& jit)
+static void stringCharLoad(SpecializedThunkJIT& jit, JSGlobalData* globalData)
{
// load string
- jit.loadJSStringArgument(SpecializedThunkJIT::ThisArgument, SpecializedThunkJIT::regT0);
+ jit.loadJSStringArgument(*globalData, SpecializedThunkJIT::ThisArgument, SpecializedThunkJIT::regT0);
// Load string length to regT2, and start the process of loading the data pointer into regT0
jit.load32(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::jsStringLengthOffset()), SpecializedThunkJIT::regT2);
@@ -76,7 +76,7 @@ static void charToString(SpecializedThunkJIT& jit, JSGlobalData* globalData, Mac
MacroAssemblerCodeRef charCodeAtThunkGenerator(JSGlobalData* globalData)
{
SpecializedThunkJIT jit(1);
- stringCharLoad(jit);
+ stringCharLoad(jit, globalData);
jit.returnInt32(SpecializedThunkJIT::regT0);
return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "charCodeAt");
}
@@ -84,7 +84,7 @@ MacroAssemblerCodeRef charCodeAtThunkGenerator(JSGlobalData* globalData)
MacroAssemblerCodeRef charAtThunkGenerator(JSGlobalData* globalData)
{
SpecializedThunkJIT jit(1);
- stringCharLoad(jit);
+ stringCharLoad(jit, globalData);
charToString(jit, globalData, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
jit.returnJSCell(SpecializedThunkJIT::regT0);
return jit.finalize(*globalData, globalData->jitStubs->ctiNativeCall(), "charAt");
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index d2d743e0a..58bf1bdeb 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -1601,8 +1601,9 @@ LLINT_SLOW_PATH_DECL(slow_path_debug)
int debugHookID = pc[1].u.operand;
int firstLine = pc[2].u.operand;
int lastLine = pc[3].u.operand;
-
- globalData.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
+ int column = pc[4].u.operand;
+
+ globalData.interpreter->debug(exec, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
LLINT_END();
}
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index 2ae3e0cb2..10a5aaeab 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -760,7 +760,7 @@ _llint_op_profile_did_call:
_llint_op_debug:
traceExecution()
callSlowPath(_llint_slow_path_debug)
- dispatch(4)
+ dispatch(5)
_llint_native_call_trampoline:
diff --git a/Source/JavaScriptCore/parser/ASTBuilder.h b/Source/JavaScriptCore/parser/ASTBuilder.h
index d4c170617..0a71f1294 100644
--- a/Source/JavaScriptCore/parser/ASTBuilder.h
+++ b/Source/JavaScriptCore/parser/ASTBuilder.h
@@ -112,8 +112,8 @@ public:
static const int DontBuildKeywords = 0;
static const int DontBuildStrings = 0;
- ExpressionNode* makeBinaryNode(int lineNumber, int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
- ExpressionNode* makeFunctionCallNode(int lineNumber, ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end);
+ ExpressionNode* makeBinaryNode(const JSTokenLocation&, int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
+ ExpressionNode* makeFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end);
JSC::SourceElements* createSourceElements() { return new (m_globalData) JSC::SourceElements(); }
@@ -124,168 +124,168 @@ public:
void appendToComma(CommaNode* commaNode, ExpressionNode* expr) { commaNode->append(expr); }
- CommaNode* createCommaExpr(int lineNumber, ExpressionNode* lhs, ExpressionNode* rhs) { return new (m_globalData) CommaNode(lineNumber, lhs, rhs); }
-
- ExpressionNode* makeAssignNode(int lineNumber, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end);
- ExpressionNode* makePrefixNode(int lineNumber, ExpressionNode*, Operator, int start, int divot, int end);
- ExpressionNode* makePostfixNode(int lineNumber, ExpressionNode*, Operator, int start, int divot, int end);
- ExpressionNode* makeTypeOfNode(int lineNumber, ExpressionNode*);
- ExpressionNode* makeDeleteNode(int lineNumber, ExpressionNode*, int start, int divot, int end);
- ExpressionNode* makeNegateNode(int lineNumber, ExpressionNode*);
- ExpressionNode* makeBitwiseNotNode(int lineNumber, ExpressionNode*);
- ExpressionNode* makeMultNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* makeDivNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* makeModNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* makeAddNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* makeSubNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* makeBitXOrNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* makeBitAndNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* makeBitOrNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* makeLeftShiftNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* makeRightShiftNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
- ExpressionNode* makeURightShiftNode(int lineNumber, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
-
- ExpressionNode* createLogicalNot(int lineNumber, ExpressionNode* expr) { return new (m_globalData) LogicalNotNode(lineNumber, expr); }
- ExpressionNode* createUnaryPlus(int lineNumber, ExpressionNode* expr) { return new (m_globalData) UnaryPlusNode(lineNumber, expr); }
- ExpressionNode* createVoid(int lineNumber, ExpressionNode* expr)
+ CommaNode* createCommaExpr(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* rhs) { return new (m_globalData) CommaNode(location, lhs, rhs); }
+
+ ExpressionNode* makeAssignNode(const JSTokenLocation&, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end);
+ ExpressionNode* makePrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, int start, int divot, int end);
+ ExpressionNode* makePostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, int start, int divot, int end);
+ ExpressionNode* makeTypeOfNode(const JSTokenLocation&, ExpressionNode*);
+ ExpressionNode* makeDeleteNode(const JSTokenLocation&, ExpressionNode*, int start, int divot, int end);
+ ExpressionNode* makeNegateNode(const JSTokenLocation&, ExpressionNode*);
+ ExpressionNode* makeBitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
+ ExpressionNode* makeMultNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+ ExpressionNode* makeDivNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+ ExpressionNode* makeModNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+ ExpressionNode* makeAddNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+ ExpressionNode* makeSubNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+ ExpressionNode* makeBitXOrNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+ ExpressionNode* makeBitAndNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+ ExpressionNode* makeBitOrNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+ ExpressionNode* makeLeftShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+ ExpressionNode* makeRightShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+ ExpressionNode* makeURightShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
+
+ ExpressionNode* createLogicalNot(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_globalData) LogicalNotNode(location, expr); }
+ ExpressionNode* createUnaryPlus(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_globalData) UnaryPlusNode(location, expr); }
+ ExpressionNode* createVoid(const JSTokenLocation& location, ExpressionNode* expr)
{
incConstants();
- return new (m_globalData) VoidNode(lineNumber, expr);
+ return new (m_globalData) VoidNode(location, expr);
}
- ExpressionNode* thisExpr(int lineNumber)
+ ExpressionNode* thisExpr(const JSTokenLocation& location)
{
usesThis();
- return new (m_globalData) ThisNode(lineNumber);
+ return new (m_globalData) ThisNode(location);
}
- ExpressionNode* createResolve(int lineNumber, const Identifier* ident, int start)
+ ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier* ident, int start)
{
if (m_globalData->propertyNames->arguments == *ident)
usesArguments();
- return new (m_globalData) ResolveNode(lineNumber, *ident, start);
+ return new (m_globalData) ResolveNode(location, *ident, start);
}
- ExpressionNode* createObjectLiteral(int lineNumber) { return new (m_globalData) ObjectLiteralNode(lineNumber); }
- ExpressionNode* createObjectLiteral(int lineNumber, PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(lineNumber, properties); }
+ ExpressionNode* createObjectLiteral(const JSTokenLocation& location) { return new (m_globalData) ObjectLiteralNode(location); }
+ ExpressionNode* createObjectLiteral(const JSTokenLocation& location, PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(location, properties); }
- ExpressionNode* createArray(int lineNumber, int elisions)
+ ExpressionNode* createArray(const JSTokenLocation& location, int elisions)
{
if (elisions)
incConstants();
- return new (m_globalData) ArrayNode(lineNumber, elisions);
+ return new (m_globalData) ArrayNode(location, elisions);
}
- ExpressionNode* createArray(int lineNumber, ElementNode* elems) { return new (m_globalData) ArrayNode(lineNumber, elems); }
- ExpressionNode* createArray(int lineNumber, int elisions, ElementNode* elems)
+ ExpressionNode* createArray(const JSTokenLocation& location, ElementNode* elems) { return new (m_globalData) ArrayNode(location, elems); }
+ ExpressionNode* createArray(const JSTokenLocation& location, int elisions, ElementNode* elems)
{
if (elisions)
incConstants();
- return new (m_globalData) ArrayNode(lineNumber, elisions, elems);
+ return new (m_globalData) ArrayNode(location, elisions, elems);
}
- ExpressionNode* createNumberExpr(int lineNumber, double d)
+ ExpressionNode* createNumberExpr(const JSTokenLocation& location, double d)
{
incConstants();
- return new (m_globalData) NumberNode(lineNumber, d);
+ return new (m_globalData) NumberNode(location, d);
}
- ExpressionNode* createString(int lineNumber, const Identifier* string)
+ ExpressionNode* createString(const JSTokenLocation& location, const Identifier* string)
{
incConstants();
- return new (m_globalData) StringNode(lineNumber, *string);
+ return new (m_globalData) StringNode(location, *string);
}
- ExpressionNode* createBoolean(int lineNumber, bool b)
+ ExpressionNode* createBoolean(const JSTokenLocation& location, bool b)
{
incConstants();
- return new (m_globalData) BooleanNode(lineNumber, b);
+ return new (m_globalData) BooleanNode(location, b);
}
- ExpressionNode* createNull(int lineNumber)
+ ExpressionNode* createNull(const JSTokenLocation& location)
{
incConstants();
- return new (m_globalData) NullNode(lineNumber);
+ return new (m_globalData) NullNode(location);
}
- ExpressionNode* createBracketAccess(int lineNumber, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, int start, int divot, int end)
+ ExpressionNode* createBracketAccess(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, int start, int divot, int end)
{
- BracketAccessorNode* node = new (m_globalData) BracketAccessorNode(lineNumber, base, property, propertyHasAssignments);
+ BracketAccessorNode* node = new (m_globalData) BracketAccessorNode(location, base, property, propertyHasAssignments);
setExceptionLocation(node, start, divot, end);
return node;
}
- ExpressionNode* createDotAccess(int lineNumber, ExpressionNode* base, const Identifier* property, int start, int divot, int end)
+ ExpressionNode* createDotAccess(const JSTokenLocation& location, ExpressionNode* base, const Identifier* property, int start, int divot, int end)
{
- DotAccessorNode* node = new (m_globalData) DotAccessorNode(lineNumber, base, *property);
+ DotAccessorNode* node = new (m_globalData) DotAccessorNode(location, base, *property);
setExceptionLocation(node, start, divot, end);
return node;
}
- ExpressionNode* createRegExp(int lineNumber, const Identifier& pattern, const Identifier& flags, int start)
+ ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, int start)
{
if (Yarr::checkSyntax(pattern.ustring()))
return 0;
- RegExpNode* node = new (m_globalData) RegExpNode(lineNumber, pattern, flags);
+ RegExpNode* node = new (m_globalData) RegExpNode(location, pattern, flags);
int size = pattern.length() + 2; // + 2 for the two /'s
setExceptionLocation(node, start, start + size, start + size);
return node;
}
- ExpressionNode* createNewExpr(int lineNumber, ExpressionNode* expr, ArgumentsNode* arguments, int start, int divot, int end)
+ ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* arguments, int start, int divot, int end)
{
- NewExprNode* node = new (m_globalData) NewExprNode(lineNumber, expr, arguments);
+ NewExprNode* node = new (m_globalData) NewExprNode(location, expr, arguments);
setExceptionLocation(node, start, divot, end);
return node;
}
- ExpressionNode* createNewExpr(int lineNumber, ExpressionNode* expr, int start, int end)
+ ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
{
- NewExprNode* node = new (m_globalData) NewExprNode(lineNumber, expr);
+ NewExprNode* node = new (m_globalData) NewExprNode(location, expr);
setExceptionLocation(node, start, end, end);
return node;
}
- ExpressionNode* createConditionalExpr(int lineNumber, ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
+ ExpressionNode* createConditionalExpr(const JSTokenLocation& location, ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
{
- return new (m_globalData) ConditionalNode(lineNumber, condition, lhs, rhs);
+ return new (m_globalData) ConditionalNode(location, condition, lhs, rhs);
}
- ExpressionNode* createAssignResolve(int lineNumber, const Identifier& ident, ExpressionNode* rhs, int start, int divot, int end)
+ ExpressionNode* createAssignResolve(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* rhs, int start, int divot, int end)
{
if (rhs->isFuncExprNode())
static_cast<FuncExprNode*>(rhs)->body()->setInferredName(ident);
- AssignResolveNode* node = new (m_globalData) AssignResolveNode(lineNumber, ident, rhs);
+ AssignResolveNode* node = new (m_globalData) AssignResolveNode(location, ident, rhs);
setExceptionLocation(node, start, divot, end);
return node;
}
- ExpressionNode* createFunctionExpr(int lineNumber, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
+ ExpressionNode* createFunctionExpr(const JSTokenLocation& location, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
{
- FuncExprNode* result = new (m_globalData) FuncExprNode(lineNumber, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
- body->setLoc(bodyStartLine, bodyEndLine);
+ FuncExprNode* result = new (m_globalData) FuncExprNode(location, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
+ body->setLoc(bodyStartLine, bodyEndLine, location.column);
return result;
}
- FunctionBodyNode* createFunctionBody(int lineNumber, bool inStrictContext)
+ FunctionBodyNode* createFunctionBody(const JSTokenLocation& location, bool inStrictContext)
{
- return FunctionBodyNode::create(m_globalData, lineNumber, inStrictContext);
+ return FunctionBodyNode::create(m_globalData, location, inStrictContext);
}
- template <bool> PropertyNode* createGetterOrSetterProperty(int lineNumber, PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
+ template <bool> PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
{
ASSERT(name);
- body->setLoc(bodyStartLine, bodyEndLine);
+ body->setLoc(bodyStartLine, bodyEndLine, location.column);
body->setInferredName(*name);
- return new (m_globalData) PropertyNode(m_globalData, *name, new (m_globalData) FuncExprNode(lineNumber, m_globalData->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), params), type);
+ return new (m_globalData) PropertyNode(m_globalData, *name, new (m_globalData) FuncExprNode(location, m_globalData->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), params), type);
}
- template <bool> PropertyNode* createGetterOrSetterProperty(JSGlobalData*, int lineNumber, PropertyNode::Type type, double name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
+ template <bool> PropertyNode* createGetterOrSetterProperty(JSGlobalData*, const JSTokenLocation& location, PropertyNode::Type type, double name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
{
- body->setLoc(bodyStartLine, bodyEndLine);
- return new (m_globalData) PropertyNode(m_globalData, name, new (m_globalData) FuncExprNode(lineNumber, m_globalData->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), params), type);
+ body->setLoc(bodyStartLine, bodyEndLine, location.column);
+ return new (m_globalData) PropertyNode(m_globalData, name, new (m_globalData) FuncExprNode(location, m_globalData->propertyNames->nullIdentifier, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), params), type);
}
ArgumentsNode* createArguments() { return new (m_globalData) ArgumentsNode(); }
ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_globalData) ArgumentsNode(args); }
- ArgumentListNode* createArgumentsList(int lineNumber, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(lineNumber, arg); }
- ArgumentListNode* createArgumentsList(int lineNumber, ArgumentListNode* args, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(lineNumber, args, arg); }
+ ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(location, arg); }
+ ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ArgumentListNode* args, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(location, args, arg); }
template <bool> PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type)
{
@@ -294,8 +294,8 @@ public:
return new (m_globalData) PropertyNode(m_globalData, *propertyName, node, type);
}
template <bool> PropertyNode* createProperty(JSGlobalData*, double propertyName, ExpressionNode* node, PropertyNode::Type type) { return new (m_globalData) PropertyNode(m_globalData, propertyName, node, type); }
- PropertyListNode* createPropertyList(int lineNumber, PropertyNode* property) { return new (m_globalData) PropertyListNode(lineNumber, property); }
- PropertyListNode* createPropertyList(int lineNumber, PropertyNode* property, PropertyListNode* tail) { return new (m_globalData) PropertyListNode(lineNumber, property, tail); }
+ PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property) { return new (m_globalData) PropertyListNode(location, property); }
+ PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property, PropertyListNode* tail) { return new (m_globalData) PropertyListNode(location, property, tail); }
ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(elisions, expr); }
ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(elems, elisions, expr); }
@@ -309,191 +309,191 @@ public:
void setUsesArguments(FunctionBodyNode* node) { node->setUsesArguments(); }
- StatementNode* createFuncDeclStatement(int lineNumber, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
+ StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
{
- FuncDeclNode* decl = new (m_globalData) FuncDeclNode(lineNumber, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
+ FuncDeclNode* decl = new (m_globalData) FuncDeclNode(location, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
if (*name == m_globalData->propertyNames->arguments)
usesArguments();
m_scope.m_funcDeclarations->data.append(decl->body());
- body->setLoc(bodyStartLine, bodyEndLine);
+ body->setLoc(bodyStartLine, bodyEndLine, location.column);
return decl;
}
- StatementNode* createBlockStatement(int lineNumber, JSC::SourceElements* elements, int startLine, int endLine)
+ StatementNode* createBlockStatement(const JSTokenLocation& location, JSC::SourceElements* elements, int startLine, int endLine)
{
- BlockNode* block = new (m_globalData) BlockNode(lineNumber, elements);
- block->setLoc(startLine, endLine);
+ BlockNode* block = new (m_globalData) BlockNode(location, elements);
+ block->setLoc(startLine, endLine, location.column);
return block;
}
- StatementNode* createExprStatement(int lineNumber, ExpressionNode* expr, int start, int end)
+ StatementNode* createExprStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
{
- ExprStatementNode* result = new (m_globalData) ExprStatementNode(lineNumber, expr);
- result->setLoc(start, end);
+ ExprStatementNode* result = new (m_globalData) ExprStatementNode(location, expr);
+ result->setLoc(start, end, location.column);
return result;
}
- StatementNode* createIfStatement(int lineNumber, ExpressionNode* condition, StatementNode* trueBlock, int start, int end)
+ StatementNode* createIfStatement(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* trueBlock, int start, int end)
{
- IfNode* result = new (m_globalData) IfNode(lineNumber, condition, trueBlock);
- result->setLoc(start, end);
+ IfNode* result = new (m_globalData) IfNode(location, condition, trueBlock);
+ result->setLoc(start, end, location.column);
return result;
}
- StatementNode* createIfStatement(int lineNumber, ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
+ StatementNode* createIfStatement(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
{
- IfNode* result = new (m_globalData) IfElseNode(lineNumber, condition, trueBlock, falseBlock);
- result->setLoc(start, end);
+ IfNode* result = new (m_globalData) IfElseNode(location, condition, trueBlock, falseBlock);
+ result->setLoc(start, end, location.column);
return result;
}
- StatementNode* createForLoop(int lineNumber, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, int start, int end)
+ StatementNode* createForLoop(const JSTokenLocation& location, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, int start, int end)
{
- ForNode* result = new (m_globalData) ForNode(lineNumber, initializer, condition, iter, statements);
+ ForNode* result = new (m_globalData) ForNode(location, initializer, condition, iter, statements);
result->setLoc(start, end);
return result;
}
- StatementNode* createForInLoop(int lineNumber, const Identifier* ident, ExpressionNode* initializer, ExpressionNode* iter, StatementNode* statements, int start, int divot, int end, int initStart, int initEnd, int startLine, int endLine)
+ StatementNode* createForInLoop(const JSTokenLocation& location, const Identifier* ident, ExpressionNode* initializer, ExpressionNode* iter, StatementNode* statements, int start, int divot, int end, int initStart, int initEnd, int startLine, int endLine)
{
- ForInNode* result = new (m_globalData) ForInNode(m_globalData, lineNumber, *ident, initializer, iter, statements, initStart, initStart - start, initEnd - initStart);
- result->setLoc(startLine, endLine);
+ ForInNode* result = new (m_globalData) ForInNode(m_globalData, location, *ident, initializer, iter, statements, initStart, initStart - start, initEnd - initStart);
+ result->setLoc(startLine, endLine, location.column);
setExceptionLocation(result, start, divot + 1, end);
return result;
}
- StatementNode* createForInLoop(int lineNumber, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, int eStart, int eDivot, int eEnd, int start, int end)
+ StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, int eStart, int eDivot, int eEnd, int start, int end)
{
- ForInNode* result = new (m_globalData) ForInNode(lineNumber, lhs, iter, statements);
- result->setLoc(start, end);
+ ForInNode* result = new (m_globalData) ForInNode(location, lhs, iter, statements);
+ result->setLoc(start, end, location.column);
setExceptionLocation(result, eStart, eDivot, eEnd);
return result;
}
- StatementNode* createEmptyStatement(int lineNumber) { return new (m_globalData) EmptyStatementNode(lineNumber); }
+ StatementNode* createEmptyStatement(const JSTokenLocation& location) { return new (m_globalData) EmptyStatementNode(location); }
- StatementNode* createVarStatement(int lineNumber, ExpressionNode* expr, int start, int end)
+ StatementNode* createVarStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
{
StatementNode* result;
if (!expr)
- result = new (m_globalData) EmptyStatementNode(lineNumber);
+ result = new (m_globalData) EmptyStatementNode(location);
else
- result = new (m_globalData) VarStatementNode(lineNumber, expr);
- result->setLoc(start, end);
+ result = new (m_globalData) VarStatementNode(location, expr);
+ result->setLoc(start, end, location.column);
return result;
}
- StatementNode* createReturnStatement(int lineNumber, ExpressionNode* expression, int eStart, int eEnd, int startLine, int endLine)
+ StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, int eStart, int eEnd, int startLine, int endLine)
{
- ReturnNode* result = new (m_globalData) ReturnNode(lineNumber, expression);
+ ReturnNode* result = new (m_globalData) ReturnNode(location, expression);
setExceptionLocation(result, eStart, eEnd, eEnd);
- result->setLoc(startLine, endLine);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createBreakStatement(int lineNumber, int eStart, int eEnd, int startLine, int endLine)
+ StatementNode* createBreakStatement(const JSTokenLocation& location, int eStart, int eEnd, int startLine, int endLine)
{
- BreakNode* result = new (m_globalData) BreakNode(m_globalData, lineNumber);
+ BreakNode* result = new (m_globalData) BreakNode(m_globalData, location);
setExceptionLocation(result, eStart, eEnd, eEnd);
- result->setLoc(startLine, endLine);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createBreakStatement(int lineNumber, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
+ StatementNode* createBreakStatement(const JSTokenLocation& location, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
{
- BreakNode* result = new (m_globalData) BreakNode(lineNumber, *ident);
+ BreakNode* result = new (m_globalData) BreakNode(location, *ident);
setExceptionLocation(result, eStart, eEnd, eEnd);
- result->setLoc(startLine, endLine);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createContinueStatement(int lineNumber, int eStart, int eEnd, int startLine, int endLine)
+ StatementNode* createContinueStatement(const JSTokenLocation& location, int eStart, int eEnd, int startLine, int endLine)
{
- ContinueNode* result = new (m_globalData) ContinueNode(m_globalData, lineNumber);
+ ContinueNode* result = new (m_globalData) ContinueNode(m_globalData, location);
setExceptionLocation(result, eStart, eEnd, eEnd);
- result->setLoc(startLine, endLine);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createContinueStatement(int lineNumber, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
+ StatementNode* createContinueStatement(const JSTokenLocation& location, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
{
- ContinueNode* result = new (m_globalData) ContinueNode(lineNumber, *ident);
+ ContinueNode* result = new (m_globalData) ContinueNode(location, *ident);
setExceptionLocation(result, eStart, eEnd, eEnd);
- result->setLoc(startLine, endLine);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createTryStatement(int lineNumber, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
+ StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier* ident, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
{
- TryNode* result = new (m_globalData) TryNode(lineNumber, tryBlock, *ident, catchBlock, finallyBlock);
+ TryNode* result = new (m_globalData) TryNode(location, tryBlock, *ident, catchBlock, finallyBlock);
if (catchBlock)
usesCatch();
- result->setLoc(startLine, endLine);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createSwitchStatement(int lineNumber, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine)
+ StatementNode* createSwitchStatement(const JSTokenLocation& location, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine)
{
CaseBlockNode* cases = new (m_globalData) CaseBlockNode(firstClauses, defaultClause, secondClauses);
- SwitchNode* result = new (m_globalData) SwitchNode(lineNumber, expr, cases);
- result->setLoc(startLine, endLine);
+ SwitchNode* result = new (m_globalData) SwitchNode(location, expr, cases);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createWhileStatement(int lineNumber, ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
+ StatementNode* createWhileStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
{
- WhileNode* result = new (m_globalData) WhileNode(lineNumber, expr, statement);
- result->setLoc(startLine, endLine);
+ WhileNode* result = new (m_globalData) WhileNode(location, expr, statement);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createDoWhileStatement(int lineNumber, StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
+ StatementNode* createDoWhileStatement(const JSTokenLocation& location, StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
{
- DoWhileNode* result = new (m_globalData) DoWhileNode(lineNumber, statement, expr);
- result->setLoc(startLine, endLine);
+ DoWhileNode* result = new (m_globalData) DoWhileNode(location, statement, expr);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createLabelStatement(int lineNumber, const Identifier* ident, StatementNode* statement, int start, int end)
+ StatementNode* createLabelStatement(const JSTokenLocation& location, const Identifier* ident, StatementNode* statement, int start, int end)
{
- LabelNode* result = new (m_globalData) LabelNode(lineNumber, *ident, statement);
+ LabelNode* result = new (m_globalData) LabelNode(location, *ident, statement);
setExceptionLocation(result, start, end, end);
return result;
}
- StatementNode* createWithStatement(int lineNumber, ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine)
+ StatementNode* createWithStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine)
{
usesWith();
- WithNode* result = new (m_globalData) WithNode(lineNumber, expr, statement, end, end - start);
- result->setLoc(startLine, endLine);
+ WithNode* result = new (m_globalData) WithNode(location, expr, statement, end, end - start);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createThrowStatement(int lineNumber, ExpressionNode* expr, int start, int end, int startLine, int endLine)
+ StatementNode* createThrowStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end, int startLine, int endLine)
{
- ThrowNode* result = new (m_globalData) ThrowNode(lineNumber, expr);
- result->setLoc(startLine, endLine);
+ ThrowNode* result = new (m_globalData) ThrowNode(location, expr);
+ result->setLoc(startLine, endLine, location.column);
setExceptionLocation(result, start, end, end);
return result;
}
- StatementNode* createDebugger(int lineNumber, int startLine, int endLine)
+ StatementNode* createDebugger(const JSTokenLocation& location, int startLine, int endLine)
{
- DebuggerStatementNode* result = new (m_globalData) DebuggerStatementNode(lineNumber);
- result->setLoc(startLine, endLine);
+ DebuggerStatementNode* result = new (m_globalData) DebuggerStatementNode(location);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- StatementNode* createConstStatement(int lineNumber, ConstDeclNode* decls, int startLine, int endLine)
+ StatementNode* createConstStatement(const JSTokenLocation& location, ConstDeclNode* decls, int startLine, int endLine)
{
- ConstStatementNode* result = new (m_globalData) ConstStatementNode(lineNumber, decls);
- result->setLoc(startLine, endLine);
+ ConstStatementNode* result = new (m_globalData) ConstStatementNode(location, decls);
+ result->setLoc(startLine, endLine, location.column);
return result;
}
- ConstDeclNode* appendConstDecl(int lineNumber, ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer)
+ ConstDeclNode* appendConstDecl(const JSTokenLocation& location, ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer)
{
- ConstDeclNode* result = new (m_globalData) ConstDeclNode(lineNumber, *name, initializer);
+ ConstDeclNode* result = new (m_globalData) ConstDeclNode(location, *name, initializer);
if (tail)
tail->m_next = result;
return result;
@@ -511,7 +511,7 @@ public:
m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs));
}
- ExpressionNode* combineCommaNodes(int lineNumber, ExpressionNode* list, ExpressionNode* init)
+ ExpressionNode* combineCommaNodes(const JSTokenLocation& location, ExpressionNode* list, ExpressionNode* init)
{
if (!list)
return init;
@@ -519,7 +519,7 @@ public:
static_cast<CommaNode*>(list)->append(init);
return list;
}
- return new (m_globalData) CommaNode(lineNumber, list, init);
+ return new (m_globalData) CommaNode(location, list, init);
}
int evalCount() const { return m_evalCount; }
@@ -547,10 +547,10 @@ public:
ASSERT(operandStackDepth >= 0);
m_binaryOperandStack.resize(m_binaryOperandStack.size() - amount);
}
- void appendBinaryOperation(int lineNumber, int& operandStackDepth, int&, const BinaryOperand& lhs, const BinaryOperand& rhs)
+ void appendBinaryOperation(const JSTokenLocation& location, int& operandStackDepth, int&, const BinaryOperand& lhs, const BinaryOperand& rhs)
{
operandStackDepth++;
- m_binaryOperandStack.append(std::make_pair(makeBinaryNode(lineNumber, m_binaryOperatorStack.last().first, lhs, rhs), BinaryOpInfo(lhs.second, rhs.second)));
+ m_binaryOperandStack.append(std::make_pair(makeBinaryNode(location, m_binaryOperatorStack.last().first, lhs, rhs), BinaryOpInfo(lhs.second, rhs.second)));
}
void operatorStackAppend(int& operatorStackDepth, int op, int precedence)
{
@@ -592,9 +592,9 @@ public:
m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op));
}
- ExpressionNode* createAssignment(int lineNumber, int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, int lastTokenEnd)
+ ExpressionNode* createAssignment(const JSTokenLocation& location, int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, int lastTokenEnd)
{
- ExpressionNode* result = makeAssignNode(lineNumber, m_assignmentInfoStack.last().m_node, m_assignmentInfoStack.last().m_op, rhs, m_assignmentInfoStack.last().m_initAssignments != initialAssignmentCount, m_assignmentInfoStack.last().m_initAssignments != currentAssignmentCount, m_assignmentInfoStack.last().m_start, m_assignmentInfoStack.last().m_divot + 1, lastTokenEnd);
+ ExpressionNode* result = makeAssignNode(location, m_assignmentInfoStack.last().m_node, m_assignmentInfoStack.last().m_op, rhs, m_assignmentInfoStack.last().m_initAssignments != initialAssignmentCount, m_assignmentInfoStack.last().m_initAssignments != currentAssignmentCount, m_assignmentInfoStack.last().m_start, m_assignmentInfoStack.last().m_divot + 1, lastTokenEnd);
m_assignmentInfoStack.removeLast();
assignmentStackDepth--;
return result;
@@ -635,9 +635,9 @@ private:
m_evalCount++;
m_scope.m_features |= EvalFeature;
}
- ExpressionNode* createNumber(int lineNumber, double d)
+ ExpressionNode* createNumber(const JSTokenLocation& location, double d)
{
- return new (m_globalData) NumberNode(lineNumber, d);
+ return new (m_globalData) NumberNode(location, d);
}
JSGlobalData* m_globalData;
@@ -650,33 +650,33 @@ private:
int m_evalCount;
};
-ExpressionNode* ASTBuilder::makeTypeOfNode(int lineNumber, ExpressionNode* expr)
+ExpressionNode* ASTBuilder::makeTypeOfNode(const JSTokenLocation& location, ExpressionNode* expr)
{
if (expr->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(expr);
- return new (m_globalData) TypeOfResolveNode(lineNumber, resolve->identifier());
+ return new (m_globalData) TypeOfResolveNode(location, resolve->identifier());
}
- return new (m_globalData) TypeOfValueNode(lineNumber, expr);
+ return new (m_globalData) TypeOfValueNode(location, expr);
}
-ExpressionNode* ASTBuilder::makeDeleteNode(int lineNumber, ExpressionNode* expr, int start, int divot, int end)
+ExpressionNode* ASTBuilder::makeDeleteNode(const JSTokenLocation& location, ExpressionNode* expr, int start, int divot, int end)
{
if (!expr->isLocation())
- return new (m_globalData) DeleteValueNode(lineNumber, expr);
+ return new (m_globalData) DeleteValueNode(location, expr);
if (expr->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(expr);
- return new (m_globalData) DeleteResolveNode(lineNumber, resolve->identifier(), divot, divot - start, end - divot);
+ return new (m_globalData) DeleteResolveNode(location, resolve->identifier(), divot, divot - start, end - divot);
}
if (expr->isBracketAccessorNode()) {
BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
- return new (m_globalData) DeleteBracketNode(lineNumber, bracket->base(), bracket->subscript(), divot, divot - start, end - divot);
+ return new (m_globalData) DeleteBracketNode(location, bracket->base(), bracket->subscript(), divot, divot - start, end - divot);
}
ASSERT(expr->isDotAccessorNode());
DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
- return new (m_globalData) DeleteDotNode(lineNumber, dot->base(), dot->identifier(), divot, divot - start, end - divot);
+ return new (m_globalData) DeleteDotNode(location, dot->base(), dot->identifier(), divot, divot - start, end - divot);
}
-ExpressionNode* ASTBuilder::makeNegateNode(int lineNumber, ExpressionNode* n)
+ExpressionNode* ASTBuilder::makeNegateNode(const JSTokenLocation& location, ExpressionNode* n)
{
if (n->isNumber()) {
NumberNode* numberNode = static_cast<NumberNode*>(n);
@@ -684,128 +684,128 @@ ExpressionNode* ASTBuilder::makeNegateNode(int lineNumber, ExpressionNode* n)
return numberNode;
}
- return new (m_globalData) NegateNode(lineNumber, n);
+ return new (m_globalData) NegateNode(location, n);
}
-ExpressionNode* ASTBuilder::makeBitwiseNotNode(int lineNumber, ExpressionNode* expr)
+ExpressionNode* ASTBuilder::makeBitwiseNotNode(const JSTokenLocation& location, ExpressionNode* expr)
{
if (expr->isNumber())
- return createNumber(lineNumber, ~toInt32(static_cast<NumberNode*>(expr)->value()));
- return new (m_globalData) BitwiseNotNode(lineNumber, expr);
+ return createNumber(location, ~toInt32(static_cast<NumberNode*>(expr)->value()));
+ return new (m_globalData) BitwiseNotNode(location, expr);
}
-ExpressionNode* ASTBuilder::makeMultNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeMultNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
expr1 = expr1->stripUnaryPlus();
expr2 = expr2->stripUnaryPlus();
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
+ return createNumber(location, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
- return new (m_globalData) UnaryPlusNode(lineNumber, expr2);
+ return new (m_globalData) UnaryPlusNode(location, expr2);
if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
- return new (m_globalData) UnaryPlusNode(lineNumber, expr1);
+ return new (m_globalData) UnaryPlusNode(location, expr1);
- return new (m_globalData) MultNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return new (m_globalData) MultNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeDivNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeDivNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
expr1 = expr1->stripUnaryPlus();
expr2 = expr2->stripUnaryPlus();
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
- return new (m_globalData) DivNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return createNumber(location, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
+ return new (m_globalData) DivNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeModNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeModNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
expr1 = expr1->stripUnaryPlus();
expr2 = expr2->stripUnaryPlus();
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, fmod(static_cast<NumberNode*>(expr1)->value(), static_cast<NumberNode*>(expr2)->value()));
- return new (m_globalData) ModNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return createNumber(location, fmod(static_cast<NumberNode*>(expr1)->value(), static_cast<NumberNode*>(expr2)->value()));
+ return new (m_globalData) ModNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeAddNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeAddNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value());
- return new (m_globalData) AddNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return createNumber(location, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value());
+ return new (m_globalData) AddNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeSubNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeSubNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
expr1 = expr1->stripUnaryPlus();
expr2 = expr2->stripUnaryPlus();
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
- return new (m_globalData) SubNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return createNumber(location, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
+ return new (m_globalData) SubNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeLeftShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeLeftShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
- return new (m_globalData) LeftShiftNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
+ return new (m_globalData) LeftShiftNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeRightShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeRightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
- return new (m_globalData) RightShiftNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
+ return new (m_globalData) RightShiftNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeURightShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeURightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, toUInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
- return new (m_globalData) UnsignedRightShiftNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return createNumber(location, toUInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
+ return new (m_globalData) UnsignedRightShiftNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeBitOrNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeBitOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, toInt32(static_cast<NumberNode*>(expr1)->value()) | toInt32(static_cast<NumberNode*>(expr2)->value()));
- return new (m_globalData) BitOrNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) | toInt32(static_cast<NumberNode*>(expr2)->value()));
+ return new (m_globalData) BitOrNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeBitAndNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeBitAndNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, toInt32(static_cast<NumberNode*>(expr1)->value()) & toInt32(static_cast<NumberNode*>(expr2)->value()));
- return new (m_globalData) BitAndNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) & toInt32(static_cast<NumberNode*>(expr2)->value()));
+ return new (m_globalData) BitAndNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeBitXOrNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ExpressionNode* ASTBuilder::makeBitXOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
{
if (expr1->isNumber() && expr2->isNumber())
- return createNumber(lineNumber, toInt32(static_cast<NumberNode*>(expr1)->value()) ^ toInt32(static_cast<NumberNode*>(expr2)->value()));
- return new (m_globalData) BitXOrNode(lineNumber, expr1, expr2, rightHasAssignments);
+ return createNumber(location, toInt32(static_cast<NumberNode*>(expr1)->value()) ^ toInt32(static_cast<NumberNode*>(expr2)->value()));
+ return new (m_globalData) BitXOrNode(location, expr1, expr2, rightHasAssignments);
}
-ExpressionNode* ASTBuilder::makeFunctionCallNode(int lineNumber, ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end)
+ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end)
{
if (!func->isLocation())
- return new (m_globalData) FunctionCallValueNode(lineNumber, func, args, divot, divot - start, end - divot);
+ return new (m_globalData) FunctionCallValueNode(location, func, args, divot, divot - start, end - divot);
if (func->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(func);
const Identifier& identifier = resolve->identifier();
if (identifier == m_globalData->propertyNames->eval) {
usesEval();
- return new (m_globalData) EvalFunctionCallNode(lineNumber, args, divot, divot - start, end - divot);
+ return new (m_globalData) EvalFunctionCallNode(location, args, divot, divot - start, end - divot);
}
- return new (m_globalData) FunctionCallResolveNode(lineNumber, identifier, args, divot, divot - start, end - divot);
+ return new (m_globalData) FunctionCallResolveNode(location, identifier, args, divot, divot - start, end - divot);
}
if (func->isBracketAccessorNode()) {
BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func);
- FunctionCallBracketNode* node = new (m_globalData) FunctionCallBracketNode(lineNumber, bracket->base(), bracket->subscript(), args, divot, divot - start, end - divot);
+ FunctionCallBracketNode* node = new (m_globalData) FunctionCallBracketNode(location, bracket->base(), bracket->subscript(), args, divot, divot - start, end - divot);
node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
return node;
}
@@ -813,118 +813,118 @@ ExpressionNode* ASTBuilder::makeFunctionCallNode(int lineNumber, ExpressionNode*
DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
FunctionCallDotNode* node;
if (dot->identifier() == m_globalData->propertyNames->call)
- node = new (m_globalData) CallFunctionCallDotNode(lineNumber, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
+ node = new (m_globalData) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
else if (dot->identifier() == m_globalData->propertyNames->apply)
- node = new (m_globalData) ApplyFunctionCallDotNode(lineNumber, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
+ node = new (m_globalData) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
else
- node = new (m_globalData) FunctionCallDotNode(lineNumber, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
+ node = new (m_globalData) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
node->setSubexpressionInfo(dot->divot(), dot->endOffset());
return node;
}
-ExpressionNode* ASTBuilder::makeBinaryNode(int lineNumber, int token, pair<ExpressionNode*, BinaryOpInfo> lhs, pair<ExpressionNode*, BinaryOpInfo> rhs)
+ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int token, pair<ExpressionNode*, BinaryOpInfo> lhs, pair<ExpressionNode*, BinaryOpInfo> rhs)
{
switch (token) {
case OR:
- return new (m_globalData) LogicalOpNode(lineNumber, lhs.first, rhs.first, OpLogicalOr);
+ return new (m_globalData) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalOr);
case AND:
- return new (m_globalData) LogicalOpNode(lineNumber, lhs.first, rhs.first, OpLogicalAnd);
+ return new (m_globalData) LogicalOpNode(location, lhs.first, rhs.first, OpLogicalAnd);
case BITOR:
- return makeBitOrNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeBitOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case BITXOR:
- return makeBitXOrNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeBitXOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case BITAND:
- return makeBitAndNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeBitAndNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case EQEQ:
- return new (m_globalData) EqualNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_globalData) EqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case NE:
- return new (m_globalData) NotEqualNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_globalData) NotEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case STREQ:
- return new (m_globalData) StrictEqualNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_globalData) StrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case STRNEQ:
- return new (m_globalData) NotStrictEqualNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_globalData) NotStrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case LT:
- return new (m_globalData) LessNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_globalData) LessNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case GT:
- return new (m_globalData) GreaterNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_globalData) GreaterNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case LE:
- return new (m_globalData) LessEqNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_globalData) LessEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case GE:
- return new (m_globalData) GreaterEqNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return new (m_globalData) GreaterEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case INSTANCEOF: {
- InstanceOfNode* node = new (m_globalData) InstanceOfNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ InstanceOfNode* node = new (m_globalData) InstanceOfNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
return node;
}
case INTOKEN: {
- InNode* node = new (m_globalData) InNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ InNode* node = new (m_globalData) InNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
return node;
}
case LSHIFT:
- return makeLeftShiftNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeLeftShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case RSHIFT:
- return makeRightShiftNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeRightShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case URSHIFT:
- return makeURightShiftNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeURightShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case PLUS:
- return makeAddNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeAddNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case MINUS:
- return makeSubNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeSubNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case TIMES:
- return makeMultNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeMultNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case DIVIDE:
- return makeDivNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeDivNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
case MOD:
- return makeModNode(lineNumber, lhs.first, rhs.first, rhs.second.hasAssignment);
+ return makeModNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
}
CRASH();
return 0;
}
-ExpressionNode* ASTBuilder::makeAssignNode(int lineNumber, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end)
+ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end)
{
if (!loc->isLocation())
- return new (m_globalData) AssignErrorNode(lineNumber, divot, divot - start, end - divot);
+ return new (m_globalData) AssignErrorNode(location, divot, divot - start, end - divot);
if (loc->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(loc);
if (op == OpEqual) {
if (expr->isFuncExprNode())
static_cast<FuncExprNode*>(expr)->body()->setInferredName(resolve->identifier());
- AssignResolveNode* node = new (m_globalData) AssignResolveNode(lineNumber, resolve->identifier(), expr);
+ AssignResolveNode* node = new (m_globalData) AssignResolveNode(location, resolve->identifier(), expr);
setExceptionLocation(node, start, divot, end);
return node;
}
- return new (m_globalData) ReadModifyResolveNode(lineNumber, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
+ return new (m_globalData) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
}
if (loc->isBracketAccessorNode()) {
BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
if (op == OpEqual)
- return new (m_globalData) AssignBracketNode(lineNumber, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot());
- ReadModifyBracketNode* node = new (m_globalData) ReadModifyBracketNode(lineNumber, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot);
+ return new (m_globalData) AssignBracketNode(location, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot());
+ ReadModifyBracketNode* node = new (m_globalData) ReadModifyBracketNode(location, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot);
node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
return node;
}
@@ -933,55 +933,55 @@ ExpressionNode* ASTBuilder::makeAssignNode(int lineNumber, ExpressionNode* loc,
if (op == OpEqual) {
if (expr->isFuncExprNode())
static_cast<FuncExprNode*>(expr)->body()->setInferredName(dot->identifier());
- return new (m_globalData) AssignDotNode(lineNumber, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot());
+ return new (m_globalData) AssignDotNode(location, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot());
}
- ReadModifyDotNode* node = new (m_globalData) ReadModifyDotNode(lineNumber, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
+ ReadModifyDotNode* node = new (m_globalData) ReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
node->setSubexpressionInfo(dot->divot(), dot->endOffset());
return node;
}
-ExpressionNode* ASTBuilder::makePrefixNode(int lineNumber, ExpressionNode* expr, Operator op, int start, int divot, int end)
+ExpressionNode* ASTBuilder::makePrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, int start, int divot, int end)
{
if (!expr->isLocation())
- return new (m_globalData) PrefixErrorNode(lineNumber, op, divot, divot - start, end - divot);
+ return new (m_globalData) PrefixErrorNode(location, op, divot, divot - start, end - divot);
if (expr->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(expr);
- return new (m_globalData) PrefixResolveNode(lineNumber, resolve->identifier(), op, divot, divot - start, end - divot);
+ return new (m_globalData) PrefixResolveNode(location, resolve->identifier(), op, divot, divot - start, end - divot);
}
if (expr->isBracketAccessorNode()) {
BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
- PrefixBracketNode* node = new (m_globalData) PrefixBracketNode(lineNumber, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
+ PrefixBracketNode* node = new (m_globalData) PrefixBracketNode(location, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
node->setSubexpressionInfo(bracket->divot(), bracket->startOffset());
return node;
}
ASSERT(expr->isDotAccessorNode());
DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
- PrefixDotNode* node = new (m_globalData) PrefixDotNode(lineNumber, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
+ PrefixDotNode* node = new (m_globalData) PrefixDotNode(location, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
node->setSubexpressionInfo(dot->divot(), dot->startOffset());
return node;
}
-ExpressionNode* ASTBuilder::makePostfixNode(int lineNumber, ExpressionNode* expr, Operator op, int start, int divot, int end)
+ExpressionNode* ASTBuilder::makePostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, int start, int divot, int end)
{
if (!expr->isLocation())
- return new (m_globalData) PostfixErrorNode(lineNumber, op, divot, divot - start, end - divot);
+ return new (m_globalData) PostfixErrorNode(location, op, divot, divot - start, end - divot);
if (expr->isResolveNode()) {
ResolveNode* resolve = static_cast<ResolveNode*>(expr);
- return new (m_globalData) PostfixResolveNode(lineNumber, resolve->identifier(), op, divot, divot - start, end - divot);
+ return new (m_globalData) PostfixResolveNode(location, resolve->identifier(), op, divot, divot - start, end - divot);
}
if (expr->isBracketAccessorNode()) {
BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
- PostfixBracketNode* node = new (m_globalData) PostfixBracketNode(lineNumber, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
+ PostfixBracketNode* node = new (m_globalData) PostfixBracketNode(location, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
return node;
}
ASSERT(expr->isDotAccessorNode());
DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
- PostfixDotNode* node = new (m_globalData) PostfixDotNode(lineNumber, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
+ PostfixDotNode* node = new (m_globalData) PostfixDotNode(location, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
node->setSubexpressionInfo(dot->divot(), dot->endOffset());
return node;
}
diff --git a/Source/JavaScriptCore/parser/Lexer.cpp b/Source/JavaScriptCore/parser/Lexer.cpp
index 3b020f4f2..2a8a8dc9e 100644
--- a/Source/JavaScriptCore/parser/Lexer.cpp
+++ b/Source/JavaScriptCore/parser/Lexer.cpp
@@ -417,6 +417,7 @@ void Lexer<T>::setCode(const SourceCode& source, ParserArena* arena)
m_codeEnd = m_codeStart + source.endOffset();
m_error = false;
m_atLineStart = true;
+ m_columnNumber = 0;
m_lexErrorMessage = UString();
m_buffer8.reserveInitialCapacity(initialReadBufferCapacity);
@@ -433,6 +434,7 @@ template <typename T>
template <int shiftAmount> ALWAYS_INLINE void Lexer<T>::internalShift()
{
m_code += shiftAmount;
+ m_columnNumber += shiftAmount;
m_current = *m_code;
}
@@ -444,6 +446,7 @@ ALWAYS_INLINE void Lexer<T>::shift()
++m_code;
if (LIKELY(m_code < m_codeEnd))
m_current = *m_code;
+ ++m_columnNumber;
}
template <typename T>
@@ -1183,7 +1186,7 @@ bool Lexer<T>::nextTokenIsColon()
}
template <typename T>
-JSTokenType Lexer<T>::lex(JSTokenData* tokenData, JSTokenInfo* tokenInfo, unsigned lexerFlags, bool strictMode)
+JSTokenType Lexer<T>::lex(JSTokenData* tokenData, JSTokenLocation* tokenLocation, unsigned lexerFlags, bool strictMode)
{
ASSERT(!m_error);
ASSERT(m_buffer8.isEmpty());
@@ -1199,7 +1202,8 @@ start:
if (atEnd())
return EOFTOK;
- tokenInfo->startOffset = currentOffset();
+ tokenLocation->startOffset = currentOffset();
+ tokenLocation->column = m_columnNumber;
CharacterType type;
if (LIKELY(isLatin1(m_current)))
@@ -1522,6 +1526,7 @@ inNumberAfterDecimalPoint:
shiftLineTerminator();
m_atLineStart = true;
m_terminator = true;
+ m_columnNumber = 0;
goto start;
case CharacterInvalid:
m_lexErrorMessage = invalidCharacterMessage();
@@ -1544,6 +1549,7 @@ inSingleLineComment:
shiftLineTerminator();
m_atLineStart = true;
m_terminator = true;
+ m_columnNumber = 0;
if (!lastTokenWasRestrKeyword())
goto start;
@@ -1551,15 +1557,15 @@ inSingleLineComment:
// Fall through into returnToken.
returnToken:
- tokenInfo->line = m_lineNumber;
- tokenInfo->endOffset = currentOffset();
+ tokenLocation->line = m_lineNumber;
+ tokenLocation->endOffset = currentOffset();
m_lastToken = token;
return token;
returnError:
m_error = true;
- tokenInfo->line = m_lineNumber;
- tokenInfo->endOffset = currentOffset();
+ tokenLocation->line = m_lineNumber;
+ tokenLocation->endOffset = currentOffset();
return ERRORTOK;
}
diff --git a/Source/JavaScriptCore/parser/Lexer.h b/Source/JavaScriptCore/parser/Lexer.h
index 41f1f8553..1ac832a2c 100644
--- a/Source/JavaScriptCore/parser/Lexer.h
+++ b/Source/JavaScriptCore/parser/Lexer.h
@@ -87,9 +87,10 @@ public:
void setIsReparsing() { m_isReparsing = true; }
bool isReparsing() const { return m_isReparsing; }
- JSTokenType lex(JSTokenData*, JSTokenInfo*, unsigned, bool strictMode);
+ JSTokenType lex(JSTokenData*, JSTokenLocation*, unsigned, bool strictMode);
bool nextTokenIsColon();
int lineNumber() const { return m_lineNumber; }
+ int currentColumnNumber() const { return m_columnNumber; }
void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; }
int lastLineNumber() const { return m_lastLineNumber; }
bool prevTerminator() const { return m_terminator; }
@@ -120,7 +121,7 @@ public:
SourceProvider* sourceProvider() const { return m_source->provider(); }
- JSTokenType lexExpectIdentifier(JSTokenData*, JSTokenInfo*, unsigned, bool strictMode);
+ JSTokenType lexExpectIdentifier(JSTokenData*, JSTokenLocation*, unsigned, bool strictMode);
private:
void record8(int);
@@ -166,6 +167,7 @@ private:
int m_lineNumber;
int m_lastLineNumber;
+ int m_columnNumber;
Vector<LChar> m_buffer8;
Vector<UChar> m_buffer16;
@@ -257,7 +259,7 @@ ALWAYS_INLINE const Identifier* Lexer<T>::makeIdentifierLCharFromUChar(const UCh
}
template <typename T>
-ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSTokenData* tokenData, JSTokenInfo* tokenInfo, unsigned lexerFlags, bool strictMode)
+ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSTokenData* tokenData, JSTokenLocation* tokenLocation, unsigned lexerFlags, bool strictMode)
{
ASSERT((lexerFlags & LexerFlagsIgnoreReservedWords));
const T* start = m_code;
@@ -285,20 +287,22 @@ ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSTokenData* tokenData,
m_current = 0;
m_code = ptr;
+ m_columnNumber = m_columnNumber + (m_code - start);
// Create the identifier if needed
if (lexerFlags & LexexFlagsDontBuildKeywords)
tokenData->ident = 0;
else
tokenData->ident = makeIdentifier(start, ptr - start);
- tokenInfo->line = m_lineNumber;
- tokenInfo->startOffset = start - m_codeStart;
- tokenInfo->endOffset = currentOffset();
+ tokenLocation->line = m_lineNumber;
+ tokenLocation->startOffset = start - m_codeStart;
+ tokenLocation->endOffset = currentOffset();
+ tokenLocation->column = m_columnNumber;
m_lastToken = IDENT;
return IDENT;
slowCase:
- return lex(tokenData, tokenInfo, lexerFlags, strictMode);
+ return lex(tokenData, tokenLocation, lexerFlags, strictMode);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/parser/NodeConstructors.h b/Source/JavaScriptCore/parser/NodeConstructors.h
index be50eeafe..43d1e17c6 100644
--- a/Source/JavaScriptCore/parser/NodeConstructors.h
+++ b/Source/JavaScriptCore/parser/NodeConstructors.h
@@ -42,60 +42,61 @@ namespace JSC {
globalData->parserArena->derefWithArena(adoptRef(this));
}
- inline Node::Node(int lineNumber)
- : m_lineNumber(lineNumber)
+ inline Node::Node(const JSTokenLocation& location)
+ : m_lineNumber(location.line)
+ , m_columnNumber(location.column)
{
}
- inline ExpressionNode::ExpressionNode(int lineNumber, ResultType resultType)
- : Node(lineNumber)
+ inline ExpressionNode::ExpressionNode(const JSTokenLocation& location, ResultType resultType)
+ : Node(location)
, m_resultType(resultType)
{
}
- inline StatementNode::StatementNode(int lineNumber)
- : Node(lineNumber)
+ inline StatementNode::StatementNode(const JSTokenLocation& location)
+ : Node(location)
, m_lastLine(-1)
{
}
- inline NullNode::NullNode(int lineNumber)
- : ExpressionNode(lineNumber, ResultType::nullType())
+ inline NullNode::NullNode(const JSTokenLocation& location)
+ : ExpressionNode(location, ResultType::nullType())
{
}
- inline BooleanNode::BooleanNode(int lineNumber, bool value)
- : ExpressionNode(lineNumber, ResultType::booleanType())
+ inline BooleanNode::BooleanNode(const JSTokenLocation& location, bool value)
+ : ExpressionNode(location, ResultType::booleanType())
, m_value(value)
{
}
- inline NumberNode::NumberNode(int lineNumber, double value)
- : ExpressionNode(lineNumber, ResultType::numberType())
+ inline NumberNode::NumberNode(const JSTokenLocation& location, double value)
+ : ExpressionNode(location, ResultType::numberType())
, m_value(value)
{
}
- inline StringNode::StringNode(int lineNumber, const Identifier& value)
- : ExpressionNode(lineNumber, ResultType::stringType())
+ inline StringNode::StringNode(const JSTokenLocation& location, const Identifier& value)
+ : ExpressionNode(location, ResultType::stringType())
, m_value(value)
{
}
- inline RegExpNode::RegExpNode(int lineNumber, const Identifier& pattern, const Identifier& flags)
- : ExpressionNode(lineNumber)
+ inline RegExpNode::RegExpNode(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags)
+ : ExpressionNode(location)
, m_pattern(pattern)
, m_flags(flags)
{
}
- inline ThisNode::ThisNode(int lineNumber)
- : ExpressionNode(lineNumber)
+ inline ThisNode::ThisNode(const JSTokenLocation& location)
+ : ExpressionNode(location)
{
}
- inline ResolveNode::ResolveNode(int lineNumber, const Identifier& ident, int startOffset)
- : ExpressionNode(lineNumber)
+ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifier& ident, int startOffset)
+ : ExpressionNode(location)
, m_ident(ident)
, m_startOffset(startOffset)
{
@@ -116,24 +117,24 @@ namespace JSC {
l->m_next = this;
}
- inline ArrayNode::ArrayNode(int lineNumber, int elision)
- : ExpressionNode(lineNumber)
+ inline ArrayNode::ArrayNode(const JSTokenLocation& location, int elision)
+ : ExpressionNode(location)
, m_element(0)
, m_elision(elision)
, m_optional(true)
{
}
- inline ArrayNode::ArrayNode(int lineNumber, ElementNode* element)
- : ExpressionNode(lineNumber)
+ inline ArrayNode::ArrayNode(const JSTokenLocation& location, ElementNode* element)
+ : ExpressionNode(location)
, m_element(element)
, m_elision(0)
, m_optional(false)
{
}
- inline ArrayNode::ArrayNode(int lineNumber, int elision, ElementNode* element)
- : ExpressionNode(lineNumber)
+ inline ArrayNode::ArrayNode(const JSTokenLocation& location, int elision, ElementNode* element)
+ : ExpressionNode(location)
, m_element(element)
, m_elision(elision)
, m_optional(true)
@@ -154,57 +155,57 @@ namespace JSC {
{
}
- inline PropertyListNode::PropertyListNode(int lineNumber, PropertyNode* node)
- : Node(lineNumber)
+ inline PropertyListNode::PropertyListNode(const JSTokenLocation& location, PropertyNode* node)
+ : Node(location)
, m_node(node)
, m_next(0)
{
}
- inline PropertyListNode::PropertyListNode(int lineNumber, PropertyNode* node, PropertyListNode* list)
- : Node(lineNumber)
+ inline PropertyListNode::PropertyListNode(const JSTokenLocation& location, PropertyNode* node, PropertyListNode* list)
+ : Node(location)
, m_node(node)
, m_next(0)
{
list->m_next = this;
}
- inline ObjectLiteralNode::ObjectLiteralNode(int lineNumber)
- : ExpressionNode(lineNumber)
+ inline ObjectLiteralNode::ObjectLiteralNode(const JSTokenLocation& location)
+ : ExpressionNode(location)
, m_list(0)
{
}
- inline ObjectLiteralNode::ObjectLiteralNode(int lineNumber, PropertyListNode* list)
- : ExpressionNode(lineNumber)
+ inline ObjectLiteralNode::ObjectLiteralNode(const JSTokenLocation& location, PropertyListNode* list)
+ : ExpressionNode(location)
, m_list(list)
{
}
- inline BracketAccessorNode::BracketAccessorNode(int lineNumber, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments)
- : ExpressionNode(lineNumber)
+ inline BracketAccessorNode::BracketAccessorNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments)
+ : ExpressionNode(location)
, m_base(base)
, m_subscript(subscript)
, m_subscriptHasAssignments(subscriptHasAssignments)
{
}
- inline DotAccessorNode::DotAccessorNode(int lineNumber, ExpressionNode* base, const Identifier& ident)
- : ExpressionNode(lineNumber)
+ inline DotAccessorNode::DotAccessorNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident)
+ : ExpressionNode(location)
, m_base(base)
, m_ident(ident)
{
}
- inline ArgumentListNode::ArgumentListNode(int lineNumber, ExpressionNode* expr)
- : Node(lineNumber)
+ inline ArgumentListNode::ArgumentListNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : Node(location)
, m_next(0)
, m_expr(expr)
{
}
- inline ArgumentListNode::ArgumentListNode(int lineNumber, ArgumentListNode* listNode, ExpressionNode* expr)
- : Node(lineNumber)
+ inline ArgumentListNode::ArgumentListNode(const JSTokenLocation& location, ArgumentListNode* listNode, ExpressionNode* expr)
+ : Node(location)
, m_next(0)
, m_expr(expr)
{
@@ -221,45 +222,45 @@ namespace JSC {
{
}
- inline NewExprNode::NewExprNode(int lineNumber, ExpressionNode* expr)
- : ExpressionNode(lineNumber)
+ inline NewExprNode::NewExprNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : ExpressionNode(location)
, m_expr(expr)
, m_args(0)
{
}
- inline NewExprNode::NewExprNode(int lineNumber, ExpressionNode* expr, ArgumentsNode* args)
- : ExpressionNode(lineNumber)
+ inline NewExprNode::NewExprNode(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* args)
+ : ExpressionNode(location)
, m_expr(expr)
, m_args(args)
{
}
- inline EvalFunctionCallNode::EvalFunctionCallNode(int lineNumber, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline EvalFunctionCallNode::EvalFunctionCallNode(const JSTokenLocation& location, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_args(args)
{
}
- inline FunctionCallValueNode::FunctionCallValueNode(int lineNumber, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline FunctionCallValueNode::FunctionCallValueNode(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_expr(expr)
, m_args(args)
{
}
- inline FunctionCallResolveNode::FunctionCallResolveNode(int lineNumber, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline FunctionCallResolveNode::FunctionCallResolveNode(const JSTokenLocation& location, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_ident(ident)
, m_args(args)
{
}
- inline FunctionCallBracketNode::FunctionCallBracketNode(int lineNumber, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline FunctionCallBracketNode::FunctionCallBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableSubExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_subscript(subscript)
@@ -267,8 +268,8 @@ namespace JSC {
{
}
- inline FunctionCallDotNode::FunctionCallDotNode(int lineNumber, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline FunctionCallDotNode::FunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableSubExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_ident(ident)
@@ -276,31 +277,31 @@ namespace JSC {
{
}
- inline CallFunctionCallDotNode::CallFunctionCallDotNode(int lineNumber, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
- : FunctionCallDotNode(lineNumber, base, ident, args, divot, startOffset, endOffset)
+ inline CallFunctionCallDotNode::CallFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : FunctionCallDotNode(location, base, ident, args, divot, startOffset, endOffset)
{
}
- inline ApplyFunctionCallDotNode::ApplyFunctionCallDotNode(int lineNumber, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
- : FunctionCallDotNode(lineNumber, base, ident, args, divot, startOffset, endOffset)
+ inline ApplyFunctionCallDotNode::ApplyFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : FunctionCallDotNode(location, base, ident, args, divot, startOffset, endOffset)
{
}
- inline PrePostResolveNode::PrePostResolveNode(int lineNumber, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber, ResultType::numberType()) // could be reusable for pre?
+ inline PrePostResolveNode::PrePostResolveNode(const JSTokenLocation& location, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location, ResultType::numberType()) // could be reusable for pre?
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_ident(ident)
{
}
- inline PostfixResolveNode::PostfixResolveNode(int lineNumber, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
- : PrePostResolveNode(lineNumber, ident, divot, startOffset, endOffset)
+ inline PostfixResolveNode::PostfixResolveNode(const JSTokenLocation& location, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : PrePostResolveNode(location, ident, divot, startOffset, endOffset)
, m_operator(oper)
{
}
- inline PostfixBracketNode::PostfixBracketNode(int lineNumber, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline PostfixBracketNode::PostfixBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableSubExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_subscript(subscript)
@@ -308,8 +309,8 @@ namespace JSC {
{
}
- inline PostfixDotNode::PostfixDotNode(int lineNumber, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline PostfixDotNode::PostfixDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableSubExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_ident(ident)
@@ -317,68 +318,68 @@ namespace JSC {
{
}
- inline PostfixErrorNode::PostfixErrorNode(int lineNumber, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline PostfixErrorNode::PostfixErrorNode(const JSTokenLocation& location, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableSubExpressionData(divot, startOffset, endOffset)
, m_operator(oper)
{
}
- inline DeleteResolveNode::DeleteResolveNode(int lineNumber, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline DeleteResolveNode::DeleteResolveNode(const JSTokenLocation& location, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_ident(ident)
{
}
- inline DeleteBracketNode::DeleteBracketNode(int lineNumber, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline DeleteBracketNode::DeleteBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_subscript(subscript)
{
}
- inline DeleteDotNode::DeleteDotNode(int lineNumber, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline DeleteDotNode::DeleteDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_ident(ident)
{
}
- inline DeleteValueNode::DeleteValueNode(int lineNumber, ExpressionNode* expr)
- : ExpressionNode(lineNumber)
+ inline DeleteValueNode::DeleteValueNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : ExpressionNode(location)
, m_expr(expr)
{
}
- inline VoidNode::VoidNode(int lineNumber, ExpressionNode* expr)
- : ExpressionNode(lineNumber)
+ inline VoidNode::VoidNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : ExpressionNode(location)
, m_expr(expr)
{
}
- inline TypeOfResolveNode::TypeOfResolveNode(int lineNumber, const Identifier& ident)
- : ExpressionNode(lineNumber, ResultType::stringType())
+ inline TypeOfResolveNode::TypeOfResolveNode(const JSTokenLocation& location, const Identifier& ident)
+ : ExpressionNode(location, ResultType::stringType())
, m_ident(ident)
{
}
- inline TypeOfValueNode::TypeOfValueNode(int lineNumber, ExpressionNode* expr)
- : ExpressionNode(lineNumber, ResultType::stringType())
+ inline TypeOfValueNode::TypeOfValueNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : ExpressionNode(location, ResultType::stringType())
, m_expr(expr)
{
}
- inline PrefixResolveNode::PrefixResolveNode(int lineNumber, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
- : PrePostResolveNode(lineNumber, ident, divot, startOffset, endOffset)
+ inline PrefixResolveNode::PrefixResolveNode(const JSTokenLocation& location, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : PrePostResolveNode(location, ident, divot, startOffset, endOffset)
, m_operator(oper)
{
}
- inline PrefixBracketNode::PrefixBracketNode(int lineNumber, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline PrefixBracketNode::PrefixBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_subscript(subscript)
@@ -386,8 +387,8 @@ namespace JSC {
{
}
- inline PrefixDotNode::PrefixDotNode(int lineNumber, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline PrefixDotNode::PrefixDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_ident(ident)
@@ -395,43 +396,43 @@ namespace JSC {
{
}
- inline PrefixErrorNode::PrefixErrorNode(int lineNumber, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline PrefixErrorNode::PrefixErrorNode(const JSTokenLocation& location, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_operator(oper)
{
}
- inline UnaryOpNode::UnaryOpNode(int lineNumber, ResultType type, ExpressionNode* expr, OpcodeID opcodeID)
- : ExpressionNode(lineNumber, type)
+ inline UnaryOpNode::UnaryOpNode(const JSTokenLocation& location, ResultType type, ExpressionNode* expr, OpcodeID opcodeID)
+ : ExpressionNode(location, type)
, m_expr(expr)
, m_opcodeID(opcodeID)
{
}
- inline UnaryPlusNode::UnaryPlusNode(int lineNumber, ExpressionNode* expr)
- : UnaryOpNode(lineNumber, ResultType::numberType(), expr, op_to_jsnumber)
+ inline UnaryPlusNode::UnaryPlusNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : UnaryOpNode(location, ResultType::numberType(), expr, op_to_jsnumber)
{
}
- inline NegateNode::NegateNode(int lineNumber, ExpressionNode* expr)
- : UnaryOpNode(lineNumber, ResultType::numberType(), expr, op_negate)
+ inline NegateNode::NegateNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : UnaryOpNode(location, ResultType::numberType(), expr, op_negate)
{
}
- inline BitwiseNotNode::BitwiseNotNode(int lineNumber, ExpressionNode* expr)
- : ExpressionNode(lineNumber, ResultType::forBitOp())
+ inline BitwiseNotNode::BitwiseNotNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : ExpressionNode(location, ResultType::forBitOp())
, m_expr(expr)
{
}
- inline LogicalNotNode::LogicalNotNode(int lineNumber, ExpressionNode* expr)
- : UnaryOpNode(lineNumber, ResultType::booleanType(), expr, op_not)
+ inline LogicalNotNode::LogicalNotNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : UnaryOpNode(location, ResultType::booleanType(), expr, op_not)
{
}
- inline BinaryOpNode::BinaryOpNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
- : ExpressionNode(lineNumber)
+ inline BinaryOpNode::BinaryOpNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
+ : ExpressionNode(location)
, m_expr1(expr1)
, m_expr2(expr2)
, m_opcodeID(opcodeID)
@@ -439,8 +440,8 @@ namespace JSC {
{
}
- inline BinaryOpNode::BinaryOpNode(int lineNumber, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
- : ExpressionNode(lineNumber, type)
+ inline BinaryOpNode::BinaryOpNode(const JSTokenLocation& location, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
+ : ExpressionNode(location, type)
, m_expr1(expr1)
, m_expr2(expr2)
, m_opcodeID(opcodeID)
@@ -448,140 +449,140 @@ namespace JSC {
{
}
- inline MultNode::MultNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_mul, rightHasAssignments)
+ inline MultNode::MultNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::numberType(), expr1, expr2, op_mul, rightHasAssignments)
{
}
- inline DivNode::DivNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_div, rightHasAssignments)
+ inline DivNode::DivNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::numberType(), expr1, expr2, op_div, rightHasAssignments)
{
}
- inline ModNode::ModNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_mod, rightHasAssignments)
+ inline ModNode::ModNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::numberType(), expr1, expr2, op_mod, rightHasAssignments)
{
}
- inline AddNode::AddNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::forAdd(expr1->resultDescriptor(), expr2->resultDescriptor()), expr1, expr2, op_add, rightHasAssignments)
+ inline AddNode::AddNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::forAdd(expr1->resultDescriptor(), expr2->resultDescriptor()), expr1, expr2, op_add, rightHasAssignments)
{
}
- inline SubNode::SubNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_sub, rightHasAssignments)
+ inline SubNode::SubNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::numberType(), expr1, expr2, op_sub, rightHasAssignments)
{
}
- inline LeftShiftNode::LeftShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::forBitOp(), expr1, expr2, op_lshift, rightHasAssignments)
+ inline LeftShiftNode::LeftShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::forBitOp(), expr1, expr2, op_lshift, rightHasAssignments)
{
}
- inline RightShiftNode::RightShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::forBitOp(), expr1, expr2, op_rshift, rightHasAssignments)
+ inline RightShiftNode::RightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::forBitOp(), expr1, expr2, op_rshift, rightHasAssignments)
{
}
- inline UnsignedRightShiftNode::UnsignedRightShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_urshift, rightHasAssignments)
+ inline UnsignedRightShiftNode::UnsignedRightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::numberType(), expr1, expr2, op_urshift, rightHasAssignments)
{
}
- inline LessNode::LessNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::booleanType(), expr1, expr2, op_less, rightHasAssignments)
+ inline LessNode::LessNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::booleanType(), expr1, expr2, op_less, rightHasAssignments)
{
}
- inline GreaterNode::GreaterNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::booleanType(), expr1, expr2, op_greater, rightHasAssignments)
+ inline GreaterNode::GreaterNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::booleanType(), expr1, expr2, op_greater, rightHasAssignments)
{
}
- inline LessEqNode::LessEqNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::booleanType(), expr1, expr2, op_lesseq, rightHasAssignments)
+ inline LessEqNode::LessEqNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::booleanType(), expr1, expr2, op_lesseq, rightHasAssignments)
{
}
- inline GreaterEqNode::GreaterEqNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::booleanType(), expr1, expr2, op_greatereq, rightHasAssignments)
+ inline GreaterEqNode::GreaterEqNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::booleanType(), expr1, expr2, op_greatereq, rightHasAssignments)
{
}
- inline ThrowableBinaryOpNode::ThrowableBinaryOpNode(int lineNumber, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, type, expr1, expr2, opcodeID, rightHasAssignments)
+ inline ThrowableBinaryOpNode::ThrowableBinaryOpNode(const JSTokenLocation& location, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
+ : BinaryOpNode(location, type, expr1, expr2, opcodeID, rightHasAssignments)
{
}
- inline ThrowableBinaryOpNode::ThrowableBinaryOpNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, expr1, expr2, opcodeID, rightHasAssignments)
+ inline ThrowableBinaryOpNode::ThrowableBinaryOpNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
+ : BinaryOpNode(location, expr1, expr2, opcodeID, rightHasAssignments)
{
}
- inline InstanceOfNode::InstanceOfNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : ThrowableBinaryOpNode(lineNumber, ResultType::booleanType(), expr1, expr2, op_instanceof, rightHasAssignments)
+ inline InstanceOfNode::InstanceOfNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : ThrowableBinaryOpNode(location, ResultType::booleanType(), expr1, expr2, op_instanceof, rightHasAssignments)
{
}
- inline InNode::InNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : ThrowableBinaryOpNode(lineNumber, expr1, expr2, op_in, rightHasAssignments)
+ inline InNode::InNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : ThrowableBinaryOpNode(location, expr1, expr2, op_in, rightHasAssignments)
{
}
- inline EqualNode::EqualNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::booleanType(), expr1, expr2, op_eq, rightHasAssignments)
+ inline EqualNode::EqualNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::booleanType(), expr1, expr2, op_eq, rightHasAssignments)
{
}
- inline NotEqualNode::NotEqualNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::booleanType(), expr1, expr2, op_neq, rightHasAssignments)
+ inline NotEqualNode::NotEqualNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::booleanType(), expr1, expr2, op_neq, rightHasAssignments)
{
}
- inline StrictEqualNode::StrictEqualNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::booleanType(), expr1, expr2, op_stricteq, rightHasAssignments)
+ inline StrictEqualNode::StrictEqualNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::booleanType(), expr1, expr2, op_stricteq, rightHasAssignments)
{
}
- inline NotStrictEqualNode::NotStrictEqualNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::booleanType(), expr1, expr2, op_nstricteq, rightHasAssignments)
+ inline NotStrictEqualNode::NotStrictEqualNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::booleanType(), expr1, expr2, op_nstricteq, rightHasAssignments)
{
}
- inline BitAndNode::BitAndNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::forBitOp(), expr1, expr2, op_bitand, rightHasAssignments)
+ inline BitAndNode::BitAndNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::forBitOp(), expr1, expr2, op_bitand, rightHasAssignments)
{
}
- inline BitOrNode::BitOrNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::forBitOp(), expr1, expr2, op_bitor, rightHasAssignments)
+ inline BitOrNode::BitOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::forBitOp(), expr1, expr2, op_bitor, rightHasAssignments)
{
}
- inline BitXOrNode::BitXOrNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
- : BinaryOpNode(lineNumber, ResultType::forBitOp(), expr1, expr2, op_bitxor, rightHasAssignments)
+ inline BitXOrNode::BitXOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+ : BinaryOpNode(location, ResultType::forBitOp(), expr1, expr2, op_bitxor, rightHasAssignments)
{
}
- inline LogicalOpNode::LogicalOpNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator oper)
- : ExpressionNode(lineNumber, ResultType::booleanType())
+ inline LogicalOpNode::LogicalOpNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator oper)
+ : ExpressionNode(location, ResultType::booleanType())
, m_expr1(expr1)
, m_expr2(expr2)
, m_operator(oper)
{
}
- inline ConditionalNode::ConditionalNode(int lineNumber, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2)
- : ExpressionNode(lineNumber)
+ inline ConditionalNode::ConditionalNode(const JSTokenLocation& location, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2)
+ : ExpressionNode(location)
, m_logical(logical)
, m_expr1(expr1)
, m_expr2(expr2)
{
}
- inline ReadModifyResolveNode::ReadModifyResolveNode(int lineNumber, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline ReadModifyResolveNode::ReadModifyResolveNode(const JSTokenLocation& location, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_ident(ident)
, m_right(right)
@@ -590,15 +591,15 @@ namespace JSC {
{
}
- inline AssignResolveNode::AssignResolveNode(int lineNumber, const Identifier& ident, ExpressionNode* right)
- : ExpressionNode(lineNumber)
+ inline AssignResolveNode::AssignResolveNode(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* right)
+ : ExpressionNode(location)
, m_ident(ident)
, m_right(right)
{
}
- inline ReadModifyBracketNode::ReadModifyBracketNode(int lineNumber, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline ReadModifyBracketNode::ReadModifyBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableSubExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_subscript(subscript)
@@ -609,8 +610,8 @@ namespace JSC {
{
}
- inline AssignBracketNode::AssignBracketNode(int lineNumber, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline AssignBracketNode::AssignBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_subscript(subscript)
@@ -620,8 +621,8 @@ namespace JSC {
{
}
- inline AssignDotNode::AssignDotNode(int lineNumber, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline AssignDotNode::AssignDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_ident(ident)
@@ -630,8 +631,8 @@ namespace JSC {
{
}
- inline ReadModifyDotNode::ReadModifyDotNode(int lineNumber, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline ReadModifyDotNode::ReadModifyDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableSubExpressionData(divot, startOffset, endOffset)
, m_base(base)
, m_ident(ident)
@@ -641,21 +642,21 @@ namespace JSC {
{
}
- inline AssignErrorNode::AssignErrorNode(int lineNumber, unsigned divot, unsigned startOffset, unsigned endOffset)
- : ExpressionNode(lineNumber)
+ inline AssignErrorNode::AssignErrorNode(const JSTokenLocation& location, unsigned divot, unsigned startOffset, unsigned endOffset)
+ : ExpressionNode(location)
, ThrowableExpressionData(divot, startOffset, endOffset)
{
}
- inline CommaNode::CommaNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2)
- : ExpressionNode(lineNumber)
+ inline CommaNode::CommaNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2)
+ : ExpressionNode(location)
{
m_expressions.append(expr1);
m_expressions.append(expr2);
}
- inline ConstStatementNode::ConstStatementNode(int lineNumber, ConstDeclNode* next)
- : StatementNode(lineNumber)
+ inline ConstStatementNode::ConstStatementNode(const JSTokenLocation& location, ConstDeclNode* next)
+ : StatementNode(location)
, m_next(next)
{
}
@@ -664,57 +665,57 @@ namespace JSC {
{
}
- inline EmptyStatementNode::EmptyStatementNode(int lineNumber)
- : StatementNode(lineNumber)
+ inline EmptyStatementNode::EmptyStatementNode(const JSTokenLocation& location)
+ : StatementNode(location)
{
}
- inline DebuggerStatementNode::DebuggerStatementNode(int lineNumber)
- : StatementNode(lineNumber)
+ inline DebuggerStatementNode::DebuggerStatementNode(const JSTokenLocation& location)
+ : StatementNode(location)
{
}
- inline ExprStatementNode::ExprStatementNode(int lineNumber, ExpressionNode* expr)
- : StatementNode(lineNumber)
+ inline ExprStatementNode::ExprStatementNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : StatementNode(location)
, m_expr(expr)
{
}
- inline VarStatementNode::VarStatementNode(int lineNumber, ExpressionNode* expr)
- : StatementNode(lineNumber)
+ inline VarStatementNode::VarStatementNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : StatementNode(location)
, m_expr(expr)
{
}
- inline IfNode::IfNode(int lineNumber, ExpressionNode* condition, StatementNode* ifBlock)
- : StatementNode(lineNumber)
+ inline IfNode::IfNode(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* ifBlock)
+ : StatementNode(location)
, m_condition(condition)
, m_ifBlock(ifBlock)
{
}
- inline IfElseNode::IfElseNode(int lineNumber, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock)
- : IfNode(lineNumber, condition, ifBlock)
+ inline IfElseNode::IfElseNode(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock)
+ : IfNode(location, condition, ifBlock)
, m_elseBlock(elseBlock)
{
}
- inline DoWhileNode::DoWhileNode(int lineNumber, StatementNode* statement, ExpressionNode* expr)
- : StatementNode(lineNumber)
+ inline DoWhileNode::DoWhileNode(const JSTokenLocation& location, StatementNode* statement, ExpressionNode* expr)
+ : StatementNode(location)
, m_statement(statement)
, m_expr(expr)
{
}
- inline WhileNode::WhileNode(int lineNumber, ExpressionNode* expr, StatementNode* statement)
- : StatementNode(lineNumber)
+ inline WhileNode::WhileNode(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement)
+ : StatementNode(location)
, m_expr(expr)
, m_statement(statement)
{
}
- inline ForNode::ForNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement)
- : StatementNode(lineNumber)
+ inline ForNode::ForNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement)
+ : StatementNode(location)
, m_expr1(expr1)
, m_expr2(expr2)
, m_expr3(expr3)
@@ -723,38 +724,38 @@ namespace JSC {
ASSERT(statement);
}
- inline ContinueNode::ContinueNode(JSGlobalData* globalData, int lineNumber)
- : StatementNode(lineNumber)
+ inline ContinueNode::ContinueNode(JSGlobalData* globalData, const JSTokenLocation& location)
+ : StatementNode(location)
, m_ident(globalData->propertyNames->nullIdentifier)
{
}
- inline ContinueNode::ContinueNode(int lineNumber, const Identifier& ident)
- : StatementNode(lineNumber)
+ inline ContinueNode::ContinueNode(const JSTokenLocation& location, const Identifier& ident)
+ : StatementNode(location)
, m_ident(ident)
{
}
- inline BreakNode::BreakNode(JSGlobalData* globalData, int lineNumber)
- : StatementNode(lineNumber)
+ inline BreakNode::BreakNode(JSGlobalData* globalData, const JSTokenLocation& location)
+ : StatementNode(location)
, m_ident(globalData->propertyNames->nullIdentifier)
{
}
- inline BreakNode::BreakNode(int lineNumber, const Identifier& ident)
- : StatementNode(lineNumber)
+ inline BreakNode::BreakNode(const JSTokenLocation& location, const Identifier& ident)
+ : StatementNode(location)
, m_ident(ident)
{
}
- inline ReturnNode::ReturnNode(int lineNumber, ExpressionNode* value)
- : StatementNode(lineNumber)
+ inline ReturnNode::ReturnNode(const JSTokenLocation& location, ExpressionNode* value)
+ : StatementNode(location)
, m_value(value)
{
}
- inline WithNode::WithNode(int lineNumber, ExpressionNode* expr, StatementNode* statement, uint32_t divot, uint32_t expressionLength)
- : StatementNode(lineNumber)
+ inline WithNode::WithNode(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, uint32_t divot, uint32_t expressionLength)
+ : StatementNode(location)
, m_expr(expr)
, m_statement(statement)
, m_divot(divot)
@@ -762,21 +763,21 @@ namespace JSC {
{
}
- inline LabelNode::LabelNode(int lineNumber, const Identifier& name, StatementNode* statement)
- : StatementNode(lineNumber)
+ inline LabelNode::LabelNode(const JSTokenLocation& location, const Identifier& name, StatementNode* statement)
+ : StatementNode(location)
, m_name(name)
, m_statement(statement)
{
}
- inline ThrowNode::ThrowNode(int lineNumber, ExpressionNode* expr)
- : StatementNode(lineNumber)
+ inline ThrowNode::ThrowNode(const JSTokenLocation& location, ExpressionNode* expr)
+ : StatementNode(location)
, m_expr(expr)
{
}
- inline TryNode::TryNode(int lineNumber, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock)
- : StatementNode(lineNumber)
+ inline TryNode::TryNode(const JSTokenLocation& location, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock)
+ : StatementNode(location)
, m_tryBlock(tryBlock)
, m_exceptionIdent(exceptionIdent)
, m_catchBlock(catchBlock)
@@ -797,15 +798,15 @@ namespace JSC {
l->m_next = this;
}
- inline FuncExprNode::FuncExprNode(int lineNumber, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter)
- : ExpressionNode(lineNumber)
+ inline FuncExprNode::FuncExprNode(const JSTokenLocation& location, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter)
+ : ExpressionNode(location)
, m_body(body)
{
m_body->finishParsing(source, parameter, ident);
}
- inline FuncDeclNode::FuncDeclNode(int lineNumber, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter)
- : StatementNode(lineNumber)
+ inline FuncDeclNode::FuncDeclNode(const JSTokenLocation& location, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter)
+ : StatementNode(location)
, m_body(body)
{
m_body->finishParsing(source, parameter, ident);
@@ -837,29 +838,29 @@ namespace JSC {
{
}
- inline SwitchNode::SwitchNode(int lineNumber, ExpressionNode* expr, CaseBlockNode* block)
- : StatementNode(lineNumber)
+ inline SwitchNode::SwitchNode(const JSTokenLocation& location, ExpressionNode* expr, CaseBlockNode* block)
+ : StatementNode(location)
, m_expr(expr)
, m_block(block)
{
}
- inline ConstDeclNode::ConstDeclNode(int lineNumber, const Identifier& ident, ExpressionNode* init)
- : ExpressionNode(lineNumber)
+ inline ConstDeclNode::ConstDeclNode(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* init)
+ : ExpressionNode(location)
, m_ident(ident)
, m_next(0)
, m_init(init)
{
}
- inline BlockNode::BlockNode(int lineNumber, SourceElements* statements)
- : StatementNode(lineNumber)
+ inline BlockNode::BlockNode(const JSTokenLocation& location, SourceElements* statements)
+ : StatementNode(location)
, m_statements(statements)
{
}
- inline ForInNode::ForInNode(int lineNumber, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
- : StatementNode(lineNumber)
+ inline ForInNode::ForInNode(const JSTokenLocation& location, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
+ : StatementNode(location)
, m_init(0)
, m_lexpr(l)
, m_expr(expr)
@@ -868,16 +869,16 @@ namespace JSC {
{
}
- inline ForInNode::ForInNode(JSGlobalData* globalData, int lineNumber, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
- : StatementNode(lineNumber)
+ inline ForInNode::ForInNode(JSGlobalData* globalData, const JSTokenLocation& location, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
+ : StatementNode(location)
, m_init(0)
- , m_lexpr(new (globalData) ResolveNode(lineNumber, ident, divot - startOffset))
+ , m_lexpr(new (globalData) ResolveNode(location, ident, divot - startOffset))
, m_expr(expr)
, m_statement(statement)
, m_identIsVarDecl(true)
{
if (in) {
- AssignResolveNode* node = new (globalData) AssignResolveNode(lineNumber, ident, in);
+ AssignResolveNode* node = new (globalData) AssignResolveNode(location, ident, in);
node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot);
m_init = node;
}
diff --git a/Source/JavaScriptCore/parser/Nodes.cpp b/Source/JavaScriptCore/parser/Nodes.cpp
index c32e4c73a..0172359c7 100644
--- a/Source/JavaScriptCore/parser/Nodes.cpp
+++ b/Source/JavaScriptCore/parser/Nodes.cpp
@@ -52,10 +52,18 @@ namespace JSC {
// ------------------------------ StatementNode --------------------------------
+void StatementNode::setLoc(int firstLine, int lastLine, int column)
+{
+ m_lineNumber = firstLine;
+ m_lastLine = lastLine;
+ m_columnNumber = column;
+}
+
void StatementNode::setLoc(int firstLine, int lastLine)
{
m_lineNumber = firstLine;
m_lastLine = lastLine;
+ m_columnNumber = 0;
}
// ------------------------------ SourceElements --------------------------------
@@ -75,8 +83,8 @@ StatementNode* SourceElements::singleStatement() const
// ------------------------------ ScopeNode -----------------------------
-ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
- : StatementNode(lineNumber)
+ScopeNode::ScopeNode(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext)
+ : StatementNode(location)
, ParserArenaRefCounted(globalData)
, m_features(inStrictContext ? StrictModeFeature : NoFeatures)
, m_numConstants(0)
@@ -84,8 +92,8 @@ ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, bool inStrictCont
{
}
-ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
- : StatementNode(lineNumber)
+ScopeNode::ScopeNode(JSGlobalData* globalData, const JSTokenLocation& location, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
+ : StatementNode(location)
, ParserArenaRefCounted(globalData)
, m_features(features)
, m_source(source)
@@ -107,14 +115,14 @@ StatementNode* ScopeNode::singleStatement() const
// ------------------------------ ProgramNode -----------------------------
-inline ProgramNode::ProgramNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants)
+inline ProgramNode::ProgramNode(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+ : ScopeNode(globalData, location, source, children, varStack, funcStack, capturedVariables, features, numConstants)
{
}
-PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
{
- RefPtr<ProgramNode> node = new ProgramNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
+ RefPtr<ProgramNode> node = new ProgramNode(globalData, location, children, varStack, funcStack, capturedVariables, source, features, numConstants);
ASSERT(node->m_arena.last() == node);
node->m_arena.removeLast();
@@ -125,14 +133,14 @@ PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNu
// ------------------------------ EvalNode -----------------------------
-inline EvalNode::EvalNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants)
+inline EvalNode::EvalNode(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+ : ScopeNode(globalData, location, source, children, varStack, funcStack, capturedVariables, features, numConstants)
{
}
-PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
+PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
{
- RefPtr<EvalNode> node = new EvalNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
+ RefPtr<EvalNode> node = new EvalNode(globalData, location, children, varStack, funcStack, capturedVariables, source, features, numConstants);
ASSERT(node->m_arena.last() == node);
node->m_arena.removeLast();
@@ -149,13 +157,13 @@ FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
append(parameter->ident());
}
-inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
- : ScopeNode(globalData, lineNumber, inStrictContext)
+inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext)
+ : ScopeNode(globalData, location, inStrictContext)
{
}
-inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
- : ScopeNode(globalData, lineNumber, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
+inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+ : ScopeNode(globalData, location, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
{
}
@@ -172,14 +180,14 @@ void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters,
m_ident = ident;
}
-FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
+FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext)
{
- return new FunctionBodyNode(globalData, lineNumber, inStrictContext);
+ return new FunctionBodyNode(globalData, location, inStrictContext);
}
-PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
{
- RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
+ RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, location, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
ASSERT(node->m_arena.last() == node);
node->m_arena.removeLast();
diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h
index 5b15be44c..ed1a85aaf 100644
--- a/Source/JavaScriptCore/parser/Nodes.h
+++ b/Source/JavaScriptCore/parser/Nodes.h
@@ -130,7 +130,7 @@ namespace JSC {
class Node : public ParserArenaFreeable {
protected:
- Node(int);
+ Node(const JSTokenLocation&);
public:
virtual ~Node() { }
@@ -139,13 +139,16 @@ namespace JSC {
int lineNo() const { return m_lineNumber; }
+ int columnNo() const { return m_columnNumber; }
+
protected:
int m_lineNumber;
+ int m_columnNumber;
};
class ExpressionNode : public Node {
protected:
- ExpressionNode(int, ResultType = ResultType::unknownType());
+ ExpressionNode(const JSTokenLocation&, ResultType = ResultType::unknownType());
public:
virtual bool isNumber() const { return false; }
@@ -175,12 +178,14 @@ namespace JSC {
class StatementNode : public Node {
protected:
- StatementNode(int);
+ StatementNode(const JSTokenLocation&);
public:
JS_EXPORT_PRIVATE void setLoc(int firstLine, int lastLine);
+ void setLoc(int firstLine, int lastLine, int column);
int firstLine() const { return lineNo(); }
int lastLine() const { return m_lastLine; }
+ int column() const { return columnNo();}
virtual bool isEmptyStatement() const { return false; }
virtual bool isReturnNode() const { return false; }
@@ -194,7 +199,7 @@ namespace JSC {
class NullNode : public ExpressionNode {
public:
- NullNode(int);
+ NullNode(const JSTokenLocation&);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -204,7 +209,7 @@ namespace JSC {
class BooleanNode : public ExpressionNode {
public:
- BooleanNode(int, bool value);
+ BooleanNode(const JSTokenLocation&, bool value);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -216,7 +221,7 @@ namespace JSC {
class NumberNode : public ExpressionNode {
public:
- NumberNode(int, double value);
+ NumberNode(const JSTokenLocation&, double value);
double value() const { return m_value; }
void setValue(double value) { m_value = value; }
@@ -232,7 +237,7 @@ namespace JSC {
class StringNode : public ExpressionNode {
public:
- StringNode(int, const Identifier&);
+ StringNode(const JSTokenLocation&, const Identifier&);
const Identifier& value() { return m_value; }
@@ -342,7 +347,7 @@ namespace JSC {
class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
public:
- RegExpNode(int, const Identifier& pattern, const Identifier& flags);
+ RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -353,7 +358,7 @@ namespace JSC {
class ThisNode : public ExpressionNode {
public:
- ThisNode(int);
+ ThisNode(const JSTokenLocation&);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -361,7 +366,7 @@ namespace JSC {
class ResolveNode : public ExpressionNode {
public:
- ResolveNode(int, const Identifier&, int startOffset);
+ ResolveNode(const JSTokenLocation&, const Identifier&, int startOffset);
const Identifier& identifier() const { return m_ident; }
@@ -393,11 +398,11 @@ namespace JSC {
class ArrayNode : public ExpressionNode {
public:
- ArrayNode(int, int elision);
- ArrayNode(int, ElementNode*);
- ArrayNode(int, int elision, ElementNode*);
+ ArrayNode(const JSTokenLocation&, int elision);
+ ArrayNode(const JSTokenLocation&, ElementNode*);
+ ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
- ArgumentListNode* toArgumentList(JSGlobalData*, int) const;
+ ArgumentListNode* toArgumentList(JSGlobalData*, int, int) const;
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -428,8 +433,8 @@ namespace JSC {
class PropertyListNode : public Node {
public:
- PropertyListNode(int, PropertyNode*);
- PropertyListNode(int, PropertyNode*, PropertyListNode*);
+ PropertyListNode(const JSTokenLocation&, PropertyNode*);
+ PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -440,8 +445,8 @@ namespace JSC {
class ObjectLiteralNode : public ExpressionNode {
public:
- ObjectLiteralNode(int);
- ObjectLiteralNode(int, PropertyListNode*);
+ ObjectLiteralNode(const JSTokenLocation&);
+ ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -451,7 +456,7 @@ namespace JSC {
class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- BracketAccessorNode(int, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
+ BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
ExpressionNode* base() const { return m_base; }
ExpressionNode* subscript() const { return m_subscript; }
@@ -469,7 +474,7 @@ namespace JSC {
class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DotAccessorNode(int, ExpressionNode* base, const Identifier&);
+ DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&);
ExpressionNode* base() const { return m_base; }
const Identifier& identifier() const { return m_ident; }
@@ -486,8 +491,8 @@ namespace JSC {
class ArgumentListNode : public Node {
public:
- ArgumentListNode(int, ExpressionNode*);
- ArgumentListNode(int, ArgumentListNode*, ExpressionNode*);
+ ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
+ ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*);
ArgumentListNode* m_next;
ExpressionNode* m_expr;
@@ -506,8 +511,8 @@ namespace JSC {
class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
public:
- NewExprNode(int, ExpressionNode*);
- NewExprNode(int, ExpressionNode*, ArgumentsNode*);
+ NewExprNode(const JSTokenLocation&, ExpressionNode*);
+ NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -518,7 +523,7 @@ namespace JSC {
class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
public:
- EvalFunctionCallNode(int, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -528,7 +533,7 @@ namespace JSC {
class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
public:
- FunctionCallValueNode(int, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -539,7 +544,7 @@ namespace JSC {
class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- FunctionCallResolveNode(int, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -550,7 +555,7 @@ namespace JSC {
class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- FunctionCallBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -562,7 +567,7 @@ namespace JSC {
class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- FunctionCallDotNode(int, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -575,7 +580,7 @@ namespace JSC {
class CallFunctionCallDotNode : public FunctionCallDotNode {
public:
- CallFunctionCallDotNode(int, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -583,7 +588,7 @@ namespace JSC {
class ApplyFunctionCallDotNode : public FunctionCallDotNode {
public:
- ApplyFunctionCallDotNode(int, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -591,7 +596,7 @@ namespace JSC {
class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- PrePostResolveNode(int, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PrePostResolveNode(const JSTokenLocation&, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
protected:
const Identifier& m_ident;
@@ -599,7 +604,7 @@ namespace JSC {
class PostfixResolveNode : public PrePostResolveNode {
public:
- PostfixResolveNode(int, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PostfixResolveNode(const JSTokenLocation&, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -609,7 +614,7 @@ namespace JSC {
class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- PostfixBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PostfixBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -621,7 +626,7 @@ namespace JSC {
class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- PostfixDotNode(int, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PostfixDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -633,7 +638,7 @@ namespace JSC {
class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- PostfixErrorNode(int, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PostfixErrorNode(const JSTokenLocation&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -643,7 +648,7 @@ namespace JSC {
class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteResolveNode(int, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+ DeleteResolveNode(const JSTokenLocation&, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -653,7 +658,7 @@ namespace JSC {
class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
+ DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -664,7 +669,7 @@ namespace JSC {
class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
public:
- DeleteDotNode(int, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+ DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -675,7 +680,7 @@ namespace JSC {
class DeleteValueNode : public ExpressionNode {
public:
- DeleteValueNode(int, ExpressionNode*);
+ DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -685,7 +690,7 @@ namespace JSC {
class VoidNode : public ExpressionNode {
public:
- VoidNode(int, ExpressionNode*);
+ VoidNode(const JSTokenLocation&, ExpressionNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -695,7 +700,7 @@ namespace JSC {
class TypeOfResolveNode : public ExpressionNode {
public:
- TypeOfResolveNode(int, const Identifier&);
+ TypeOfResolveNode(const JSTokenLocation&, const Identifier&);
const Identifier& identifier() const { return m_ident; }
@@ -707,7 +712,7 @@ namespace JSC {
class TypeOfValueNode : public ExpressionNode {
public:
- TypeOfValueNode(int, ExpressionNode*);
+ TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -717,7 +722,7 @@ namespace JSC {
class PrefixResolveNode : public PrePostResolveNode {
public:
- PrefixResolveNode(int, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PrefixResolveNode(const JSTokenLocation&, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -727,7 +732,7 @@ namespace JSC {
class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
public:
- PrefixBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PrefixBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -739,7 +744,7 @@ namespace JSC {
class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
public:
- PrefixDotNode(int, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PrefixDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -751,7 +756,7 @@ namespace JSC {
class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- PrefixErrorNode(int, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+ PrefixErrorNode(const JSTokenLocation&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -761,7 +766,7 @@ namespace JSC {
class UnaryOpNode : public ExpressionNode {
public:
- UnaryOpNode(int, ResultType, ExpressionNode*, OpcodeID);
+ UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID);
protected:
ExpressionNode* expr() { return m_expr; }
@@ -778,7 +783,7 @@ namespace JSC {
class UnaryPlusNode : public UnaryOpNode {
public:
- UnaryPlusNode(int, ExpressionNode*);
+ UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
private:
virtual ExpressionNode* stripUnaryPlus() { return expr(); }
@@ -786,12 +791,12 @@ namespace JSC {
class NegateNode : public UnaryOpNode {
public:
- NegateNode(int, ExpressionNode*);
+ NegateNode(const JSTokenLocation&, ExpressionNode*);
};
class BitwiseNotNode : public ExpressionNode {
public:
- BitwiseNotNode(int, ExpressionNode*);
+ BitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
protected:
ExpressionNode* expr() { return m_expr; }
@@ -805,7 +810,7 @@ namespace JSC {
class LogicalNotNode : public UnaryOpNode {
public:
- LogicalNotNode(int, ExpressionNode*);
+ LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
private:
void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
virtual bool hasConditionContextCodegen() const { return expr()->hasConditionContextCodegen(); }
@@ -813,8 +818,8 @@ namespace JSC {
class BinaryOpNode : public ExpressionNode {
public:
- BinaryOpNode(int, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
- BinaryOpNode(int, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+ BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+ BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
@@ -838,72 +843,72 @@ namespace JSC {
class MultNode : public BinaryOpNode {
public:
- MultNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class DivNode : public BinaryOpNode {
public:
- DivNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class ModNode : public BinaryOpNode {
public:
- ModNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class AddNode : public BinaryOpNode {
public:
- AddNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
virtual bool isAdd() const { return true; }
};
class SubNode : public BinaryOpNode {
public:
- SubNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
virtual bool isSubtract() const { return true; }
};
class LeftShiftNode : public BinaryOpNode {
public:
- LeftShiftNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class RightShiftNode : public BinaryOpNode {
public:
- RightShiftNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class UnsignedRightShiftNode : public BinaryOpNode {
public:
- UnsignedRightShiftNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class LessNode : public BinaryOpNode {
public:
- LessNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class GreaterNode : public BinaryOpNode {
public:
- GreaterNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class LessEqNode : public BinaryOpNode {
public:
- LessEqNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class GreaterEqNode : public BinaryOpNode {
public:
- GreaterEqNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
public:
- ThrowableBinaryOpNode(int, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
- ThrowableBinaryOpNode(int, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+ ThrowableBinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+ ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -911,7 +916,7 @@ namespace JSC {
class InstanceOfNode : public ThrowableBinaryOpNode {
public:
- InstanceOfNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -919,12 +924,12 @@ namespace JSC {
class InNode : public ThrowableBinaryOpNode {
public:
- InNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class EqualNode : public BinaryOpNode {
public:
- EqualNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -932,12 +937,12 @@ namespace JSC {
class NotEqualNode : public BinaryOpNode {
public:
- NotEqualNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class StrictEqualNode : public BinaryOpNode {
public:
- StrictEqualNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -945,28 +950,28 @@ namespace JSC {
class NotStrictEqualNode : public BinaryOpNode {
public:
- NotStrictEqualNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class BitAndNode : public BinaryOpNode {
public:
- BitAndNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class BitOrNode : public BinaryOpNode {
public:
- BitOrNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
class BitXOrNode : public BinaryOpNode {
public:
- BitXOrNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+ BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
};
// m_expr1 && m_expr2, m_expr1 || m_expr2
class LogicalOpNode : public ExpressionNode {
public:
- LogicalOpNode(int, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
+ LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -981,7 +986,7 @@ namespace JSC {
// The ternary operator, "m_logical ? m_expr1 : m_expr2"
class ConditionalNode : public ExpressionNode {
public:
- ConditionalNode(int, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
+ ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -993,7 +998,7 @@ namespace JSC {
class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- ReadModifyResolveNode(int, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1006,7 +1011,7 @@ namespace JSC {
class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignResolveNode(int, const Identifier&, ExpressionNode* right);
+ AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1017,7 +1022,7 @@ namespace JSC {
class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- ReadModifyBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1032,7 +1037,7 @@ namespace JSC {
class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1046,7 +1051,7 @@ namespace JSC {
class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignDotNode(int, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1059,7 +1064,7 @@ namespace JSC {
class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
public:
- ReadModifyDotNode(int, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+ ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1073,7 +1078,7 @@ namespace JSC {
class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
public:
- AssignErrorNode(int, unsigned divot, unsigned startOffset, unsigned endOffset);
+ AssignErrorNode(const JSTokenLocation&, unsigned divot, unsigned startOffset, unsigned endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1083,7 +1088,7 @@ namespace JSC {
class CommaNode : public ExpressionNode, public ParserArenaDeletable {
public:
- CommaNode(int, ExpressionNode* expr1, ExpressionNode* expr2);
+ CommaNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2);
using ParserArenaDeletable::operator new;
@@ -1098,7 +1103,7 @@ namespace JSC {
class ConstDeclNode : public ExpressionNode {
public:
- ConstDeclNode(int, const Identifier&, ExpressionNode*);
+ ConstDeclNode(const JSTokenLocation&, const Identifier&, ExpressionNode*);
bool hasInitializer() const { return m_init; }
const Identifier& ident() { return m_ident; }
@@ -1118,7 +1123,7 @@ namespace JSC {
class ConstStatementNode : public StatementNode {
public:
- ConstStatementNode(int, ConstDeclNode* next);
+ ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1143,7 +1148,7 @@ namespace JSC {
class BlockNode : public StatementNode {
public:
- BlockNode(int, SourceElements* = 0);
+ BlockNode(const JSTokenLocation&, SourceElements* = 0);
StatementNode* singleStatement() const;
StatementNode* lastStatement() const;
@@ -1158,7 +1163,7 @@ namespace JSC {
class EmptyStatementNode : public StatementNode {
public:
- EmptyStatementNode(int);
+ EmptyStatementNode(const JSTokenLocation&);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1168,7 +1173,7 @@ namespace JSC {
class DebuggerStatementNode : public StatementNode {
public:
- DebuggerStatementNode(int);
+ DebuggerStatementNode(const JSTokenLocation&);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1176,7 +1181,7 @@ namespace JSC {
class ExprStatementNode : public StatementNode {
public:
- ExprStatementNode(int, ExpressionNode*);
+ ExprStatementNode(const JSTokenLocation&, ExpressionNode*);
ExpressionNode* expr() const { return m_expr; }
@@ -1190,8 +1195,7 @@ namespace JSC {
class VarStatementNode : public StatementNode {
public:
- VarStatementNode(int, ExpressionNode*);
-
+ VarStatementNode(const JSTokenLocation&, ExpressionNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1200,7 +1204,7 @@ namespace JSC {
class IfNode : public StatementNode {
public:
- IfNode(int, ExpressionNode* condition, StatementNode* ifBlock);
+ IfNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock);
protected:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1211,7 +1215,7 @@ namespace JSC {
class IfElseNode : public IfNode {
public:
- IfElseNode(int, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
+ IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1221,7 +1225,7 @@ namespace JSC {
class DoWhileNode : public StatementNode {
public:
- DoWhileNode(int, StatementNode*, ExpressionNode*);
+ DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1232,7 +1236,7 @@ namespace JSC {
class WhileNode : public StatementNode {
public:
- WhileNode(int, ExpressionNode*, StatementNode*);
+ WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1243,7 +1247,7 @@ namespace JSC {
class ForNode : public StatementNode {
public:
- ForNode(int, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
+ ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1256,8 +1260,8 @@ namespace JSC {
class ForInNode : public StatementNode, public ThrowableExpressionData {
public:
- ForInNode(int, ExpressionNode*, ExpressionNode*, StatementNode*);
- ForInNode(JSGlobalData*, int, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
+ ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
+ ForInNode(JSGlobalData*, const JSTokenLocation&, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1271,8 +1275,8 @@ namespace JSC {
class ContinueNode : public StatementNode, public ThrowableExpressionData {
public:
- ContinueNode(JSGlobalData*, int);
- ContinueNode(int, const Identifier&);
+ ContinueNode(JSGlobalData*, const JSTokenLocation&);
+ ContinueNode(const JSTokenLocation&, const Identifier&);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1282,8 +1286,8 @@ namespace JSC {
class BreakNode : public StatementNode, public ThrowableExpressionData {
public:
- BreakNode(JSGlobalData*, int);
- BreakNode(int, const Identifier&);
+ BreakNode(JSGlobalData*, const JSTokenLocation&);
+ BreakNode(const JSTokenLocation&, const Identifier&);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1293,7 +1297,7 @@ namespace JSC {
class ReturnNode : public StatementNode, public ThrowableExpressionData {
public:
- ReturnNode(int, ExpressionNode* value);
+ ReturnNode(const JSTokenLocation&, ExpressionNode* value);
ExpressionNode* value() { return m_value; }
@@ -1307,7 +1311,7 @@ namespace JSC {
class WithNode : public StatementNode {
public:
- WithNode(int, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
+ WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1320,7 +1324,7 @@ namespace JSC {
class LabelNode : public StatementNode, public ThrowableExpressionData {
public:
- LabelNode(int, const Identifier& name, StatementNode*);
+ LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1331,7 +1335,7 @@ namespace JSC {
class ThrowNode : public StatementNode, public ThrowableExpressionData {
public:
- ThrowNode(int, ExpressionNode*);
+ ThrowNode(const JSTokenLocation&, ExpressionNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1341,7 +1345,7 @@ namespace JSC {
class TryNode : public StatementNode {
public:
- TryNode(int, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
+ TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1370,8 +1374,8 @@ namespace JSC {
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNode(JSGlobalData*, int, bool inStrictContext);
- ScopeNode(JSGlobalData*, int, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
+ ScopeNode(JSGlobalData*, const JSTokenLocation&, bool inStrictContext);
+ ScopeNode(JSGlobalData*, const JSTokenLocation&, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
using ParserArenaRefCounted::operator new;
@@ -1433,12 +1437,12 @@ namespace JSC {
class ProgramNode : public ScopeNode {
public:
static const bool isFunctionNode = false;
- static PassRefPtr<ProgramNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<ProgramNode> create(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
static const bool scopeIsFunction = false;
private:
- ProgramNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ ProgramNode(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
@@ -1446,12 +1450,12 @@ namespace JSC {
class EvalNode : public ScopeNode {
public:
static const bool isFunctionNode = false;
- static PassRefPtr<EvalNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static PassRefPtr<EvalNode> create(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
static const bool scopeIsFunction = false;
private:
- EvalNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ EvalNode(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
@@ -1468,8 +1472,8 @@ namespace JSC {
class FunctionBodyNode : public ScopeNode {
public:
static const bool isFunctionNode = true;
- static FunctionBodyNode* create(JSGlobalData*, int, bool isStrictMode);
- static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ static FunctionBodyNode* create(JSGlobalData*, const JSTokenLocation&, bool isStrictMode);
+ static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
FunctionParameters* parameters() const { return m_parameters.get(); }
size_t parameterCount() const { return m_parameters->size(); }
@@ -1486,8 +1490,8 @@ namespace JSC {
static const bool scopeIsFunction = true;
private:
- FunctionBodyNode(JSGlobalData*, int, bool inStrictContext);
- FunctionBodyNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+ FunctionBodyNode(JSGlobalData*, const JSTokenLocation&, bool inStrictContext);
+ FunctionBodyNode(JSGlobalData*, const JSTokenLocation&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
Identifier m_ident;
Identifier m_inferredName;
@@ -1496,7 +1500,7 @@ namespace JSC {
class FuncExprNode : public ExpressionNode {
public:
- FuncExprNode(int, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
+ FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
FunctionBodyNode* body() { return m_body; }
@@ -1510,7 +1514,7 @@ namespace JSC {
class FuncDeclNode : public StatementNode {
public:
- FuncDeclNode(int, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
+ FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
FunctionBodyNode* body() { return m_body; }
@@ -1561,7 +1565,7 @@ namespace JSC {
class SwitchNode : public StatementNode {
public:
- SwitchNode(int, ExpressionNode*, CaseBlockNode*);
+ SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp
index 558f50e5f..4fd671fb7 100644
--- a/Source/JavaScriptCore/parser/Parser.cpp
+++ b/Source/JavaScriptCore/parser/Parser.cpp
@@ -138,7 +138,7 @@ template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements Parser<
bool seenNonDirective = false;
const Identifier* directive = 0;
unsigned directiveLiteralLength = 0;
- unsigned startOffset = m_token.m_info.startOffset;
+ unsigned startOffset = m_token.m_location.startOffset;
unsigned oldLastLineNumber = m_lexer->lastLineNumber();
unsigned oldLineNumber = m_lexer->lineNumber();
bool hasSetStrict = false;
@@ -172,6 +172,7 @@ template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVarDeclaration(TreeBuilder& context)
{
ASSERT(match(VAR));
+ JSTokenLocation location(tokenLocation());
int start = tokenLine();
int end = 0;
int scratch;
@@ -182,20 +183,21 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVarDeclaratio
failIfTrue(m_error);
failIfFalse(autoSemiColon());
- return context.createVarStatement(m_lexer->lastLineNumber(), varDecls, start, end);
+ return context.createVarStatement(location, varDecls, start, end);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseConstDeclaration(TreeBuilder& context)
{
ASSERT(match(CONSTTOKEN));
+ JSTokenLocation location(tokenLocation());
int start = tokenLine();
int end = 0;
TreeConstDeclList constDecls = parseConstDeclarationList(context);
failIfTrue(m_error);
failIfFalse(autoSemiColon());
- return context.createConstStatement(m_lexer->lastLineNumber(), constDecls, start, end);
+ return context.createConstStatement(location, constDecls, start, end);
}
template <typename LexerType>
@@ -210,6 +212,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseDoWhileStatem
endLoop();
failIfFalse(statement);
int endLine = tokenLine();
+ JSTokenLocation location(tokenLocation());
consumeOrFail(WHILE);
consumeOrFail(OPENPAREN);
TreeExpression expr = parseExpression(context);
@@ -217,13 +220,14 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseDoWhileStatem
consumeOrFail(CLOSEPAREN);
if (match(SEMICOLON))
next(); // Always performs automatic semicolon insertion.
- return context.createDoWhileStatement(m_lexer->lastLineNumber(), statement, expr, startLine, endLine);
+ return context.createDoWhileStatement(location, statement, expr, startLine, endLine);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWhileStatement(TreeBuilder& context)
{
ASSERT(match(WHILE));
+ JSTokenLocation location(tokenLocation());
int startLine = tokenLine();
next();
consumeOrFail(OPENPAREN);
@@ -236,7 +240,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWhileStatemen
TreeStatement statement = parseStatement(context, unused);
endLoop();
failIfFalse(statement);
- return context.createWhileStatement(m_lexer->lastLineNumber(), expr, statement, startLine, endLine);
+ return context.createWhileStatement(location, expr, statement, startLine, endLine);
}
template <typename LexerType>
@@ -245,6 +249,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarati
TreeExpression varDecls = 0;
do {
declarations++;
+ JSTokenLocation location(tokenLocation());
next();
matchOrFail(IDENT);
@@ -265,11 +270,11 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarati
lastInitializer = initializer;
failIfFalse(initializer);
- TreeExpression node = context.createAssignResolve(m_lexer->lastLineNumber(), *name, initializer, varStart, varDivot, lastTokenEnd());
+ TreeExpression node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEnd());
if (!varDecls)
varDecls = node;
else
- varDecls = context.combineCommaNodes(m_lexer->lastLineNumber(), varDecls, node);
+ varDecls = context.combineCommaNodes(location, varDecls, node);
}
} while (match(COMMA));
return varDecls;
@@ -282,6 +287,7 @@ template <class TreeBuilder> TreeConstDeclList Parser<LexerType>::parseConstDecl
TreeConstDeclList constDecls = 0;
TreeConstDeclList tail = 0;
do {
+ JSTokenLocation location(tokenLocation());
next();
matchOrFail(IDENT);
const Identifier* name = m_token.m_data.ident;
@@ -294,7 +300,7 @@ template <class TreeBuilder> TreeConstDeclList Parser<LexerType>::parseConstDecl
next(TreeBuilder::DontBuildStrings); // consume '='
initializer = parseAssignmentExpression(context);
}
- tail = context.appendConstDecl(m_lexer->lastLineNumber(), tail, name, initializer);
+ tail = context.appendConstDecl(location, tail, name, initializer);
if (!constDecls)
constDecls = tail;
} while (match(COMMA));
@@ -305,6 +311,7 @@ template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(TreeBuilder& context)
{
ASSERT(match(FOR));
+ JSTokenLocation location(tokenLocation());
int startLine = tokenLine();
next();
consumeOrFail(OPENPAREN);
@@ -352,7 +359,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
endLoop();
failIfFalse(statement);
- return context.createForInLoop(m_lexer->lastLineNumber(), forInTarget, forInInitializer, expr, statement, declsStart, inLocation, exprEnd, initStart, initEnd, startLine, endLine);
+ return context.createForInLoop(location, forInTarget, forInInitializer, expr, statement, declsStart, inLocation, exprEnd, initStart, initEnd, startLine, endLine);
}
if (!match(SEMICOLON)) {
@@ -388,7 +395,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
TreeStatement statement = parseStatement(context, unused);
endLoop();
failIfFalse(statement);
- return context.createForLoop(m_lexer->lastLineNumber(), decls, condition, increment, statement, startLine, endLine);
+ return context.createForLoop(location, decls, condition, increment, statement, startLine, endLine);
}
// For-in loop
@@ -405,13 +412,14 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(
endLoop();
failIfFalse(statement);
- return context.createForInLoop(m_lexer->lastLineNumber(), decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine);
+ return context.createForInLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBreakStatement(TreeBuilder& context)
{
ASSERT(match(BREAK));
+ JSTokenLocation location(tokenLocation());
int startCol = tokenStart();
int endCol = tokenEnd();
int startLine = tokenLine();
@@ -420,7 +428,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBreakStatemen
if (autoSemiColon()) {
failIfFalseWithMessage(breakIsValid(), "'break' is only valid inside a switch or loop statement");
- return context.createBreakStatement(m_lexer->lastLineNumber(), startCol, endCol, startLine, endLine);
+ return context.createBreakStatement(location, startCol, endCol, startLine, endLine);
}
matchOrFail(IDENT);
const Identifier* ident = m_token.m_data.ident;
@@ -429,13 +437,14 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBreakStatemen
endLine = tokenLine();
next();
failIfFalse(autoSemiColon());
- return context.createBreakStatement(m_lexer->lastLineNumber(), ident, startCol, endCol, startLine, endLine);
+ return context.createBreakStatement(location, ident, startCol, endCol, startLine, endLine);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseContinueStatement(TreeBuilder& context)
{
ASSERT(match(CONTINUE));
+ JSTokenLocation location(tokenLocation());
int startCol = tokenStart();
int endCol = tokenEnd();
int startLine = tokenLine();
@@ -444,7 +453,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseContinueState
if (autoSemiColon()) {
failIfFalseWithMessage(continueIsValid(), "'continue' is only valid inside a loop statement");
- return context.createContinueStatement(m_lexer->lastLineNumber(), startCol, endCol, startLine, endLine);
+ return context.createContinueStatement(location, startCol, endCol, startLine, endLine);
}
matchOrFail(IDENT);
const Identifier* ident = m_token.m_data.ident;
@@ -455,13 +464,14 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseContinueState
endLine = tokenLine();
next();
failIfFalse(autoSemiColon());
- return context.createContinueStatement(m_lexer->lastLineNumber(), ident, startCol, endCol, startLine, endLine);
+ return context.createContinueStatement(location, ident, startCol, endCol, startLine, endLine);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseReturnStatement(TreeBuilder& context)
{
ASSERT(match(RETURN));
+ JSTokenLocation location(tokenLocation());
failIfFalse(currentScope()->isFunction());
int startLine = tokenLine();
int endLine = startLine;
@@ -474,20 +484,21 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseReturnStateme
if (match(SEMICOLON))
endLine = tokenLine();
if (autoSemiColon())
- return context.createReturnStatement(m_lexer->lastLineNumber(), 0, start, end, startLine, endLine);
+ return context.createReturnStatement(location, 0, start, end, startLine, endLine);
TreeExpression expr = parseExpression(context);
failIfFalse(expr);
end = lastTokenEnd();
if (match(SEMICOLON))
endLine = tokenLine();
failIfFalse(autoSemiColon());
- return context.createReturnStatement(m_lexer->lastLineNumber(), expr, start, end, startLine, endLine);
+ return context.createReturnStatement(location, expr, start, end, startLine, endLine);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseThrowStatement(TreeBuilder& context)
{
ASSERT(match(THROW));
+ JSTokenLocation location(tokenLocation());
int eStart = tokenStart();
int startLine = tokenLine();
next();
@@ -500,13 +511,14 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseThrowStatemen
int endLine = tokenLine();
failIfFalse(autoSemiColon());
- return context.createThrowStatement(m_lexer->lastLineNumber(), expr, eStart, eEnd, startLine, endLine);
+ return context.createThrowStatement(location, expr, eStart, eEnd, startLine, endLine);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement(TreeBuilder& context)
{
ASSERT(match(WITH));
+ JSTokenLocation location(tokenLocation());
failIfTrueWithMessage(strictMode(), "'with' statements are not valid in strict mode");
currentScope()->setNeedsFullActivation();
int startLine = tokenLine();
@@ -523,13 +535,14 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement
TreeStatement statement = parseStatement(context, unused);
failIfFalse(statement);
- return context.createWithStatement(m_lexer->lastLineNumber(), expr, statement, start, end, startLine, endLine);
+ return context.createWithStatement(location, expr, statement, start, end, startLine, endLine);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseSwitchStatement(TreeBuilder& context)
{
ASSERT(match(SWITCH));
+ JSTokenLocation location(tokenLocation());
int startLine = tokenLine();
next();
consumeOrFail(OPENPAREN);
@@ -550,7 +563,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseSwitchStateme
endSwitch();
consumeOrFail(CLOSEBRACE);
- return context.createSwitchStatement(m_lexer->lastLineNumber(), expr, firstClauses, defaultClause, secondClauses, startLine, endLine);
+ return context.createSwitchStatement(location, expr, firstClauses, defaultClause, secondClauses, startLine, endLine);
}
@@ -598,6 +611,7 @@ template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement(TreeBuilder& context)
{
ASSERT(match(TRY));
+ JSTokenLocation location(tokenLocation());
TreeStatement tryBlock = 0;
const Identifier* ident = &m_globalData->propertyNames->nullIdentifier;
TreeStatement catchBlock = 0;
@@ -634,37 +648,39 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement(
failIfFalse(finallyBlock);
}
failIfFalse(catchBlock || finallyBlock);
- return context.createTryStatement(m_lexer->lastLineNumber(), tryBlock, ident, catchBlock, finallyBlock, firstLine, lastLine);
+ return context.createTryStatement(location, tryBlock, ident, catchBlock, finallyBlock, firstLine, lastLine);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseDebuggerStatement(TreeBuilder& context)
{
ASSERT(match(DEBUGGER));
+ JSTokenLocation location(tokenLocation());
int startLine = tokenLine();
int endLine = startLine;
next();
if (match(SEMICOLON))
startLine = tokenLine();
failIfFalse(autoSemiColon());
- return context.createDebugger(m_lexer->lastLineNumber(), startLine, endLine);
+ return context.createDebugger(location, startLine, endLine);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBlockStatement(TreeBuilder& context)
{
ASSERT(match(OPENBRACE));
+ JSTokenLocation location(tokenLocation());
int start = tokenLine();
next();
if (match(CLOSEBRACE)) {
next();
- return context.createBlockStatement(m_lexer->lastLineNumber(), 0, start, m_lastLine);
+ return context.createBlockStatement(location, 0, start, m_lastLine);
}
TreeSourceElements subtree = parseSourceElements<DontCheckForStrictMode>(context);
failIfFalse(subtree);
matchOrFail(CLOSEBRACE);
next();
- return context.createBlockStatement(m_lexer->lastLineNumber(), subtree, start, m_lastLine);
+ return context.createBlockStatement(location, subtree, start, m_lastLine);
}
template <typename LexerType>
@@ -685,9 +701,11 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
case FUNCTION:
failIfFalseIfStrictWithMessage(m_statementDepth == 1, "Functions cannot be declared in a nested block in strict mode");
return parseFunctionDeclaration(context);
- case SEMICOLON:
+ case SEMICOLON: {
+ JSTokenLocation location(tokenLocation());
next();
- return context.createEmptyStatement(m_lexer->lastLineNumber());
+ return context.createEmptyStatement(location);
+ }
case IF:
return parseIfStatement(context);
case DO:
@@ -723,7 +741,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
case STRING:
directive = m_token.m_data.ident;
if (directiveLiteralLength)
- *directiveLiteralLength = m_token.m_info.endOffset - m_token.m_info.startOffset;
+ *directiveLiteralLength = m_token.m_location.endOffset - m_token.m_location.startOffset;
nonTrivialExpressionCount = m_nonTrivialExpressionCount;
default:
TreeStatement exprStatement = parseExpressionStatement(context);
@@ -756,12 +774,12 @@ template <typename LexerType>
template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(TreeBuilder& context)
{
if (match(CLOSEBRACE))
- return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode());
+ return context.createFunctionBody(tokenLocation(), strictMode());
DepthManager statementDepth(&m_statementDepth);
m_statementDepth = 0;
typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<JSGlobalData*>(m_globalData), m_lexer.get());
failIfFalse(parseSourceElements<CheckForStrictMode>(bodyBuilder));
- return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode());
+ return context.createFunctionBody(tokenLocation(), strictMode());
}
template <typename LexerType>
@@ -786,20 +804,21 @@ template <FunctionRequirements requirements, bool nameIsInContainingScope, class
openBracePos = m_token.m_data.intValue;
bodyStartLine = tokenLine();
+ JSTokenLocation location(tokenLocation());
// If we know about this function already, we can use the cached info and skip the parser to the end of the function.
if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(openBracePos) : 0) {
// If we're in a strict context, the cached function info must say it was strict too.
ASSERT(!strictMode() || cachedInfo->strictMode);
- body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->strictMode);
+ body = context.createFunctionBody(location, cachedInfo->strictMode);
functionScope->restoreFunctionInfo(cachedInfo);
failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
closeBracePos = cachedInfo->closeBracePos;
m_token = cachedInfo->closeBraceToken();
- m_lexer->setOffset(m_token.m_info.endOffset);
- m_lexer->setLineNumber(m_token.m_info.line);
+ m_lexer->setOffset(m_token.m_location.endOffset);
+ m_lexer->setLineNumber(m_token.m_location.line);
next();
return true;
@@ -821,7 +840,7 @@ template <FunctionRequirements requirements, bool nameIsInContainingScope, class
OwnPtr<SourceProviderCacheItem> newInfo;
int functionLength = closeBracePos - openBracePos;
if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) {
- newInfo = adoptPtr(new SourceProviderCacheItem(m_token.m_info.line, closeBracePos));
+ newInfo = adoptPtr(new SourceProviderCacheItem(m_token.m_location.line, closeBracePos));
functionScope->saveFunctionInfo(newInfo.get());
}
@@ -841,6 +860,7 @@ template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context)
{
ASSERT(match(FUNCTION));
+ JSTokenLocation location(tokenLocation());
next();
const Identifier* name = 0;
TreeFormalParameterList parameters = 0;
@@ -851,7 +871,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
failIfFalse(name);
failIfFalseIfStrict(declareVariable(name));
- return context.createFuncDeclStatement(m_lexer->lastLineNumber(), name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
+ return context.createFuncDeclStatement(location, name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
}
struct LabelInfo {
@@ -875,10 +895,11 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
* special case that looks for a colon as the next character in the input.
*/
Vector<LabelInfo> labels;
-
+ JSTokenLocation location;
do {
int start = tokenStart();
int startLine = tokenLine();
+ location = tokenLocation();
if (!nextTokenIsColon()) {
// If we hit this path we're making a expression statement, which
// by definition can't make use of continue/break so we can just
@@ -886,7 +907,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
TreeExpression expression = parseExpression(context);
failIfFalse(expression);
failIfFalse(autoSemiColon());
- return context.createExprStatement(m_lexer->lastLineNumber(), expression, startLine, m_lastLine);
+ return context.createExprStatement(location, expression, startLine, m_lastLine);
}
const Identifier* ident = m_token.m_data.ident;
int end = tokenEnd();
@@ -925,7 +946,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
failIfFalse(statement);
for (size_t i = 0; i < labels.size(); i++) {
const LabelInfo& info = labels[labels.size() - i - 1];
- statement = context.createLabelStatement(m_lexer->lastLineNumber(), info.m_ident, statement, info.m_start, info.m_end);
+ statement = context.createLabelStatement(location, info.m_ident, statement, info.m_start, info.m_end);
}
return statement;
}
@@ -934,39 +955,42 @@ template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionStatement(TreeBuilder& context)
{
int startLine = tokenLine();
+ JSTokenLocation location(tokenLocation());
TreeExpression expression = parseExpression(context);
failIfFalse(expression);
failIfFalse(autoSemiColon());
- return context.createExprStatement(m_lexer->lastLineNumber(), expression, startLine, m_lastLine);
+ return context.createExprStatement(location, expression, startLine, m_lastLine);
}
template <typename LexerType>
template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(TreeBuilder& context)
{
ASSERT(match(IF));
-
+ JSTokenLocation ifLocation(tokenLocation());
int start = tokenLine();
next();
-
+
consumeOrFail(OPENPAREN);
-
+
TreeExpression condition = parseExpression(context);
failIfFalse(condition);
int end = tokenLine();
consumeOrFail(CLOSEPAREN);
-
+
const Identifier* unused = 0;
TreeStatement trueBlock = parseStatement(context, unused);
failIfFalse(trueBlock);
-
+
if (!match(ELSE))
- return context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, start, end);
-
+ return context.createIfStatement(ifLocation, condition, trueBlock, start, end);
+
Vector<TreeExpression> exprStack;
Vector<pair<int, int> > posStack;
+ Vector<JSTokenLocation> tokenLocationStack;
Vector<TreeStatement> statementStack;
bool trailingElse = false;
do {
+ JSTokenLocation tempLocation = tokenLocation();
next();
if (!match(IF)) {
const Identifier* unused = 0;
@@ -978,21 +1002,22 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(T
}
int innerStart = tokenLine();
next();
-
+
consumeOrFail(OPENPAREN);
-
+
TreeExpression innerCondition = parseExpression(context);
failIfFalse(innerCondition);
int innerEnd = tokenLine();
consumeOrFail(CLOSEPAREN);
const Identifier* unused = 0;
TreeStatement innerTrueBlock = parseStatement(context, unused);
- failIfFalse(innerTrueBlock);
+ failIfFalse(innerTrueBlock);
+ tokenLocationStack.append(tempLocation);
exprStack.append(innerCondition);
posStack.append(make_pair(innerStart, innerEnd));
statementStack.append(innerTrueBlock);
} while (match(ELSE));
-
+
if (!trailingElse) {
TreeExpression condition = exprStack.last();
exprStack.removeLast();
@@ -1000,9 +1025,11 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(T
statementStack.removeLast();
pair<int, int> pos = posStack.last();
posStack.removeLast();
- statementStack.append(context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, pos.first, pos.second));
+ JSTokenLocation elseLocation = tokenLocationStack.last();
+ tokenLocationStack.removeLast();
+ statementStack.append(context.createIfStatement(elseLocation, condition, trueBlock, pos.first, pos.second));
}
-
+
while (!exprStack.isEmpty()) {
TreeExpression condition = exprStack.last();
exprStack.removeLast();
@@ -1012,16 +1039,19 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(T
statementStack.removeLast();
pair<int, int> pos = posStack.last();
posStack.removeLast();
- statementStack.append(context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, falseBlock, pos.first, pos.second));
+ JSTokenLocation elseLocation = tokenLocationStack.last();
+ tokenLocationStack.removeLast();
+ statementStack.append(context.createIfStatement(elseLocation, condition, trueBlock, falseBlock, pos.first, pos.second));
}
-
- return context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, statementStack.last(), start, end);
+
+ return context.createIfStatement(ifLocation, condition, trueBlock, statementStack.last(), start, end);
}
template <typename LexerType>
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseExpression(TreeBuilder& context)
{
failIfStackOverflow();
+ JSTokenLocation location(tokenLocation());
TreeExpression node = parseAssignmentExpression(context);
failIfFalse(node);
if (!match(COMMA))
@@ -1031,7 +1061,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseExpression(T
m_nonLHSCount++;
TreeExpression right = parseAssignmentExpression(context);
failIfFalse(right);
- typename TreeBuilder::Comma commaNode = context.createCommaExpr(m_lexer->lastLineNumber(), node, right);
+ typename TreeBuilder::Comma commaNode = context.createCommaExpr(location, node, right);
while (match(COMMA)) {
next(TreeBuilder::DontBuildStrings);
right = parseAssignmentExpression(context);
@@ -1046,6 +1076,7 @@ template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
{
failIfStackOverflow();
int start = tokenStart();
+ JSTokenLocation location(tokenLocation());
int initialAssignmentCount = m_assignmentCount;
int initialNonLHSCount = m_nonLHSCount;
TreeExpression lhs = parseConditionalExpression(context);
@@ -1098,7 +1129,7 @@ end:
return lhs;
while (assignmentStack)
- lhs = context.createAssignment(m_lexer->lastLineNumber(), assignmentStack, lhs, initialAssignmentCount, m_assignmentCount, lastTokenEnd());
+ lhs = context.createAssignment(location, assignmentStack, lhs, initialAssignmentCount, m_assignmentCount, lastTokenEnd());
return lhs;
}
@@ -1106,6 +1137,7 @@ end:
template <typename LexerType>
template <class TreeBuilder> TreeExpression Parser<LexerType>::parseConditionalExpression(TreeBuilder& context)
{
+ JSTokenLocation location(tokenLocation());
TreeExpression cond = parseBinaryExpression(context);
failIfFalse(cond);
if (!match(QUESTION))
@@ -1118,7 +1150,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseConditionalE
TreeExpression rhs = parseAssignmentExpression(context);
failIfFalse(rhs);
- return context.createConditionalExpr(m_lexer->lastLineNumber(), cond, lhs, rhs);
+ return context.createConditionalExpr(location, cond, lhs, rhs);
}
ALWAYS_INLINE static bool isUnaryOp(JSTokenType token)
@@ -1141,6 +1173,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseBinaryExpres
int operandStackDepth = 0;
int operatorStackDepth = 0;
typename TreeBuilder::BinaryExprContext binaryExprContext(context);
+ JSTokenLocation location(tokenLocation());
while (true) {
int exprStart = tokenStart();
int initialAssignments = m_assignmentCount;
@@ -1162,7 +1195,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseBinaryExpres
typename TreeBuilder::BinaryOperand rhs = context.getFromOperandStack(-1);
typename TreeBuilder::BinaryOperand lhs = context.getFromOperandStack(-2);
context.shrinkOperandStackBy(operandStackDepth, 2);
- context.appendBinaryOperation(m_lexer->lastLineNumber(), operandStackDepth, operatorStackDepth, lhs, rhs);
+ context.appendBinaryOperation(location, operandStackDepth, operatorStackDepth, lhs, rhs);
context.operatorStackPop(operatorStackDepth);
}
context.operatorStackAppend(operatorStackDepth, operatorToken, precedence);
@@ -1173,7 +1206,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseBinaryExpres
typename TreeBuilder::BinaryOperand rhs = context.getFromOperandStack(-1);
typename TreeBuilder::BinaryOperand lhs = context.getFromOperandStack(-2);
context.shrinkOperandStackBy(operandStackDepth, 2);
- context.appendBinaryOperation(m_lexer->lastLineNumber(), operandStackDepth, operatorStackDepth, lhs, rhs);
+ context.appendBinaryOperation(location, operandStackDepth, operatorStackDepth, lhs, rhs);
context.operatorStackPop(operatorStackDepth);
}
return context.popOperandStack(operandStackDepth);
@@ -1222,11 +1255,12 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars
numericPropertyName = m_token.m_data.doubleValue;
else
fail();
+ JSTokenLocation location(tokenLocation());
next();
failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
if (stringPropertyName)
- return context.template createGetterOrSetterProperty<complete>(m_lexer->lastLineNumber(), type, stringPropertyName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
- return context.template createGetterOrSetterProperty<complete>(const_cast<JSGlobalData*>(m_globalData), m_lexer->lastLineNumber(), type, numericPropertyName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
+ return context.template createGetterOrSetterProperty<complete>(location, type, stringPropertyName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
+ return context.template createGetterOrSetterProperty<complete>(const_cast<JSGlobalData*>(m_globalData), location, type, numericPropertyName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
}
case NUMBER: {
double propertyName = m_token.m_data.doubleValue;
@@ -1249,12 +1283,13 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLitera
unsigned oldLastLineNumber = m_lexer->lastLineNumber();
unsigned oldLineNumber = m_lexer->lineNumber();
consumeOrFailWithFlags(OPENBRACE, TreeBuilder::DontBuildStrings);
-
+ JSTokenLocation location(tokenLocation());
+
int oldNonLHSCount = m_nonLHSCount;
if (match(CLOSEBRACE)) {
next();
- return context.createObjectLiteral(m_lexer->lastLineNumber());
+ return context.createObjectLiteral(location);
}
TreeProperty property = parseProperty<false>(context);
@@ -1266,13 +1301,14 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLitera
m_lexer->setLineNumber(oldLineNumber);
return parseStrictObjectLiteral(context);
}
- TreePropertyList propertyList = context.createPropertyList(m_lexer->lastLineNumber(), property);
+ TreePropertyList propertyList = context.createPropertyList(location, property);
TreePropertyList tail = propertyList;
while (match(COMMA)) {
next(TreeBuilder::DontBuildStrings);
// allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
if (match(CLOSEBRACE))
break;
+ JSTokenLocation propertyLocation(tokenLocation());
property = parseProperty<false>(context);
failIfFalse(property);
if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
@@ -1282,14 +1318,15 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLitera
m_lexer->setLineNumber(oldLineNumber);
return parseStrictObjectLiteral(context);
}
- tail = context.createPropertyList(m_lexer->lastLineNumber(), property, tail);
+ tail = context.createPropertyList(propertyLocation, property, tail);
}
-
+
+ location = tokenLocation();
consumeOrFail(CLOSEBRACE);
m_nonLHSCount = oldNonLHSCount;
- return context.createObjectLiteral(m_lexer->lastLineNumber(), propertyList);
+ return context.createObjectLiteral(location, propertyList);
}
template <typename LexerType>
@@ -1299,9 +1336,10 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseStrictObject
int oldNonLHSCount = m_nonLHSCount;
+ JSTokenLocation location(tokenLocation());
if (match(CLOSEBRACE)) {
next();
- return context.createObjectLiteral(m_lexer->lastLineNumber());
+ return context.createObjectLiteral(location);
}
TreeProperty property = parseProperty<true>(context);
@@ -1313,13 +1351,14 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseStrictObject
if (!m_syntaxAlreadyValidated)
objectValidator.add(context.getName(property).impl(), context.getType(property));
- TreePropertyList propertyList = context.createPropertyList(m_lexer->lastLineNumber(), property);
+ TreePropertyList propertyList = context.createPropertyList(location, property);
TreePropertyList tail = propertyList;
while (match(COMMA)) {
next();
// allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
if (match(CLOSEBRACE))
break;
+ JSTokenLocation propertyLocation(tokenLocation());
property = parseProperty<true>(context);
failIfFalse(property);
if (!m_syntaxAlreadyValidated) {
@@ -1331,14 +1370,15 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseStrictObject
propertyEntry.iterator->second |= context.getType(property);
}
}
- tail = context.createPropertyList(m_lexer->lastLineNumber(), property, tail);
+ tail = context.createPropertyList(propertyLocation, property, tail);
}
-
+
+ location = tokenLocation();
consumeOrFail(CLOSEBRACE);
m_nonLHSCount = oldNonLHSCount;
- return context.createObjectLiteral(m_lexer->lastLineNumber(), propertyList);
+ return context.createObjectLiteral(location, propertyList);
}
template <typename LexerType>
@@ -1354,8 +1394,9 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrayLiteral
elisions++;
}
if (match(CLOSEBRACKET)) {
+ JSTokenLocation location(tokenLocation());
next(TreeBuilder::DontBuildStrings);
- return context.createArray(m_lexer->lastLineNumber(), elisions);
+ return context.createArray(location, elisions);
}
TreeExpression elem = parseAssignmentExpression(context);
@@ -1373,19 +1414,21 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrayLiteral
}
if (match(CLOSEBRACKET)) {
+ JSTokenLocation location(tokenLocation());
next(TreeBuilder::DontBuildStrings);
- return context.createArray(m_lexer->lastLineNumber(), elisions, elementList);
+ return context.createArray(location, elisions, elementList);
}
TreeExpression elem = parseAssignmentExpression(context);
failIfFalse(elem);
tail = context.createElementList(tail, elisions, elem);
}
-
+
+ JSTokenLocation location(tokenLocation());
consumeOrFail(CLOSEBRACKET);
m_nonLHSCount = oldNonLHSCount;
- return context.createArray(m_lexer->lastLineNumber(), elementList);
+ return context.createArray(location, elementList);
}
template <typename LexerType>
@@ -1409,38 +1452,45 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
return result;
}
case THISTOKEN: {
+ JSTokenLocation location(tokenLocation());
next();
- return context.thisExpr(m_lexer->lastLineNumber());
+ return context.thisExpr(location);
}
case IDENT: {
int start = tokenStart();
const Identifier* ident = m_token.m_data.ident;
+ JSTokenLocation location(tokenLocation());
next();
currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident);
m_lastIdentifier = ident;
- return context.createResolve(m_lexer->lastLineNumber(), ident, start);
+ return context.createResolve(location, ident, start);
}
case STRING: {
const Identifier* ident = m_token.m_data.ident;
+ JSTokenLocation location(tokenLocation());
next();
- return context.createString(m_lexer->lastLineNumber(), ident);
+ return context.createString(location, ident);
}
case NUMBER: {
double d = m_token.m_data.doubleValue;
+ JSTokenLocation location(tokenLocation());
next();
- return context.createNumberExpr(m_lexer->lastLineNumber(), d);
+ return context.createNumberExpr(location, d);
}
case NULLTOKEN: {
+ JSTokenLocation location(tokenLocation());
next();
- return context.createNull(m_lexer->lastLineNumber());
+ return context.createNull(location);
}
case TRUETOKEN: {
+ JSTokenLocation location(tokenLocation());
next();
- return context.createBoolean(m_lexer->lastLineNumber(), true);
+ return context.createBoolean(location, true);
}
case FALSETOKEN: {
+ JSTokenLocation location(tokenLocation());
next();
- return context.createBoolean(m_lexer->lastLineNumber(), false);
+ return context.createBoolean(location, false);
}
case DIVEQUAL:
case DIVIDE: {
@@ -1453,8 +1503,9 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
failIfFalse(m_lexer->scanRegExp(pattern, flags));
int start = tokenStart();
+ JSTokenLocation location(tokenLocation());
next();
- TreeExpression re = context.createRegExp(m_lexer->lastLineNumber(), *pattern, *flags, start);
+ TreeExpression re = context.createRegExp(location, *pattern, *flags, start);
if (!re) {
const char* yarrErrorMsg = Yarr::checkSyntax(pattern->ustring());
ASSERT(!m_errorMessage.isNull());
@@ -1471,6 +1522,7 @@ template <typename LexerType>
template <class TreeBuilder> TreeArguments Parser<LexerType>::parseArguments(TreeBuilder& context)
{
consumeOrFailWithFlags(OPENPAREN, TreeBuilder::DontBuildStrings);
+ JSTokenLocation location(tokenLocation());
if (match(CLOSEPAREN)) {
next(TreeBuilder::DontBuildStrings);
return context.createArguments();
@@ -1478,13 +1530,14 @@ template <class TreeBuilder> TreeArguments Parser<LexerType>::parseArguments(Tre
TreeExpression firstArg = parseAssignmentExpression(context);
failIfFalse(firstArg);
- TreeArgumentsList argList = context.createArgumentsList(m_lexer->lastLineNumber(), firstArg);
+ TreeArgumentsList argList = context.createArgumentsList(location, firstArg);
TreeArgumentsList tail = argList;
while (match(COMMA)) {
+ JSTokenLocation argumentLocation(tokenLocation());
next(TreeBuilder::DontBuildStrings);
TreeExpression arg = parseAssignmentExpression(context);
failIfFalse(arg);
- tail = context.createArgumentsList(m_lexer->lastLineNumber(), tail, arg);
+ tail = context.createArgumentsList(argumentLocation, tail, arg);
}
consumeOrFail(CLOSEPAREN);
return context.createArguments(argList);
@@ -1497,6 +1550,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
int start = tokenStart();
int expressionStart = start;
int newCount = 0;
+ JSTokenLocation location;
while (match(NEW)) {
next();
newCount++;
@@ -1509,14 +1563,16 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
int openBracePos = 0;
int closeBracePos = 0;
int bodyStartLine = 0;
+ location = tokenLocation();
next();
failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
- base = context.createFunctionExpr(m_lexer->lastLineNumber(), name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
+ base = context.createFunctionExpr(location, name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
} else
base = parsePrimaryExpression(context);
failIfFalse(base);
while (true) {
+ location = tokenLocation();
switch (m_token.m_type) {
case OPENBRACKET: {
m_nonTrivialExpressionCount++;
@@ -1526,7 +1582,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
int initialAssignments = m_assignmentCount;
TreeExpression property = parseExpression(context);
failIfFalse(property);
- base = context.createBracketAccess(m_lexer->lastLineNumber(), base, property, initialAssignments != m_assignmentCount, expressionStart, expressionEnd, tokenEnd());
+ base = context.createBracketAccess(location, base, property, initialAssignments != m_assignmentCount, expressionStart, expressionEnd, tokenEnd());
consumeOrFail(CLOSEBRACKET);
m_nonLHSCount = nonLHSCount;
break;
@@ -1539,12 +1595,12 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
int exprEnd = lastTokenEnd();
TreeArguments arguments = parseArguments(context);
failIfFalse(arguments);
- base = context.createNewExpr(m_lexer->lastLineNumber(), base, arguments, start, exprEnd, lastTokenEnd());
+ base = context.createNewExpr(location, base, arguments, start, exprEnd, lastTokenEnd());
} else {
int expressionEnd = lastTokenEnd();
TreeArguments arguments = parseArguments(context);
failIfFalse(arguments);
- base = context.makeFunctionCallNode(m_lexer->lastLineNumber(), base, arguments, expressionStart, expressionEnd, lastTokenEnd());
+ base = context.makeFunctionCallNode(location, base, arguments, expressionStart, expressionEnd, lastTokenEnd());
}
m_nonLHSCount = nonLHSCount;
break;
@@ -1554,7 +1610,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
int expressionEnd = lastTokenEnd();
nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
matchOrFail(IDENT);
- base = context.createDotAccess(m_lexer->lastLineNumber(), base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEnd());
+ base = context.createDotAccess(location, base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEnd());
next();
break;
}
@@ -1564,7 +1620,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
}
endMemberExpression:
while (newCount--)
- base = context.createNewExpr(m_lexer->lastLineNumber(), base, start, lastTokenEnd());
+ base = context.createNewExpr(location, base, start, lastTokenEnd());
return base;
}
@@ -1602,6 +1658,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
m_nonTrivialExpressionCount++;
}
int subExprStart = tokenStart();
+ JSTokenLocation location(tokenLocation());
TreeExpression expr = parseMemberExpression(context);
failIfFalse(expr);
bool isEvalOrArguments = false;
@@ -1614,7 +1671,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
case PLUSPLUS:
m_nonTrivialExpressionCount++;
m_nonLHSCount++;
- expr = context.makePostfixNode(m_lexer->lastLineNumber(), expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd());
+ expr = context.makePostfixNode(location, expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd());
m_assignmentCount++;
failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
failIfTrueIfStrict(requiresLExpr);
@@ -1623,7 +1680,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
case MINUSMINUS:
m_nonTrivialExpressionCount++;
m_nonLHSCount++;
- expr = context.makePostfixNode(m_lexer->lastLineNumber(), expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd());
+ expr = context.makePostfixNode(location, expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd());
m_assignmentCount++;
failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
failIfTrueIfStrict(requiresLExpr);
@@ -1637,40 +1694,42 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
if (!TreeBuilder::CreatesAST && (m_syntaxAlreadyValidated || !strictMode()))
return expr;
-
+
+ location = tokenLocation();
+ location.line = m_lexer->lastLineNumber();
while (tokenStackDepth) {
switch (context.unaryTokenStackLastType(tokenStackDepth)) {
case EXCLAMATION:
- expr = context.createLogicalNot(m_lexer->lastLineNumber(), expr);
+ expr = context.createLogicalNot(location, expr);
break;
case TILDE:
- expr = context.makeBitwiseNotNode(m_lexer->lastLineNumber(), expr);
+ expr = context.makeBitwiseNotNode(location, expr);
break;
case MINUS:
- expr = context.makeNegateNode(m_lexer->lastLineNumber(), expr);
+ expr = context.makeNegateNode(location, expr);
break;
case PLUS:
- expr = context.createUnaryPlus(m_lexer->lastLineNumber(), expr);
+ expr = context.createUnaryPlus(location, expr);
break;
case PLUSPLUS:
case AUTOPLUSPLUS:
- expr = context.makePrefixNode(m_lexer->lastLineNumber(), expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
+ expr = context.makePrefixNode(location, expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
m_assignmentCount++;
break;
case MINUSMINUS:
case AUTOMINUSMINUS:
- expr = context.makePrefixNode(m_lexer->lastLineNumber(), expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
+ expr = context.makePrefixNode(location, expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
m_assignmentCount++;
break;
case TYPEOF:
- expr = context.makeTypeOfNode(m_lexer->lastLineNumber(), expr);
+ expr = context.makeTypeOfNode(location, expr);
break;
case VOIDTOKEN:
- expr = context.createVoid(m_lexer->lastLineNumber(), expr);
+ expr = context.createVoid(location, expr);
break;
case DELETETOKEN:
failIfTrueIfStrictWithNameAndMessage(context.isResolve(expr), "Cannot delete unqualified property", m_lastIdentifier->impl(), "in strict mode");
- expr = context.makeDeleteNode(m_lexer->lastLineNumber(), expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end);
+ expr = context.makeDeleteNode(location, expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end);
break;
default:
// If we get here something has gone horribly horribly wrong
diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h
index c2a11d665..79a95b696 100644
--- a/Source/JavaScriptCore/parser/Parser.h
+++ b/Source/JavaScriptCore/parser/Parser.h
@@ -502,18 +502,18 @@ private:
ALWAYS_INLINE void next(unsigned lexerFlags = 0)
{
- m_lastLine = m_token.m_info.line;
- m_lastTokenEnd = m_token.m_info.endOffset;
+ m_lastLine = m_token.m_location.line;
+ m_lastTokenEnd = m_token.m_location.endOffset;
m_lexer->setLastLineNumber(m_lastLine);
- m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_info, lexerFlags, strictMode());
+ m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_location, lexerFlags, strictMode());
}
ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0)
{
- m_lastLine = m_token.m_info.line;
- m_lastTokenEnd = m_token.m_info.endOffset;
+ m_lastLine = m_token.m_location.line;
+ m_lastTokenEnd = m_token.m_location.endOffset;
m_lexer->setLastLineNumber(m_lastLine);
- m_token.m_type = m_lexer->lexExpectIdentifier(&m_token.m_data, &m_token.m_info, lexerFlags, strictMode());
+ m_token.m_type = m_lexer->lexExpectIdentifier(&m_token.m_data, &m_token.m_location, lexerFlags, strictMode());
}
ALWAYS_INLINE bool nextTokenIsColon()
@@ -541,20 +541,25 @@ private:
ALWAYS_INLINE int tokenStart()
{
- return m_token.m_info.startOffset;
+ return m_token.m_location.startOffset;
}
ALWAYS_INLINE int tokenLine()
{
- return m_token.m_info.line;
+ return m_token.m_location.line;
}
ALWAYS_INLINE int tokenEnd()
{
- return m_token.m_info.endOffset;
+ return m_token.m_location.endOffset;
}
- const char* getTokenName(JSTokenType tok)
+ ALWAYS_INLINE const JSTokenLocation& tokenLocation()
+ {
+ return m_token.m_location;
+ }
+
+ const char* getTokenName(JSTokenType tok)
{
switch (tok) {
case NULLTOKEN:
@@ -1003,8 +1008,11 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(JSGlobalObject* lexicalGlobalObj
RefPtr<ParsedNode> result;
if (m_sourceElements) {
+ JSTokenLocation location;
+ location.line = m_lexer->lastLineNumber();
+ location.column = m_lexer->currentColumnNumber();
result = ParsedNode::create(&lexicalGlobalObject->globalData(),
- m_lexer->lastLineNumber(),
+ location,
m_sourceElements,
m_varDeclarations ? &m_varDeclarations->data : 0,
m_funcDeclarations ? &m_funcDeclarations->data : 0,
@@ -1012,7 +1020,7 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(JSGlobalObject* lexicalGlobalObj
*m_source,
m_features,
m_numConstants);
- result->setLoc(m_source->firstLine(), m_lastLine);
+ result->setLoc(m_source->firstLine(), m_lastLine, m_lexer->currentColumnNumber());
} else if (lexicalGlobalObject) {
// We can never see a syntax error when reparsing a function, since we should have
// reported the error when parsing the containing program or eval code. So if we're
diff --git a/Source/JavaScriptCore/parser/ParserTokens.h b/Source/JavaScriptCore/parser/ParserTokens.h
index a1ea751ac..6e6cec114 100644
--- a/Source/JavaScriptCore/parser/ParserTokens.h
+++ b/Source/JavaScriptCore/parser/ParserTokens.h
@@ -140,17 +140,25 @@ union JSTokenData {
const Identifier* ident;
};
-struct JSTokenInfo {
- JSTokenInfo() : line(0) { }
+struct JSTokenLocation {
+ JSTokenLocation() : line(0), column(0) { }
+ JSTokenLocation(const JSTokenLocation& location)
+ {
+ line = location.line;
+ startOffset = location.startOffset;
+ endOffset = location.endOffset;
+ column = location.column;
+ }
int line;
int startOffset;
int endOffset;
+ int column;
};
struct JSToken {
JSTokenType m_type;
JSTokenData m_data;
- JSTokenInfo m_info;
+ JSTokenLocation m_location;
};
enum JSParserStrictness { JSParseNormal, JSParseStrict };
diff --git a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
index 3662367a0..bfd35648e 100644
--- a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
+++ b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
@@ -53,9 +53,9 @@ public:
JSToken token;
token.m_type = CLOSEBRACE;
token.m_data.intValue = closeBracePos;
- token.m_info.startOffset = closeBracePos;
- token.m_info.endOffset = closeBracePos + 1;
- token.m_info.line = closeBraceLine;
+ token.m_location.startOffset = closeBracePos;
+ token.m_location.endOffset = closeBracePos + 1;
+ token.m_location.line = closeBraceLine;
return token;
}
diff --git a/Source/JavaScriptCore/parser/SyntaxChecker.h b/Source/JavaScriptCore/parser/SyntaxChecker.h
index fe3ce714f..7d44ef3c6 100644
--- a/Source/JavaScriptCore/parser/SyntaxChecker.h
+++ b/Source/JavaScriptCore/parser/SyntaxChecker.h
@@ -119,42 +119,42 @@ public:
static const unsigned DontBuildStrings = LexerFlagsDontBuildStrings;
int createSourceElements() { return 1; }
- ExpressionType makeFunctionCallNode(int, int, int, int, int, int) { return CallExpr; }
+ ExpressionType makeFunctionCallNode(const JSTokenLocation&, int, int, int, int, int) { return CallExpr; }
void appendToComma(ExpressionType& base, ExpressionType right) { base = right; }
- ExpressionType createCommaExpr(int, ExpressionType, ExpressionType right) { return right; }
- ExpressionType makeAssignNode(int, ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; }
- ExpressionType makePrefixNode(int, ExpressionType, Operator, int, int, int) { return PreExpr; }
- ExpressionType makePostfixNode(int, ExpressionType, Operator, int, int, int) { return PostExpr; }
- ExpressionType makeTypeOfNode(int, ExpressionType) { return TypeofExpr; }
- ExpressionType makeDeleteNode(int, ExpressionType, int, int, int) { return DeleteExpr; }
- ExpressionType makeNegateNode(int, ExpressionType) { return UnaryExpr; }
- ExpressionType makeBitwiseNotNode(int, ExpressionType) { return UnaryExpr; }
- ExpressionType createLogicalNot(int, ExpressionType) { return UnaryExpr; }
- ExpressionType createUnaryPlus(int, ExpressionType) { return UnaryExpr; }
- ExpressionType createVoid(int, ExpressionType) { return UnaryExpr; }
- ExpressionType thisExpr(int) { return ThisExpr; }
- ExpressionType createResolve(int, const Identifier*, int) { return ResolveExpr; }
- ExpressionType createObjectLiteral(int) { return ObjectLiteralExpr; }
- ExpressionType createObjectLiteral(int, int) { return ObjectLiteralExpr; }
- ExpressionType createArray(int, int) { return ArrayLiteralExpr; }
- ExpressionType createArray(int, int, int) { return ArrayLiteralExpr; }
- ExpressionType createNumberExpr(int, double) { return NumberExpr; }
- ExpressionType createString(int, const Identifier*) { return StringExpr; }
- ExpressionType createBoolean(int, bool) { return BoolExpr; }
- ExpressionType createNull(int) { return NullExpr; }
- ExpressionType createBracketAccess(int, ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; }
- ExpressionType createDotAccess(int, ExpressionType, const Identifier*, int, int, int) { return DotExpr; }
- ExpressionType createRegExp(int, const Identifier& pattern, const Identifier&, int) { return Yarr::checkSyntax(pattern.ustring()) ? 0 : RegExpExpr; }
- ExpressionType createNewExpr(int, ExpressionType, int, int, int, int) { return NewExpr; }
- ExpressionType createNewExpr(int, ExpressionType, int, int) { return NewExpr; }
- ExpressionType createConditionalExpr(int, ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; }
- ExpressionType createAssignResolve(int, const Identifier&, ExpressionType, int, int, int) { return AssignmentExpr; }
- ExpressionType createFunctionExpr(int, const Identifier*, int, int, int, int, int, int) { return FunctionExpr; }
- int createFunctionBody(int, bool) { return 1; }
+ ExpressionType createCommaExpr(const JSTokenLocation&, ExpressionType, ExpressionType right) { return right; }
+ ExpressionType makeAssignNode(const JSTokenLocation&, ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; }
+ ExpressionType makePrefixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int) { return PreExpr; }
+ ExpressionType makePostfixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int) { return PostExpr; }
+ ExpressionType makeTypeOfNode(const JSTokenLocation&, ExpressionType) { return TypeofExpr; }
+ ExpressionType makeDeleteNode(const JSTokenLocation&, ExpressionType, int, int, int) { return DeleteExpr; }
+ ExpressionType makeNegateNode(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
+ ExpressionType makeBitwiseNotNode(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
+ ExpressionType createLogicalNot(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
+ ExpressionType createUnaryPlus(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
+ ExpressionType createVoid(const JSTokenLocation&, ExpressionType) { return UnaryExpr; }
+ ExpressionType thisExpr(const JSTokenLocation&) { return ThisExpr; }
+ ExpressionType createResolve(const JSTokenLocation&, const Identifier*, int) { return ResolveExpr; }
+ ExpressionType createObjectLiteral(const JSTokenLocation&) { return ObjectLiteralExpr; }
+ ExpressionType createObjectLiteral(const JSTokenLocation&, int) { return ObjectLiteralExpr; }
+ ExpressionType createArray(const JSTokenLocation&, int) { return ArrayLiteralExpr; }
+ ExpressionType createArray(const JSTokenLocation&, int, int) { return ArrayLiteralExpr; }
+ ExpressionType createNumberExpr(const JSTokenLocation&, double) { return NumberExpr; }
+ ExpressionType createString(const JSTokenLocation&, const Identifier*) { return StringExpr; }
+ ExpressionType createBoolean(const JSTokenLocation&, bool) { return BoolExpr; }
+ ExpressionType createNull(const JSTokenLocation&) { return NullExpr; }
+ ExpressionType createBracketAccess(const JSTokenLocation&, ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; }
+ ExpressionType createDotAccess(const JSTokenLocation&, ExpressionType, const Identifier*, int, int, int) { return DotExpr; }
+ ExpressionType createRegExp(const JSTokenLocation&, const Identifier& pattern, const Identifier&, int) { return Yarr::checkSyntax(pattern.ustring()) ? 0 : RegExpExpr; }
+ ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int, int, int) { return NewExpr; }
+ ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int) { return NewExpr; }
+ ExpressionType createConditionalExpr(const JSTokenLocation&, ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; }
+ ExpressionType createAssignResolve(const JSTokenLocation&, const Identifier&, ExpressionType, int, int, int) { return AssignmentExpr; }
+ ExpressionType createFunctionExpr(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int) { return FunctionExpr; }
+ int createFunctionBody(const JSTokenLocation&, bool) { return 1; }
int createArguments() { return 1; }
int createArguments(int) { return 1; }
- int createArgumentsList(int, int) { return 1; }
- int createArgumentsList(int, int, int) { return 1; }
+ int createArgumentsList(const JSTokenLocation&, int) { return 1; }
+ int createArgumentsList(const JSTokenLocation&, int, int) { return 1; }
template <bool complete> Property createProperty(const Identifier* name, int, PropertyNode::Type type)
{
if (!complete)
@@ -168,8 +168,8 @@ public:
return Property(type);
return Property(&globalData->parserArena->identifierArena().makeNumericIdentifier(globalData, name), type);
}
- int createPropertyList(int, Property) { return 1; }
- int createPropertyList(int, Property, int) { return 1; }
+ int createPropertyList(const JSTokenLocation&, Property) { return 1; }
+ int createPropertyList(const JSTokenLocation&, Property, int) { return 1; }
int createElementList(int, int) { return 1; }
int createElementList(int, int, int) { return 1; }
int createFormalParameterList(const Identifier&) { return 1; }
@@ -178,39 +178,39 @@ public:
int createClauseList(int) { return 1; }
int createClauseList(int, int) { return 1; }
void setUsesArguments(int) { }
- int createFuncDeclStatement(int, const Identifier*, int, int, int, int, int, int) { return 1; }
- int createBlockStatement(int, int, int, int) { return 1; }
- int createExprStatement(int, int, int, int) { return 1; }
- int createIfStatement(int, int, int, int, int) { return 1; }
- int createIfStatement(int, int, int, int, int, int) { return 1; }
- int createForLoop(int, int, int, int, int, int, int) { return 1; }
- int createForInLoop(int, const Identifier*, int, int, int, int, int, int, int, int, int, int) { return 1; }
- int createForInLoop(int, int, int, int, int, int, int, int, int) { return 1; }
- int createEmptyStatement(int) { return 1; }
- int createVarStatement(int, int, int, int) { return 1; }
- int createReturnStatement(int, int, int, int, int, int) { return 1; }
- int createBreakStatement(int, int, int, int, int) { return 1; }
- int createBreakStatement(int, const Identifier*, int, int, int, int) { return 1; }
- int createContinueStatement(int, int, int, int, int) { return 1; }
- int createContinueStatement(int, const Identifier*, int, int, int, int) { return 1; }
- int createTryStatement(int, int, const Identifier*, int, int, int, int) { return 1; }
- int createSwitchStatement(int, int, int, int, int, int, int) { return 1; }
- int createWhileStatement(int, int, int, int, int) { return 1; }
- int createWithStatement(int, int, int, int, int, int, int) { return 1; }
- int createDoWhileStatement(int, int, int, int, int) { return 1; }
- int createLabelStatement(int, const Identifier*, int, int, int) { return 1; }
- int createThrowStatement(int, int, int, int, int, int) { return 1; }
- int createDebugger(int, int, int) { return 1; }
- int createConstStatement(int, int, int, int) { return 1; }
- int appendConstDecl(int, int, const Identifier*, int) { return 1; }
- template <bool strict> Property createGetterOrSetterProperty(int, PropertyNode::Type type, const Identifier* name, int, int, int, int, int, int)
+ int createFuncDeclStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int) { return 1; }
+ int createBlockStatement(const JSTokenLocation&, int, int, int) { return 1; }
+ int createExprStatement(const JSTokenLocation&, int, int, int) { return 1; }
+ int createIfStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
+ int createIfStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; }
+ int createForLoop(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
+ int createForInLoop(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int, int, int, int) { return 1; }
+ int createForInLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int) { return 1; }
+ int createEmptyStatement(const JSTokenLocation&) { return 1; }
+ int createVarStatement(const JSTokenLocation&, int, int, int) { return 1; }
+ int createReturnStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; }
+ int createBreakStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
+ int createBreakStatement(const JSTokenLocation&, const Identifier*, int, int, int, int) { return 1; }
+ int createContinueStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
+ int createContinueStatement(const JSTokenLocation&, const Identifier*, int, int, int, int) { return 1; }
+ int createTryStatement(const JSTokenLocation&, int, const Identifier*, int, int, int, int) { return 1; }
+ int createSwitchStatement(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
+ int createWhileStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
+ int createWithStatement(const JSTokenLocation&, int, int, int, int, int, int) { return 1; }
+ int createDoWhileStatement(const JSTokenLocation&, int, int, int, int) { return 1; }
+ int createLabelStatement(const JSTokenLocation&, const Identifier*, int, int, int) { return 1; }
+ int createThrowStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; }
+ int createDebugger(const JSTokenLocation&, int, int) { return 1; }
+ int createConstStatement(const JSTokenLocation&, int, int, int) { return 1; }
+ int appendConstDecl(const JSTokenLocation&, int, const Identifier*, int) { return 1; }
+ template <bool strict> Property createGetterOrSetterProperty(const JSTokenLocation&, PropertyNode::Type type, const Identifier* name, int, int, int, int, int, int)
{
ASSERT(name);
if (!strict)
return Property(type);
return Property(name, type);
}
- template <bool strict> Property createGetterOrSetterProperty(JSGlobalData* globalData, int, PropertyNode::Type type, double name, int, int, int, int, int, int)
+ template <bool strict> Property createGetterOrSetterProperty(JSGlobalData* globalData, const JSTokenLocation&, PropertyNode::Type type, double name, int, int, int, int, int, int)
{
if (!strict)
return Property(type);
@@ -219,7 +219,7 @@ public:
void appendStatement(int, int) { }
void addVar(const Identifier*, bool) { }
- int combineCommaNodes(int, int, int) { return 1; }
+ int combineCommaNodes(const JSTokenLocation&, int, int) { return 1; }
int evalCount() const { return 0; }
void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool)
{
@@ -235,7 +235,7 @@ public:
bool operatorStackHasHigherPrecedence(int&, int) { return true; }
BinaryOperand getFromOperandStack(int) { return m_topBinaryExpr; }
void shrinkOperandStackBy(int& operandStackDepth, int amount) { operandStackDepth -= amount; }
- void appendBinaryOperation(int, int& operandStackDepth, int&, BinaryOperand, BinaryOperand) { operandStackDepth++; }
+ void appendBinaryOperation(const JSTokenLocation&, int& operandStackDepth, int&, BinaryOperand, BinaryOperand) { operandStackDepth++; }
void operatorStackAppend(int& operatorStackDepth, int, int) { operatorStackDepth++; }
int popOperandStack(int&) { int res = m_topBinaryExpr; m_topBinaryExpr = 0; return res; }
@@ -245,7 +245,7 @@ public:
void unaryTokenStackRemoveLast(int& stackDepth) { stackDepth = 0; }
void assignmentStackAppend(int, int, int, int, int, Operator) { }
- int createAssignment(int, int, int, int, int, int) { ASSERT_NOT_REACHED(); return 1; }
+ int createAssignment(const JSTokenLocation&, int, int, int, int, int) { ASSERT_NOT_REACHED(); return 1; }
const Identifier& getName(const Property& property) const { ASSERT(property.name); return *property.name; }
PropertyNode::Type getType(const Property& property) const { return property.type; }
bool isResolve(ExpressionType expr) const { return expr == ResolveExpr || expr == ResolveEvalExpr; }
diff --git a/Source/JavaScriptCore/runtime/CommonIdentifiers.cpp b/Source/JavaScriptCore/runtime/CommonIdentifiers.cpp
index 82beda336..e929d7a49 100644
--- a/Source/JavaScriptCore/runtime/CommonIdentifiers.cpp
+++ b/Source/JavaScriptCore/runtime/CommonIdentifiers.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2007, 2009, 2012 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,14 +23,12 @@
namespace JSC {
-static const char* const nullCString = 0;
-
#define INITIALIZE_PROPERTY_NAME(name) , name(globalData, #name)
#define INITIALIZE_KEYWORD(name) , name##Keyword(globalData, #name)
CommonIdentifiers::CommonIdentifiers(JSGlobalData* globalData)
- : nullIdentifier(globalData, nullCString)
- , emptyIdentifier(globalData, "")
+ : nullIdentifier()
+ , emptyIdentifier(Identifier::EmptyIdentifier)
, underscoreProto(globalData, "__proto__")
, thisIdentifier(globalData, "this")
, useStrictIdentifier(globalData, "use strict")
diff --git a/Source/JavaScriptCore/runtime/DateConstructor.cpp b/Source/JavaScriptCore/runtime/DateConstructor.cpp
index 5984bbf97..e4f89dd37 100644
--- a/Source/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/DateConstructor.cpp
@@ -168,11 +168,7 @@ static EncodedJSValue JSC_HOST_CALL callDate(ExecState* exec)
{
GregorianDateTime ts;
msToGregorianDateTime(exec, currentTimeMS(), false, ts);
- DateConversionBuffer date;
- DateConversionBuffer time;
- formatDate(ts, date);
- formatTime(ts, time);
- return JSValue::encode(jsMakeNontrivialString(exec, date, " ", time));
+ return JSValue::encode(jsNontrivialString(exec, formatDateTime(ts, DateTimeFormatDateAndTime, false)));
}
CallType DateConstructor::getCallData(JSCell*, CallData& callData)
diff --git a/Source/JavaScriptCore/runtime/DateConversion.cpp b/Source/JavaScriptCore/runtime/DateConversion.cpp
index 706ffe9a2..47839817f 100644
--- a/Source/JavaScriptCore/runtime/DateConversion.cpp
+++ b/Source/JavaScriptCore/runtime/DateConversion.cpp
@@ -1,95 +1,127 @@
/*
- * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com>
*
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
+ * 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.
*
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Alternatively, the contents of this file may be used under the terms
- * of either the Mozilla Public License Version 1.1, found at
- * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
- * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
- * (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above. If you wish to allow use of your
- * version of this file only under the terms of one of those two
- * licenses (the MPL or the GPL) and not to allow others to use your
- * version of this file under the LGPL, indicate your decision by
- * deletingthe provisions above and replace them with the notice and
- * other provisions required by the MPL or the GPL, as the case may be.
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under any of the LGPL, the MPL or the GPL.
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "DateConversion.h"
-#include "CallFrame.h"
-#include "JSDateMath.h"
-#include "JSObject.h"
-#include "ScopeChain.h"
#include "UString.h"
-#include <wtf/StringExtras.h>
-#include <wtf/text/CString.h>
+#include <wtf/Assertions.h>
+#include <wtf/DateMath.h>
+#include <wtf/text/StringBuilder.h>
+
+#if OS(WINDOWS)
+#include <windows.h>
+#endif
using namespace WTF;
namespace JSC {
-void formatDate(const GregorianDateTime &t, DateConversionBuffer& buffer)
+template<int width>
+static inline void appendNumber(StringBuilder& builder, int value)
{
- snprintf(buffer, DateConversionBufferSize, "%s %s %02d %04d",
- weekdayName[(t.weekDay() + 6) % 7],
- monthName[t.month()], t.monthDay(), t.year());
+ int fillingZerosCount = width;
+ if (value < 0) {
+ builder.append('-');
+ value = -value;
+ --fillingZerosCount;
+ }
+ String valueString = String::number(value);
+ fillingZerosCount -= valueString.length();
+ for (int i = 0; i < fillingZerosCount; ++i)
+ builder.append('0');
+ builder.append(valueString);
}
-void formatDateUTCVariant(const GregorianDateTime &t, DateConversionBuffer& buffer)
+template<>
+void appendNumber<2>(StringBuilder& builder, int value)
{
- snprintf(buffer, DateConversionBufferSize, "%s, %02d %s %04d",
- weekdayName[(t.weekDay() + 6) % 7],
- t.monthDay(), monthName[t.month()], t.year());
+ ASSERT(0 <= value && value <= 99);
+ builder.append(static_cast<char>('0' + value / 10));
+ builder.append(static_cast<char>('0' + value % 10));
}
-void formatTime(const GregorianDateTime &t, DateConversionBuffer& buffer)
+UString formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool asUTCVariant)
{
- int offset = abs(t.utcOffset());
- char timeZoneName[70];
- struct tm gtm = t;
- strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
-
- if (timeZoneName[0]) {
- snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d (%s)",
- t.hour(), t.minute(), t.second(),
- t.utcOffset() < 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(),
- t.utcOffset() < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
+ bool appendDate = format & DateTimeFormatDate;
+ bool appendTime = format & DateTimeFormatTime;
+
+ StringBuilder builder;
+
+ if (appendDate) {
+ builder.append(weekdayName[(t.weekDay() + 6) % 7]);
+
+ if (asUTCVariant) {
+ builder.append(", ");
+ appendNumber<2>(builder, t.monthDay());
+ builder.append(' ');
+ builder.append(monthName[t.month()]);
+ } else {
+ builder.append(' ');
+ builder.append(monthName[t.month()]);
+ builder.append(' ');
+ appendNumber<2>(builder, t.monthDay());
+ }
+ builder.append(' ');
+ appendNumber<4>(builder, t.year());
}
-}
-void formatTimeUTC(const GregorianDateTime &t, DateConversionBuffer& buffer)
-{
- snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT", t.hour(), t.minute(), t.second());
+ if (appendDate && appendTime)
+ builder.append(' ');
+
+ if (appendTime) {
+ appendNumber<2>(builder, t.hour());
+ builder.append(':');
+ appendNumber<2>(builder, t.minute());
+ builder.append(':');
+ appendNumber<2>(builder, t.second());
+ builder.append(" GMT");
+
+ if (!asUTCVariant) {
+ int offset = abs(t.utcOffset()) / 60;
+ builder.append(t.utcOffset() < 0 ? '-' : '+');
+ appendNumber<2>(builder, offset / 60);
+ appendNumber<2>(builder, offset % 60);
+
+#if OS(WINDOWS)
+ TIME_ZONE_INFORMATION timeZoneInformation;
+ GetTimeZoneInformation(&timeZoneInformation);
+ const WCHAR* timeZoneName = t.isDST() ? timeZoneInformation.DaylightName : timeZoneInformation.StandardName;
+#else
+ struct tm gtm = t;
+ char timeZoneName[70];
+ strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
+#endif
+ if (timeZoneName[0]) {
+ builder.append(" (");
+ builder.append(timeZoneName);
+ builder.append(')');
+ }
+ }
+ }
+
+ return builder.toString().impl();
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/DateConversion.h b/Source/JavaScriptCore/runtime/DateConversion.h
index 0b078cd34..fd1a7eb35 100644
--- a/Source/JavaScriptCore/runtime/DateConversion.h
+++ b/Source/JavaScriptCore/runtime/DateConversion.h
@@ -1,42 +1,25 @@
/*
- * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
+ * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DateConversion_h
@@ -46,15 +29,15 @@
namespace JSC {
-class ExecState;
+class UString;
-static const unsigned DateConversionBufferSize = 100;
-typedef char DateConversionBuffer[DateConversionBufferSize];
+enum DateTimeFormat {
+ DateTimeFormatDate = 1,
+ DateTimeFormatTime = 2,
+ DateTimeFormatDateAndTime = DateTimeFormatDate | DateTimeFormatTime
+};
-void formatDate(const GregorianDateTime&, DateConversionBuffer&);
-void formatDateUTCVariant(const GregorianDateTime&, DateConversionBuffer&);
-void formatTime(const GregorianDateTime&, DateConversionBuffer&);
-void formatTimeUTC(const GregorianDateTime&, DateConversionBuffer&);
+UString formatDateTime(const GregorianDateTime&, DateTimeFormat, bool asUTCVariant);
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp
index 7cbab0497..363eec03a 100644
--- a/Source/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp
@@ -340,6 +340,23 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, doubl
#endif // !PLATFORM(MAC) && !PLATFORM(IOS)
+static EncodedJSValue formateDateInstance(ExecState* exec, DateTimeFormat format, bool asUTCVariant)
+{
+ JSValue thisValue = exec->hostThisValue();
+ if (!thisValue.inherits(&DateInstance::s_info))
+ return throwVMTypeError(exec);
+
+ DateInstance* thisDateObj = asDateInstance(thisValue);
+
+ const GregorianDateTime* gregorianDateTime = asUTCVariant
+ ? thisDateObj->gregorianDateTimeUTC(exec)
+ : thisDateObj->gregorianDateTime(exec);
+ if (!gregorianDateTime)
+ return JSValue::encode(jsNontrivialString(exec, "Invalid Date"));
+
+ return JSValue::encode(jsNontrivialString(exec, formatDateTime(*gregorianDateTime, format, asUTCVariant)));
+}
+
// Converts a list of arguments sent to a Date member function into milliseconds, updating
// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately.
//
@@ -513,38 +530,14 @@ bool DatePrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec,
EncodedJSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec)
{
- JSValue thisValue = exec->hostThisValue();
- if (!thisValue.inherits(&DateInstance::s_info))
- return throwVMTypeError(exec);
-
- DateInstance* thisDateObj = asDateInstance(thisValue);
-
- const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
- if (!gregorianDateTime)
- return JSValue::encode(jsNontrivialString(exec, "Invalid Date"));
- DateConversionBuffer date;
- DateConversionBuffer time;
- formatDate(*gregorianDateTime, date);
- formatTime(*gregorianDateTime, time);
- return JSValue::encode(jsMakeNontrivialString(exec, date, " ", time));
+ const bool asUTCVariant = false;
+ return formateDateInstance(exec, DateTimeFormatDateAndTime, asUTCVariant);
}
EncodedJSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec)
{
- JSValue thisValue = exec->hostThisValue();
- if (!thisValue.inherits(&DateInstance::s_info))
- return throwVMTypeError(exec);
-
- DateInstance* thisDateObj = asDateInstance(thisValue);
-
- const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
- if (!gregorianDateTime)
- return JSValue::encode(jsNontrivialString(exec, "Invalid Date"));
- DateConversionBuffer date;
- DateConversionBuffer time;
- formatDateUTCVariant(*gregorianDateTime, date);
- formatTimeUTC(*gregorianDateTime, time);
- return JSValue::encode(jsMakeNontrivialString(exec, date, " ", time));
+ const bool asUTCVariant = true;
+ return formateDateInstance(exec, DateTimeFormatDateAndTime, asUTCVariant);
}
EncodedJSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec)
@@ -577,34 +570,14 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec)
EncodedJSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec)
{
- JSValue thisValue = exec->hostThisValue();
- if (!thisValue.inherits(&DateInstance::s_info))
- return throwVMTypeError(exec);
-
- DateInstance* thisDateObj = asDateInstance(thisValue);
-
- const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
- if (!gregorianDateTime)
- return JSValue::encode(jsNontrivialString(exec, "Invalid Date"));
- DateConversionBuffer date;
- formatDate(*gregorianDateTime, date);
- return JSValue::encode(jsNontrivialString(exec, date));
+ const bool asUTCVariant = false;
+ return formateDateInstance(exec, DateTimeFormatDate, asUTCVariant);
}
EncodedJSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec)
{
- JSValue thisValue = exec->hostThisValue();
- if (!thisValue.inherits(&DateInstance::s_info))
- return throwVMTypeError(exec);
-
- DateInstance* thisDateObj = asDateInstance(thisValue);
-
- const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
- if (!gregorianDateTime)
- return JSValue::encode(jsNontrivialString(exec, "Invalid Date"));
- DateConversionBuffer time;
- formatTime(*gregorianDateTime, time);
- return JSValue::encode(jsNontrivialString(exec, time));
+ const bool asUTCVariant = false;
+ return formateDateInstance(exec, DateTimeFormatTime, asUTCVariant);
}
EncodedJSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec)
@@ -676,20 +649,8 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec)
EncodedJSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec)
{
- JSValue thisValue = exec->hostThisValue();
- if (!thisValue.inherits(&DateInstance::s_info))
- return throwVMTypeError(exec);
-
- DateInstance* thisDateObj = asDateInstance(thisValue);
-
- const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
- if (!gregorianDateTime)
- return JSValue::encode(jsNontrivialString(exec, "Invalid Date"));
- DateConversionBuffer date;
- DateConversionBuffer time;
- formatDateUTCVariant(*gregorianDateTime, date);
- formatTimeUTC(*gregorianDateTime, time);
- return JSValue::encode(jsMakeNontrivialString(exec, date, " ", time));
+ const bool asUTCVariant = true;
+ return formateDateInstance(exec, DateTimeFormatDateAndTime, asUTCVariant);
}
EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec)
diff --git a/Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp b/Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp
index c052c61ba..35b992567 100644
--- a/Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp
+++ b/Source/JavaScriptCore/runtime/GCActivityCallbackBlackBerry.cpp
@@ -25,8 +25,6 @@
namespace JSC {
-static const size_t bytesWorthGC = 4 * 1024 * 1024;
-
DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap)
: GCActivityCallback(heap->globalData())
{
@@ -40,7 +38,7 @@ void DefaultGCActivityCallback::doWork()
void DefaultGCActivityCallback::didAllocate(size_t bytesAllocated)
{
- if (bytesAllocated < bytesWorthGC || m_timer.started())
+ if (m_timer.started())
return;
// Try using ~5% CPU time.
diff --git a/Source/JavaScriptCore/runtime/Identifier.cpp b/Source/JavaScriptCore/runtime/Identifier.cpp
index 20770928c..0fc54f3c6 100644
--- a/Source/JavaScriptCore/runtime/Identifier.cpp
+++ b/Source/JavaScriptCore/runtime/Identifier.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2012 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
@@ -46,10 +46,10 @@ void deleteIdentifierTable(IdentifierTable* table)
delete table;
}
-struct IdentifierCStringTranslator {
+struct IdentifierASCIIStringTranslator {
static unsigned hash(const LChar* c)
{
- return StringHasher::computeHash<LChar>(c);
+ return StringHasher::computeHashAndMaskTop8Bits<LChar>(c);
}
static bool equal(StringImpl* r, const LChar* s)
@@ -60,19 +60,15 @@ struct IdentifierCStringTranslator {
static void translate(StringImpl*& location, const LChar* c, unsigned hash)
{
size_t length = strlen(reinterpret_cast<const char*>(c));
- LChar* d;
- StringImpl* r = StringImpl::createUninitialized(length, d).leakRef();
- for (size_t i = 0; i != length; i++)
- d[i] = c[i];
- r->setHash(hash);
- location = r;
+ location = StringImpl::createFromLiteral(reinterpret_cast<const char*>(c), length).leakRef();
+ location->setHash(hash);
}
};
struct IdentifierLCharFromUCharTranslator {
static unsigned hash(const CharBuffer<UChar>& buf)
{
- return StringHasher::computeHash<UChar>(buf.s, buf.length);
+ return StringHasher::computeHashAndMaskTop8Bits<UChar>(buf.s, buf.length);
}
static bool equal(StringImpl* str, const CharBuffer<UChar>& buf)
@@ -96,10 +92,8 @@ struct IdentifierLCharFromUCharTranslator {
PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const char* c)
{
- if (!c)
- return 0;
- if (!c[0])
- return StringImpl::empty();
+ ASSERT(c);
+ ASSERT(c[0]);
if (!c[1])
return add(globalData, globalData->smallStrings.singleCharacterStringRep(c[0]));
@@ -110,7 +104,7 @@ PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const char* c)
if (iter != literalIdentifierTable.end())
return iter->second;
- HashSet<StringImpl*>::AddResult addResult = identifierTable.add<const LChar*, IdentifierCStringTranslator>(reinterpret_cast<const LChar*>(c));
+ HashSet<StringImpl*>::AddResult addResult = identifierTable.add<const LChar*, IdentifierASCIIStringTranslator>(reinterpret_cast<const LChar*>(c));
// If the string is newly-translated, then we need to adopt it.
// The boolean in the pair tells us if that is so.
diff --git a/Source/JavaScriptCore/runtime/Identifier.h b/Source/JavaScriptCore/runtime/Identifier.h
index 7b7907983..196fdca23 100644
--- a/Source/JavaScriptCore/runtime/Identifier.h
+++ b/Source/JavaScriptCore/runtime/Identifier.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2012 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
@@ -35,12 +35,18 @@ namespace JSC {
friend class Structure;
public:
Identifier() { }
+ enum EmptyIdentifierFlag { EmptyIdentifier };
+ Identifier(EmptyIdentifierFlag) : m_string(StringImpl::empty()) { }
- Identifier(ExecState* exec, const char* s) : m_string(add(exec, s)) { } // Only to be used with string literals.
- Identifier(ExecState* exec, StringImpl* rep) : m_string(add(exec, rep)) { }
+ // Only to be used with string literals.
+ template<unsigned charactersCount>
+ Identifier(ExecState* exec, const char (&characters)[charactersCount]) : m_string(add(exec, characters)) { }
+ template<unsigned charactersCount>
+ Identifier(JSGlobalData* globalData, const char (&characters)[charactersCount]) : m_string(add(globalData, characters)) { }
+
+ Identifier(ExecState* exec, StringImpl* rep) : m_string(add(exec, rep)) { }
Identifier(ExecState* exec, const UString& s) : m_string(add(exec, s.impl())) { }
- Identifier(JSGlobalData* globalData, const char* s) : m_string(add(globalData, s)) { } // Only to be used with string literals.
Identifier(JSGlobalData* globalData, const LChar* s, int length) : m_string(add(globalData, s, length)) { }
Identifier(JSGlobalData* globalData, const UChar* s, int length) : m_string(add(globalData, s, length)) { }
Identifier(JSGlobalData* globalData, StringImpl* rep) : m_string(add(globalData, rep)) { }
@@ -80,8 +86,9 @@ namespace JSC {
static bool equal(const StringImpl*, const UChar*, unsigned length);
static bool equal(const StringImpl* a, const StringImpl* b) { return ::equal(a, b); }
- JS_EXPORT_PRIVATE static PassRefPtr<StringImpl> add(ExecState*, const char*); // Only to be used with string literals.
- static PassRefPtr<StringImpl> add(JSGlobalData*, const char*); // Only to be used with string literals.
+ // Only to be used with string literals.
+ static PassRefPtr<StringImpl> add(JSGlobalData*, const char*);
+ JS_EXPORT_PRIVATE static PassRefPtr<StringImpl> add(ExecState*, const char*);
private:
UString m_string;
@@ -143,7 +150,7 @@ namespace JSC {
struct IdentifierCharBufferTranslator {
static unsigned hash(const CharBuffer<T>& buf)
{
- return StringHasher::computeHash<T>(buf.s, buf.length);
+ return StringHasher::computeHashAndMaskTop8Bits<T>(buf.s, buf.length);
}
static bool equal(StringImpl* str, const CharBuffer<T>& buf)
diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h
index cdd409706..90e531cec 100644
--- a/Source/JavaScriptCore/runtime/JSCell.h
+++ b/Source/JavaScriptCore/runtime/JSCell.h
@@ -192,11 +192,6 @@ namespace JSC {
return m_structure.get();
}
- inline const ClassInfo* JSCell::classInfo() const
- {
- return m_classInfo;
- }
-
inline void JSCell::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
MARK_LOG_PARENT(visitor, cell);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
index dd05005c7..2d6d1e54f 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -223,9 +223,7 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
JSGlobalData::~JSGlobalData()
{
ASSERT(!m_apiLock.currentThreadIsHoldingLock());
- heap.activityCallback()->didStartVMShutdown();
- heap.sweeper()->didStartVMShutdown();
- heap.lastChanceToFinalize();
+ heap.didStartVMShutdown();
delete interpreter;
#ifndef NDEBUG
diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h
index 0a55bda6b..ab3f34bb6 100644
--- a/Source/JavaScriptCore/runtime/Options.h
+++ b/Source/JavaScriptCore/runtime/Options.h
@@ -109,6 +109,7 @@ namespace JSC {
v(double, desiredProfileFullnessRate, 0.35) \
\
v(double, doubleVoteRatioForDoubleFormat, 2) \
+ v(double, structureCheckVoteRatioForHoisting, 1) \
\
v(unsigned, minimumNumberOfScansBetweenRebalance, 100) \
v(unsigned, gcMarkStackSegmentSize, pageSize()) \
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index 8e41781e2..ee0b573d9 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -602,6 +602,15 @@ namespace JSC {
ASSERT(m_structure || !globalData.structureStructure);
}
+ inline const ClassInfo* JSCell::classInfo() const
+ {
+#if ENABLE(GC_VALIDATION)
+ return m_structure.unvalidatedGet()->classInfo();
+#else
+ return m_structure->classInfo();
+#endif
+ }
+
} // namespace JSC
#endif // Structure_h
diff --git a/Source/JavaScriptCore/runtime/TimeoutChecker.cpp b/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
index 8f3d1a578..56d6d4b71 100644
--- a/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
+++ b/Source/JavaScriptCore/runtime/TimeoutChecker.cpp
@@ -80,6 +80,11 @@ static inline unsigned getCPUTime()
GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000;
+#elif OS(QNX)
+ struct timespec time;
+ if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time))
+ CRASH();
+ return time.tv_sec * 1000.0 + time.tv_nsec / 1.0e6;
#else
// FIXME: We should return the time the current thread has spent executing.