Web Inspector: [JSC] implement setting breakpoints by line:column
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Aug 2012 04:49:25 +0000 (04:49 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Aug 2012 04:49:25 +0000 (04:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=53003

Patch by Peter Wang <peter.wang@torchmobile.com.cn> on 2012-08-01
Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

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):

Source/WebCore:

As JSC is enabled to provide column info of statement, ScriptDebugServer can use it to
support "Pretty Print" debug mode.

No new test case for this patch.

* bindings/js/ScriptDebugServer.cpp:
(WebCore::ScriptDebugServer::setBreakpoint):
(WebCore::ScriptDebugServer::removeBreakpoint):
(WebCore):
(WebCore::ScriptDebugServer::updateCurrentStatementPosition):
(WebCore::ScriptDebugServer::hasBreakpoint):
(WebCore::ScriptDebugServer::createCallFrameAndPauseIfNeeded):
(WebCore::ScriptDebugServer::updateCallFrameAndPauseIfNeeded):
(WebCore::ScriptDebugServer::callEvent):
(WebCore::ScriptDebugServer::atStatement):
(WebCore::ScriptDebugServer::returnEvent):
(WebCore::ScriptDebugServer::exception):
(WebCore::ScriptDebugServer::willExecuteProgram):
(WebCore::ScriptDebugServer::didExecuteProgram):
(WebCore::ScriptDebugServer::didReachBreakpoint):
* bindings/js/ScriptDebugServer.h:
(ScriptDebugServer):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@124406 268f45cc-cd09-0410-ab3c-d52691b4dbfc

26 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/Opcode.h
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
Source/JavaScriptCore/debugger/Debugger.h
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/interpreter/Interpreter.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITStubs.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/parser/ASTBuilder.h
Source/JavaScriptCore/parser/Lexer.cpp
Source/JavaScriptCore/parser/Lexer.h
Source/JavaScriptCore/parser/NodeConstructors.h
Source/JavaScriptCore/parser/Nodes.cpp
Source/JavaScriptCore/parser/Nodes.h
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/Parser.h
Source/JavaScriptCore/parser/ParserTokens.h
Source/JavaScriptCore/parser/SourceProviderCacheItem.h
Source/JavaScriptCore/parser/SyntaxChecker.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/ScriptDebugServer.cpp
Source/WebCore/bindings/js/ScriptDebugServer.h

index 7a80d01..0e46802 100644 (file)
@@ -1,3 +1,469 @@
+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
index 14cefb9..4308e79 100644 (file)
@@ -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) \
         \
index 33f282c..ac234b7 100644 (file)
@@ -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)
index 52fd7e8..490991f 100644 (file)
@@ -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; }
index d243e8c..4acc573 100644 (file)
@@ -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);
@@ -1128,6 +1131,8 @@ RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, Register
     RefPtr<Label> beforeElse = generator.newLabel();
     RefPtr<Label> afterElse = generator.newLabel();
 
+    generator.emitDebugHook(WillExecuteStatement, lineNo(), lineNo(), columnNo());
+
     if (m_logical->hasConditionContextCodegen()) {
         RefPtr<Label> beforeThen = generator.newLabel();
         generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), true);
@@ -1385,7 +1390,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 +1433,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 +1441,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 +1450,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 +1459,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 +1467,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 +1491,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 +1527,11 @@ RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
     RefPtr<Label> topOfLoop = generator.newLabel();
     generator.emitLabel(topOfLoop.get());
     generator.emitLoopHint();
-    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
    
     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 +1550,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 +1564,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 +1585,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 +1606,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 +1633,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 +1696,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 +1706,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 +1720,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 +1733,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 +1749,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 +1757,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 +1922,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 +1937,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 +1952,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 +1969,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 +2026,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 +2041,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 +2056,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 +2072,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;
     }
index a237329..a6a433a 100644 (file)
@@ -42,14 +42,25 @@ 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, bool) = 0;
+        virtual void atStatement(const DebuggerCallFrame&, intptr_t, int) = 0;
+        virtual void callEvent(const DebuggerCallFrame&, intptr_t, int) = 0;
+        virtual void returnEvent(const DebuggerCallFrame&, intptr_t, int) = 0;
+
+        virtual void exception(const DebuggerCallFrame&, intptr_t, int, int, bool) { };
+        virtual void atStatement(const DebuggerCallFrame&, intptr_t, int, int) { };
+        virtual void callEvent(const DebuggerCallFrame&, intptr_t, int, int) { };
+        virtual void returnEvent(const DebuggerCallFrame&, intptr_t, int, int) { };
+
+
+        virtual void willExecuteProgram(const DebuggerCallFrame&, intptr_t, int) = 0;
+        virtual void didExecuteProgram(const DebuggerCallFrame&, intptr_t, int) = 0;
+        virtual void didReachBreakpoint(const DebuggerCallFrame&, intptr_t, int) = 0;
+
+        virtual void willExecuteProgram(const DebuggerCallFrame&, intptr_t, int, int) { };
+        virtual void didExecuteProgram(const DebuggerCallFrame&, intptr_t, int, int) { };
+        virtual void didReachBreakpoint(const DebuggerCallFrame&, intptr_t, int, int) { };
+
 
         void recompileAllJSFunctions(JSGlobalData*);
 
index 3edb858..c27a7e7 100644 (file)
@@ -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;
     }
 }
index 8663bf8..f4ccd99 100644 (file)
@@ -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);
index c0af6f9..421cf5b 100644 (file)
@@ -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
 }
index 095ea57..70a608e 100644 (file)
@@ -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
 }
index 0f03a0a..7100a0c 100644 (file)
@@ -3403,8 +3403,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)
index d2d743e..58bf1bd 100644 (file)
@@ -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();
 }
index d4c1706..0a71f12 100644 (file)
@@ -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;
 }
index 3b020f4..2a8a8dc 100644 (file)
@@ -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;
 }
 
index 41f1f85..1ac832a 100644 (file)
@@ -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
index be50eea..43d1e17 100644 (file)
@@ -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;
         }
index c32e4c7..0172359 100644 (file)
@@ -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();
index 5b15be4..ed1a85a 100644 (file)
@@ -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);
index 558f50e..3e243b4 100644 (file)
@@ -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,17 +955,18 @@ 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();
     
@@ -960,13 +982,15 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(T
     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 {
+        tokenLocationStack.append(tokenLocation());
         next();
         if (!match(IF)) {
             const Identifier* unused = 0;
@@ -992,7 +1016,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(T
         posStack.append(make_pair(innerStart, innerEnd));
         statementStack.append(innerTrueBlock);
     } while (match(ELSE));
-    
+
     if (!trailingElse) {
         TreeExpression condition = exprStack.last();
         exprStack.removeLast();
@@ -1000,7 +1024,9 @@ 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()) {
@@ -1012,16 +1038,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 +1060,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 +1075,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 +1128,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 +1136,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 +1149,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 +1172,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 +1194,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 +1205,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 +1254,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 +1282,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 +1300,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 +1317,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 +1335,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 +1350,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 +1369,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 +1393,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 +1413,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 +1451,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 +1502,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 +1521,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 +1529,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 +1549,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 +1562,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 +1581,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 +1594,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 +1609,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 +1619,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 +1657,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 +1670,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 +1679,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 +1693,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
index c2a11d6..79a95b6 100644 (file)
@@ -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
index a1ea751..6e6cec1 100644 (file)
@@ -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 };
index 3662367..8b36205 100644 (file)
@@ -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;
     }
     
index fe3ce71..7d44ef3 100644 (file)
@@ -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; }
index 9bfdccd..0763e6e 100644 (file)
@@ -1,3 +1,33 @@
+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.
+
+        As JSC is enabled to provide column info of statement, ScriptDebugServer can use it to
+        support "Pretty Print" debug mode.
+
+        No new test case for this patch.
+
+        * bindings/js/ScriptDebugServer.cpp:
+        (WebCore::ScriptDebugServer::setBreakpoint):
+        (WebCore::ScriptDebugServer::removeBreakpoint):
+        (WebCore):
+        (WebCore::ScriptDebugServer::updateCurrentStatementPosition):
+        (WebCore::ScriptDebugServer::hasBreakpoint):
+        (WebCore::ScriptDebugServer::createCallFrameAndPauseIfNeeded):
+        (WebCore::ScriptDebugServer::updateCallFrameAndPauseIfNeeded):
+        (WebCore::ScriptDebugServer::callEvent):
+        (WebCore::ScriptDebugServer::atStatement):
+        (WebCore::ScriptDebugServer::returnEvent):
+        (WebCore::ScriptDebugServer::exception):
+        (WebCore::ScriptDebugServer::willExecuteProgram):
+        (WebCore::ScriptDebugServer::didExecuteProgram):
+        (WebCore::ScriptDebugServer::didReachBreakpoint):
+        * bindings/js/ScriptDebugServer.h:
+        (ScriptDebugServer):
+
 2012-08-01  Xingnan Wang  <xingnan.wang@intel.com>
 
         IndexedDB: ObjectStoreMetaDataKey::m_metaDataType should use byte type
index 9ace82d..00b68a5 100644 (file)
@@ -75,20 +75,28 @@ String ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBrea
     SourceIdToBreakpointsMap::iterator it = m_sourceIdToBreakpoints.find(sourceIDValue);
     if (it == m_sourceIdToBreakpoints.end())
         it = m_sourceIdToBreakpoints.set(sourceIDValue, LineToBreakpointMap()).iterator;
-    if (it->second.contains(scriptBreakpoint.lineNumber + 1))
-        return "";
-    it->second.set(scriptBreakpoint.lineNumber + 1, scriptBreakpoint);
+    LineToBreakpointMap::iterator breaksIt = it->second.find(scriptBreakpoint.lineNumber + 1);
+    if (breaksIt == it->second.end())
+        breaksIt = it->second.set(scriptBreakpoint.lineNumber + 1, BreakpointsInLine()).iterator;
+
+    BreakpointsInLine& breaksVector = breaksIt->second;
+    unsigned breaksCount = breaksVector.size();
+    for (unsigned i = 0; i < breaksCount; i++) {
+        if (breaksVector.at(i).columnNumber == scriptBreakpoint.columnNumber)
+            return "";
+    }
+    breaksVector.append(scriptBreakpoint);
+
     *actualLineNumber = scriptBreakpoint.lineNumber;
-    // FIXME(WK53003): implement setting breakpoints by line:column.
-    *actualColumnNumber = 0;
-    return sourceID + ":" + String::number(scriptBreakpoint.lineNumber);
+    *actualColumnNumber = scriptBreakpoint.columnNumber;
+    return sourceID + ":" + String::number(scriptBreakpoint.lineNumber) + ":" + String::number(scriptBreakpoint.columnNumber);
 }
 
 void ScriptDebugServer::removeBreakpoint(const String& breakpointId)
 {
     Vector<String> tokens;
     breakpointId.split(":", tokens);
-    if (tokens.size() != 2)
+    if (tokens.size() != 3)
         return;
     bool success;
     intptr_t sourceIDValue = tokens[0].toIntPtr(&success);
@@ -97,9 +105,63 @@ void ScriptDebugServer::removeBreakpoint(const String& breakpointId)
     unsigned lineNumber = tokens[1].toUInt(&success);
     if (!success)
         return;
+    unsigned columnNumber = tokens[2].toUInt(&success);
+    if (!success)
+        return;
+
     SourceIdToBreakpointsMap::iterator it = m_sourceIdToBreakpoints.find(sourceIDValue);
-    if (it != m_sourceIdToBreakpoints.end())
-        it->second.remove(lineNumber + 1);
+    if (it == m_sourceIdToBreakpoints.end())
+        return;
+    LineToBreakpointMap::iterator breaksIt = it->second.find(lineNumber + 1);
+    if (breaksIt == it->second.end())
+        return;
+
+    BreakpointsInLine& breaksVector = breaksIt->second;
+    unsigned breaksCount = breaksVector.size();
+    for (unsigned i = 0; i < breaksCount; i++) {
+        if (breaksVector.at(i).columnNumber == static_cast<int>(columnNumber)) {
+            breaksVector.remove(i);
+            break;
+        }
+    }
+}
+
+void ScriptDebugServer::updateCurrentStatementPosition(intptr_t sourceID, int line)
+{
+    if (line < 0)
+        return;
+
+    SourceProvider* source = reinterpret_cast<SourceProvider*>(sourceID);
+
+    if (m_currentSourceID != sourceID) {
+        String sourceCode = ustringToString(JSC::UString(const_cast<StringImpl*>(source->data())));
+        m_currentSourceCode.clear();
+        sourceCode.split("\n", true, m_currentSourceCode);
+        m_currentSourceID = sourceID;
+        m_currentStatementPosition.lineNumber = 0;
+        m_currentStatementPosition.columnNumber = 0;
+    }
+
+    if (line != m_currentStatementPosition.lineNumber) {
+        m_currentStatementPosition.lineNumber = line;
+        m_currentStatementPosition.columnNumber = 0;
+        return;
+    }
+
+    int startLine = source->startPosition().m_line.zeroBasedInt();
+    if ((m_currentStatementPosition.lineNumber - startLine - 1) >= static_cast<int>(m_currentSourceCode.size()))
+        return;
+    const String& codeInLine = m_currentSourceCode[m_currentStatementPosition.lineNumber - startLine - 1];
+    if (codeInLine.isEmpty())
+        return;
+    int nextColumn = codeInLine.find(";", m_currentStatementPosition.columnNumber);
+    if (nextColumn != -1) {
+        UChar c = codeInLine[nextColumn + 1];
+        if (c == ' ' || c == '\t')
+            nextColumn += 1;
+        m_currentStatementPosition.columnNumber = nextColumn + 1;
+    } else
+        m_currentStatementPosition.columnNumber = 0;
 }
 
 bool ScriptDebugServer::hasBreakpoint(intptr_t sourceID, const TextPosition& position) const
@@ -110,19 +172,37 @@ bool ScriptDebugServer::hasBreakpoint(intptr_t sourceID, const TextPosition& pos
     SourceIdToBreakpointsMap::const_iterator it = m_sourceIdToBreakpoints.find(sourceID);
     if (it == m_sourceIdToBreakpoints.end())
         return false;
-    int lineNumber = position.m_line.oneBasedInt();
-    if (lineNumber <= 0)
+
+    int lineNumber = position.m_line.zeroBasedInt();
+    int columnNumber = position.m_column.zeroBasedInt();
+    if (lineNumber < 0 || columnNumber < 0)
+        return false;
+
+    LineToBreakpointMap::const_iterator breaksIt = it->second.find(lineNumber + 1);
+    if (breaksIt == it->second.end())
         return false;
-    LineToBreakpointMap::const_iterator breakIt = it->second.find(lineNumber);
-    if (breakIt == it->second.end())
+
+    bool hit = false;
+    const BreakpointsInLine& breaksVector = breaksIt->second;
+    unsigned breaksCount = breaksVector.size();
+    unsigned i;
+    for (i = 0; i < breaksCount; i++) {
+        int breakColumn = breaksVector.at(i).columnNumber;
+        int breakLine = breaksVector.at(i).lineNumber;
+        if (lineNumber == breakLine && columnNumber == breakColumn) {
+            hit = true;
+            break;
+        }
+    }
+    if (!hit)
         return false;
 
     // An empty condition counts as no condition which is equivalent to "true".
-    if (breakIt->second.condition.isEmpty())
+    if (breaksVector.at(i).condition.isEmpty())
         return true;
 
     JSValue exception;
-    JSValue result = m_currentCallFrame->evaluate(stringToUString(breakIt->second.condition), exception);
+    JSValue result = m_currentCallFrame->evaluate(stringToUString(breaksVector.at(i).condition), exception);
     if (exception) {
         // An erroneous condition counts as "false".
         return false;
@@ -347,20 +427,20 @@ void ScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback
     m_callingListeners = false;
 }
 
-void ScriptDebugServer::createCallFrameAndPauseIfNeeded(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
+void ScriptDebugServer::createCallFrameAndPauseIfNeeded(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber)
 {
-    TextPosition textPosition(OrdinalNumber::fromOneBasedInt(lineNumber), OrdinalNumber::first());
+    TextPosition textPosition(OrdinalNumber::fromOneBasedInt(lineNumber), OrdinalNumber::fromZeroBasedInt(columnNumber));
     m_currentCallFrame = JavaScriptCallFrame::create(debuggerCallFrame, m_currentCallFrame, sourceID, textPosition);
     pauseIfNeeded(debuggerCallFrame.dynamicGlobalObject());
 }
 
-void ScriptDebugServer::updateCallFrameAndPauseIfNeeded(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
+void ScriptDebugServer::updateCallFrameAndPauseIfNeeded(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber)
 {
     ASSERT(m_currentCallFrame);
     if (!m_currentCallFrame)
         return;
 
-    TextPosition textPosition(OrdinalNumber::fromOneBasedInt(lineNumber), OrdinalNumber::first());
+    TextPosition textPosition(OrdinalNumber::fromOneBasedInt(lineNumber), OrdinalNumber::fromZeroBasedInt(columnNumber));
     m_currentCallFrame->update(debuggerCallFrame, sourceID, textPosition);
     pauseIfNeeded(debuggerCallFrame.dynamicGlobalObject());
 }
@@ -401,22 +481,37 @@ void ScriptDebugServer::pauseIfNeeded(JSGlobalObject* dynamicGlobalObject)
 
 void ScriptDebugServer::callEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
 {
+    callEvent(debuggerCallFrame, sourceID, lineNumber, 0);
+}
+
+void ScriptDebugServer::callEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber)
+{
     if (!m_paused)
-        createCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber);
+        createCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber, columnNumber);
 }
 
 void ScriptDebugServer::atStatement(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
 {
+    atStatement(debuggerCallFrame, sourceID, lineNumber, 0);
+}
+
+void ScriptDebugServer::atStatement(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber)
+{
     if (!m_paused)
-        updateCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber);
+        updateCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber, columnNumber);
 }
 
 void ScriptDebugServer::returnEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
 {
+    returnEvent(debuggerCallFrame, sourceID, lineNumber, 0);
+}
+
+void ScriptDebugServer::returnEvent(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber)
+{
     if (m_paused)
         return;
 
-    updateCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber);
+    updateCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber, columnNumber);
 
     // detach may have been called during pauseIfNeeded
     if (!m_currentCallFrame)
@@ -430,27 +525,42 @@ void ScriptDebugServer::returnEvent(const DebuggerCallFrame& debuggerCallFrame,
 
 void ScriptDebugServer::exception(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, bool hasHandler)
 {
+    exception(debuggerCallFrame, sourceID, lineNumber, 0, hasHandler);
+}
+
+void ScriptDebugServer::exception(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber, bool hasHandler)
+{
     if (m_paused)
         return;
 
     if (m_pauseOnExceptionsState == PauseOnAllExceptions || (m_pauseOnExceptionsState == PauseOnUncaughtExceptions && !hasHandler))
         m_pauseOnNextStatement = true;
 
-    updateCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber);
+    updateCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber, columnNumber);
 }
 
 void ScriptDebugServer::willExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
 {
+    willExecuteProgram(debuggerCallFrame, sourceID, lineNumber, 0);
+}
+
+void ScriptDebugServer::willExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber)
+{
     if (!m_paused)
-        createCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber);
+        createCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber, columnNumber);
 }
 
 void ScriptDebugServer::didExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
 {
+    didExecuteProgram(debuggerCallFrame, sourceID, lineNumber, 0);
+}
+
+void ScriptDebugServer::didExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber)
+{
     if (m_paused)
         return;
 
-    updateCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber);
+    updateCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber, columnNumber);
 
     // Treat stepping over the end of a program like stepping out.
     if (m_currentCallFrame == m_pauseOnCallFrame)
@@ -460,11 +570,16 @@ void ScriptDebugServer::didExecuteProgram(const DebuggerCallFrame& debuggerCallF
 
 void ScriptDebugServer::didReachBreakpoint(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber)
 {
+    didReachBreakpoint(debuggerCallFrame, sourceID, lineNumber, 0);
+}
+
+void ScriptDebugServer::didReachBreakpoint(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineNumber, int columnNumber)
+{
     if (m_paused)
         return;
 
     m_pauseOnNextStatement = true;
-    updateCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber);
+    updateCallFrameAndPauseIfNeeded(debuggerCallFrame, sourceID, lineNumber, columnNumber);
 }
 
 void ScriptDebugServer::recompileAllJSFunctionsSoon()
index 84fba5c..9d97c16 100644 (file)
@@ -123,8 +123,8 @@ protected:
     void dispatchDidParseSource(const ListenerSet& listeners, JSC::SourceProvider*, bool isContentScript);
     void dispatchFailedToParseSource(const ListenerSet& listeners, JSC::SourceProvider*, int errorLine, const String& errorMessage);
 
-    void createCallFrameAndPauseIfNeeded(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber);
-    void updateCallFrameAndPauseIfNeeded(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber);
+    void createCallFrameAndPauseIfNeeded(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber, int columnNumber);
+    void updateCallFrameAndPauseIfNeeded(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber, int columnNumber);
     void pauseIfNeeded(JSC::JSGlobalObject* dynamicGlobalObject);
 
     virtual void detach(JSC::JSGlobalObject*);
@@ -138,7 +138,19 @@ protected:
     virtual void didExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno);
     virtual void didReachBreakpoint(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno);
 
-    typedef HashMap<long, ScriptBreakpoint> LineToBreakpointMap;
+    virtual void callEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber, int columnNumber);
+    virtual void atStatement(const JSC::DebuggerCallFrame&, intptr_t sourceID, int firstLine, int columnNumber);
+    virtual void returnEvent(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber, int columnNumber);
+    virtual void exception(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineNumber, int columnNumber, bool hasHandler);
+    virtual void willExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno, int columnNumber);
+    virtual void didExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno, int columnNumber);
+    virtual void didReachBreakpoint(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno, int columnNumber);
+
+
+    void updateCurrentStatementPosition(intptr_t, int);
+
+    typedef Vector<ScriptBreakpoint> BreakpointsInLine;
+    typedef HashMap<long, BreakpointsInLine> LineToBreakpointMap;
     typedef HashMap<intptr_t, LineToBreakpointMap> SourceIdToBreakpointsMap;
 
     bool m_callingListeners;
@@ -151,6 +163,10 @@ protected:
     RefPtr<JavaScriptCallFrame> m_currentCallFrame;
     SourceIdToBreakpointsMap m_sourceIdToBreakpoints;
     Timer<ScriptDebugServer> m_recompileTimer;
+
+    Vector<String> m_currentSourceCode;
+    intptr_t m_currentSourceID;
+    ScriptBreakpoint m_currentStatementPosition;
 };
 
 } // namespace WebCore