Ignore:
Timestamp:
Jul 9, 2013, 9:15:12 AM (12 years ago)
Author:
[email protected]
Message:

Fix 30% JSBench regression (caused by adding column numbers to stack traces).
https://bugs.webkit.org/show_bug.cgi?id=118481.

Reviewed by Mark Hahnenberg and Geoffrey Garen.

Source/JavaScriptCore:

Previously, we already capture ExpressionRangeInfo that provides a divot for
each bytecode that can potentially throw an exception (and therefore generate
a stack trace). On first attempt to compute column numbers, we then do a walk
of the source string to record all line start positions in a table associated
with the SourceProvider. The column number can then be computed as

divot - lineStartFor(bytecodeOffset).

The computation of this lineStarts table is the source of the 30% JSBench
performance regression.

The new code now records lineStarts as the lexer and parser scans the source
code. These lineStarts are then used to compute the column number for the
given divot, and stored in the ExpressionRangeInfo. Similarly, we also capture
the line number at the divot point and store that in the ExpressionRangeInfo.
Hence, to look up line and column numbers, we now lookup the ExpressionRangeInfo
for the bytecodeOffset, and then compute the line and column from the values
stored in the expression info.

The strategy:

  1. We want to minimize perturbations to the lexer and parser. Specifically, the changes added should not change how it scans code, and generate bytecode.
  2. We regard the divot as the source character position we are interested in. As such, we'll capture line and lineStart (for column) at the point when we capture the divot information. This ensures that the 3 values are consistent.

How the change is done:

  1. Change the lexer to track lineStarts.
  2. Change the parser to capture line and lineStarts at the point of capturing divots.
  3. Change the parser and associated code to plumb these values all the way to the point that the correspoinding ExpressionRangeInfo is emitted.
  4. Propagate and record SourceCode firstLine and firstLineColumnOffset to the the necessary places so that we can add them as needed when reifying UnlinkedCodeBlocks into CodeBlocks.
  5. Compress the line and column number values in the ExpressionRangeInfo. In practice, we seldom have both large line and column numbers. Hence, we can encode both in an uint32_t most of the time. For the times when we encounter both large line and column numbers, we have a fallback to store the "fat" position info.
  6. Emit an ExpressionRangeInfo for UnaryOp nodes to get more line and column number coverage.
  7. Change the interpreter to use the new way of computing line and column.
  8. Delete old line and column computation code that is now unused.

Misc details:

  • the old lexer was tracking both a startOffset and charPosition where charPosition equals startOffset - SourceCode.startOffset. We now use startOffset exclusively throughout the system for consistency. All offset values (including lineStart) are relative to the start of the SourceProvider string. These values will only be converted to be relative to the SourceCode.startOffset at the very last minute i.e. when the divot is stored into the ExpressionRangeInfo.

This change to use the same offset system everywhere reduces confusion
from having to convert back and forth between the 2 systems. It also
enables a lot of assertions to be used.

  • Also fixed some bugs in the choice of divot positions to use. For example, both Eval and Function expressions previously used column numbers from the start of the expression but used the line number at the end of the expression. This is now fixed to use either the start or end positions as appropriate, but not a mix of line and columns from both.
  • Why use ints instead of unsigneds for offsets and lineStarts inside the lexer and parser? Some tests (e.g. fast/js/call-base-resolution.html and fast/js/eval-cross-window.html) has shown that lineStart offsets can be prior to the SourceCode.startOffset. Keeping the lexer offsets as ints simplifies computations and makes it easier to maintain the assertions that (startOffset >= lineStartOffset).

However, column and line numbers are always unsigned when we publish
them to the ExpressionRangeInfo. The ints are only used inside the
lexer and parser ... well, and bytecode generator.

  • For all cases, lineStart is always captured where the divot is captured. However, some sputnik conformance tests have shown that we cannot honor line breaks for assignment statements like the following:

eval("x\u000A*=\u000A-1;");

In this case, the lineStart is expected to be captured at the start of
the assignment expression instead of at the divot point in the middle.
The assignment expression is the only special case for this.

This patch has been tested against the full layout tests both with release
and debug builds with no regression.

  • API/JSContextRef.cpp:

(JSContextCreateBacktrace):

  • Updated to use the new StackFrame::computeLineAndColumn().
  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::CodeBlock):

  • Added m_firstLineColumnOffset initialization.
  • Plumbed the firstLineColumnOffset into the SourceCode.
  • Initialized column for op_debug using the new way.

(JSC::CodeBlock::lineNumberForBytecodeOffset):

  • Changed to compute line number using the ExpressionRangeInfo.

(JSC::CodeBlock::columnNumberForBytecodeOffset): Added

  • Changed to compute column number using the ExpressionRangeInfo.

(JSC::CodeBlock::expressionRangeForBytecodeOffset):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::firstLineColumnOffset):
(JSC::GlobalCodeBlock::GlobalCodeBlock):

  • Plumbed firstLineColumnOffset through to the super class.

(JSC::ProgramCodeBlock::ProgramCodeBlock):

  • Plumbed firstLineColumnOffset through to the super class.

(JSC::EvalCodeBlock::EvalCodeBlock):

  • Plumbed firstLineColumnOffset through to the super class. But for EvalCodeBlocks, the firstLineColumnOffset is always 1 because we're starting with a new source string with no start offset.

(JSC::FunctionCodeBlock::FunctionCodeBlock):

  • Plumbed firstLineColumnOffset through to the super class.
  • bytecode/ExpressionRangeInfo.h:
    • Added modes for encoding line and column into a single 30-bit unsigned. The encoding is in 1 of 3 modes:
      1. FatLineMode: 22-bit line, 8-bit column
      2. FatColumnMode: 8-bit line, 22-bit column
      3. FatLineAndColumnMode: 32-bit line, 32-bit column

(JSC::ExpressionRangeInfo::encodeFatLineMode): Added.

  • Encodes line and column into the 30-bit position using FatLine mode.

(JSC::ExpressionRangeInfo::encodeFatColumnMode): Added.

  • Encodes line and column into the 30-bit position using FatColumn mode.

(JSC::ExpressionRangeInfo::decodeFatLineMode): Added.

  • Decodes the FatLine mode 30-bit position into line and column.

(JSC::ExpressionRangeInfo::decodeFatColumnMode): Added.

  • Decodes the FatColumn mode 30-bit position into line and column.
  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):

  • Plumbed startColumn through.

(JSC::UnlinkedFunctionExecutable::link):

  • Plumbed startColumn through.

(JSC::UnlinkedCodeBlock::lineNumberForBytecodeOffset):

  • Computes a line number using the new way.

(JSC::UnlinkedCodeBlock::expressionRangeForBytecodeOffset):

  • Added decoding of line and column.
  • Added handling of the case when we do not find a fitting expression range info for a specified bytecodeOffset. This only happens if the bytecodeOffset is below the first expression range info. In that case, we'll use the first expression range info entry.

(JSC::UnlinkedCodeBlock::addExpressionInfo):

  • Added encoding of line and column.
  • bytecode/UnlinkedCodeBlock.h:
    • Added m_expressionInfoFatPositions in RareData.

(JSC::UnlinkedFunctionExecutable::functionStartColumn):
(JSC::UnlinkedCodeBlock::shrinkToFit):

  • Removed obsoleted m_lineInfo.
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitCall): Plumbed line and lineStart through.
(JSC::BytecodeGenerator::emitCallEval): Plumbed line and lineStart through.
(JSC::BytecodeGenerator::emitCallVarargs): Plumbed line and lineStart through.
(JSC::BytecodeGenerator::emitConstruct): Plumbed line and lineStart through.
(JSC::BytecodeGenerator::emitDebugHook): Plumbed lineStart through.

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::emitNode):
(JSC::BytecodeGenerator::emitNodeInConditionContext):

  • Removed obsoleted m_lineInfo.

(JSC::BytecodeGenerator::emitExpressionInfo):

  • Plumbed line and lineStart through.
  • Compute the line and column to be added to the expression range info.
  • bytecompiler/NodesCodegen.cpp:

(JSC::ThrowableExpressionData::emitThrowReferenceError):
(JSC::ResolveNode::emitBytecode):
(JSC::ArrayNode::toArgumentList):
(JSC::BracketAccessorNode::emitBytecode):
(JSC::DotAccessorNode::emitBytecode):
(JSC::NewExprNode::emitBytecode):
(JSC::EvalFunctionCallNode::emitBytecode):
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::FunctionCallBracketNode::emitBytecode):
(JSC::FunctionCallDotNode::emitBytecode):
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):
(JSC::PostfixNode::emitResolve):
(JSC::PostfixNode::emitBracket):
(JSC::PostfixNode::emitDot):
(JSC::DeleteResolveNode::emitBytecode):
(JSC::DeleteBracketNode::emitBytecode):
(JSC::DeleteDotNode::emitBytecode):
(JSC::PrefixNode::emitResolve):
(JSC::PrefixNode::emitBracket):
(JSC::PrefixNode::emitDot):

  • Plumbed line and lineStart through the above as needed.

(JSC::UnaryOpNode::emitBytecode):

  • Added emission of an ExpressionRangeInfo for the UnaryOp node.

(JSC::BinaryOpNode::emitStrcat):
(JSC::ThrowableBinaryOpNode::emitBytecode):
(JSC::InstanceOfNode::emitBytecode):
(JSC::emitReadModifyAssignment):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::AssignDotNode::emitBytecode):
(JSC::ReadModifyDotNode::emitBytecode):
(JSC::AssignBracketNode::emitBytecode):
(JSC::ReadModifyBracketNode::emitBytecode):

  • Plumbed line and lineStart through the above as needed.

(JSC::ConstStatementNode::emitBytecode):
(JSC::EmptyStatementNode::emitBytecode):
(JSC::DebuggerStatementNode::emitBytecode):
(JSC::ExprStatementNode::emitBytecode):
(JSC::VarStatementNode::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):

  • Plumbed line and lineStart through the above as needed.
  • interpreter/Interpreter.cpp:

(JSC::appendSourceToError):

  • Added line and column arguments for expressionRangeForBytecodeOffset().

(JSC::StackFrame::computeLineAndColumn):

  • Replaces StackFrame::line() and StackFrame::column().

(JSC::StackFrame::expressionInfo):

  • Added line and column arguments.

(JSC::StackFrame::toString):

  • Changed to use the new StackFrame::computeLineAndColumn().

(JSC::Interpreter::getStackTrace):

  • Added the needed firstLineColumnOffset arg for the StackFrame.
  • interpreter/Interpreter.h:
  • parser/ASTBuilder.h:

(JSC::ASTBuilder::BinaryOpInfo::BinaryOpInfo):
(JSC::ASTBuilder::AssignmentInfo::AssignmentInfo):
(JSC::ASTBuilder::createResolve):
(JSC::ASTBuilder::createBracketAccess):
(JSC::ASTBuilder::createDotAccess):
(JSC::ASTBuilder::createRegExp):
(JSC::ASTBuilder::createNewExpr):
(JSC::ASTBuilder::createAssignResolve):
(JSC::ASTBuilder::createFunctionExpr):
(JSC::ASTBuilder::createFunctionBody):
(JSC::ASTBuilder::createGetterOrSetterProperty):
(JSC::ASTBuilder::createFuncDeclStatement):
(JSC::ASTBuilder::createBlockStatement):
(JSC::ASTBuilder::createExprStatement):
(JSC::ASTBuilder::createIfStatement):
(JSC::ASTBuilder::createForLoop):
(JSC::ASTBuilder::createForInLoop):
(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::appendBinaryExpressionInfo):
(JSC::ASTBuilder::appendUnaryToken):
(JSC::ASTBuilder::unaryTokenStackLastStart):
(JSC::ASTBuilder::unaryTokenStackLastLineStartPosition): Added.
(JSC::ASTBuilder::assignmentStackAppend):
(JSC::ASTBuilder::createAssignment):
(JSC::ASTBuilder::setExceptionLocation):
(JSC::ASTBuilder::makeDeleteNode):
(JSC::ASTBuilder::makeFunctionCallNode):
(JSC::ASTBuilder::makeBinaryNode):
(JSC::ASTBuilder::makeAssignNode):
(JSC::ASTBuilder::makePrefixNode):
(JSC::ASTBuilder::makePostfixNode):.

  • Plumbed line, lineStart, and startColumn through the above as needed.
  • parser/Lexer.cpp:

(JSC::::currentSourcePtr):
(JSC::::setCode):

  • Added tracking for sourceoffset and lineStart.

(JSC::::internalShift):
(JSC::::parseIdentifier):

  • Added tracking for lineStart.

(JSC::::parseIdentifierSlowCase):
(JSC::::parseString):

  • Added tracking for lineStart.

(JSC::::parseStringSlowCase):
(JSC::::lex):

  • Added tracking for sourceoffset.

(JSC::::sourceCode):

  • parser/Lexer.h:

(JSC::Lexer::currentOffset):
(JSC::Lexer::currentLineStartOffset):
(JSC::Lexer::setOffset):

  • Added tracking for lineStart.

(JSC::Lexer::offsetFromSourcePtr): Added. conversion function.
(JSC::Lexer::sourcePtrFromOffset): Added. conversion function.
(JSC::Lexer::setOffsetFromSourcePtr):
(JSC::::lexExpectIdentifier):

  • Added tracking for sourceoffset and lineStart.
  • parser/NodeConstructors.h:

(JSC::Node::Node):
(JSC::ResolveNode::ResolveNode):
(JSC::EvalFunctionCallNode::EvalFunctionCallNode):
(JSC::FunctionCallValueNode::FunctionCallValueNode):
(JSC::FunctionCallResolveNode::FunctionCallResolveNode):
(JSC::FunctionCallBracketNode::FunctionCallBracketNode):
(JSC::FunctionCallDotNode::FunctionCallDotNode):
(JSC::CallFunctionCallDotNode::CallFunctionCallDotNode):
(JSC::ApplyFunctionCallDotNode::ApplyFunctionCallDotNode):
(JSC::PostfixNode::PostfixNode):
(JSC::DeleteResolveNode::DeleteResolveNode):
(JSC::DeleteBracketNode::DeleteBracketNode):
(JSC::DeleteDotNode::DeleteDotNode):
(JSC::PrefixNode::PrefixNode):
(JSC::ReadModifyResolveNode::ReadModifyResolveNode):
(JSC::ReadModifyBracketNode::ReadModifyBracketNode):
(JSC::AssignBracketNode::AssignBracketNode):
(JSC::AssignDotNode::AssignDotNode):
(JSC::ReadModifyDotNode::ReadModifyDotNode):
(JSC::AssignErrorNode::AssignErrorNode):
(JSC::WithNode::WithNode):
(JSC::ForInNode::ForInNode):

  • Plumbed line and lineStart through the above as needed.
  • parser/Nodes.cpp:

(JSC::StatementNode::setLoc): Plumbed lineStart.
(JSC::ScopeNode::ScopeNode): Plumbed lineStart.
(JSC::ProgramNode::ProgramNode): Plumbed startColumn.
(JSC::ProgramNode::create): Plumbed startColumn.
(JSC::EvalNode::create):
(JSC::FunctionBodyNode::FunctionBodyNode): Plumbed startColumn.
(JSC::FunctionBodyNode::create): Plumbed startColumn.

  • parser/Nodes.h:

(JSC::Node::startOffset):
(JSC::Node::lineStartOffset): Added.
(JSC::StatementNode::firstLine):
(JSC::StatementNode::lastLine):
(JSC::ThrowableExpressionData::ThrowableExpressionData):
(JSC::ThrowableExpressionData::setExceptionSourceCode):
(JSC::ThrowableExpressionData::divotStartOffset):
(JSC::ThrowableExpressionData::divotEndOffset):
(JSC::ThrowableExpressionData::divotLine):
(JSC::ThrowableExpressionData::divotLineStart):
(JSC::ThrowableSubExpressionData::ThrowableSubExpressionData):
(JSC::ThrowableSubExpressionData::setSubexpressionInfo):
(JSC::ThrowableSubExpressionData::subexpressionDivot):
(JSC::ThrowableSubExpressionData::subexpressionStartOffset):
(JSC::ThrowableSubExpressionData::subexpressionEndOffset):
(JSC::ThrowableSubExpressionData::subexpressionLine):
(JSC::ThrowableSubExpressionData::subexpressionLineStart):
(JSC::ThrowablePrefixedSubExpressionData::ThrowablePrefixedSubExpressionData):
(JSC::ThrowablePrefixedSubExpressionData::setSubexpressionInfo):
(JSC::ThrowablePrefixedSubExpressionData::subexpressionDivot):
(JSC::ThrowablePrefixedSubExpressionData::subexpressionStartOffset):
(JSC::ThrowablePrefixedSubExpressionData::subexpressionEndOffset):
(JSC::ThrowablePrefixedSubExpressionData::subexpressionLine):
(JSC::ThrowablePrefixedSubExpressionData::subexpressionLineStart):
(JSC::ScopeNode::startStartOffset):
(JSC::ScopeNode::startLineStartOffset):
(JSC::ProgramNode::startColumn):
(JSC::EvalNode::startColumn):
(JSC::FunctionBodyNode::startColumn):

  • Plumbed line and lineStart through the above as needed.
  • parser/Parser.cpp:

(JSC::::Parser):
(JSC::::parseSourceElements):
(JSC::::parseVarDeclarationList):
(JSC::::parseConstDeclarationList):
(JSC::::parseForStatement):
(JSC::::parseBreakStatement):
(JSC::::parseContinueStatement):
(JSC::::parseReturnStatement):
(JSC::::parseThrowStatement):
(JSC::::parseWithStatement):

  • Plumbed line and lineStart through the above as needed.

(JSC::::parseFunctionBody):

  • Plumbed startColumn.

(JSC::::parseFunctionInfo):
(JSC::::parseFunctionDeclaration):
(JSC::LabelInfo::LabelInfo):
(JSC::::parseExpressionOrLabelStatement):
(JSC::::parseAssignmentExpression):
(JSC::::parseBinaryExpression):
(JSC::::parseProperty):
(JSC::::parseObjectLiteral):
(JSC::::parsePrimaryExpression):
(JSC::::parseMemberExpression):
(JSC::::parseUnaryExpression):

  • Plumbed line, lineStart, startColumn through the above as needed.
  • parser/Parser.h:

(JSC::Parser::next):
(JSC::Parser::nextExpectIdentifier):
(JSC::Parser::tokenStart):
(JSC::Parser::tokenColumn):
(JSC::Parser::tokenEnd):
(JSC::Parser::tokenLineStart):
(JSC::Parser::lastTokenLine):
(JSC::Parser::lastTokenLineStart):
(JSC::::parse):

  • parser/ParserTokens.h:

(JSC::JSTokenLocation::JSTokenLocation):

  • Plumbed lineStart.

(JSC::JSTokenLocation::lineStartPosition):
(JSC::JSTokenLocation::startPosition):
(JSC::JSTokenLocation::endPosition):

  • parser/SourceCode.h:

(JSC::SourceCode::SourceCode):
(JSC::SourceCode::startColumn):
(JSC::makeSource):
(JSC::SourceCode::subExpression):

  • parser/SourceProvider.cpp: delete old code.
  • parser/SourceProvider.h: delete old code.
  • parser/SourceProviderCacheItem.h:

(JSC::SourceProviderCacheItem::closeBraceToken):
(JSC::SourceProviderCacheItem::SourceProviderCacheItem):

  • Plumbed lineStart.
  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::makeFunctionCallNode):
(JSC::SyntaxChecker::makeAssignNode):
(JSC::SyntaxChecker::makePrefixNode):
(JSC::SyntaxChecker::makePostfixNode):
(JSC::SyntaxChecker::makeDeleteNode):
(JSC::SyntaxChecker::createResolve):
(JSC::SyntaxChecker::createBracketAccess):
(JSC::SyntaxChecker::createDotAccess):
(JSC::SyntaxChecker::createRegExp):
(JSC::SyntaxChecker::createNewExpr):
(JSC::SyntaxChecker::createAssignResolve):
(JSC::SyntaxChecker::createFunctionExpr):
(JSC::SyntaxChecker::createFunctionBody):
(JSC::SyntaxChecker::createFuncDeclStatement):
(JSC::SyntaxChecker::createForInLoop):
(JSC::SyntaxChecker::createReturnStatement):
(JSC::SyntaxChecker::createBreakStatement):
(JSC::SyntaxChecker::createContinueStatement):
(JSC::SyntaxChecker::createWithStatement):
(JSC::SyntaxChecker::createLabelStatement):
(JSC::SyntaxChecker::createThrowStatement):
(JSC::SyntaxChecker::createGetterOrSetterProperty):
(JSC::SyntaxChecker::appendBinaryExpressionInfo):
(JSC::SyntaxChecker::operatorStackPop):

  • Made SyntaxChecker prototype changes to match ASTBuilder due to new args added for plumbing line, lineStart, and startColumn.
  • runtime/CodeCache.cpp:

(JSC::CodeCache::generateBytecode):
(JSC::CodeCache::getCodeBlock):

  • Plumbed startColumn.
  • runtime/Executable.cpp:

(JSC::FunctionExecutable::FunctionExecutable):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::produceCodeBlockFor):
(JSC::FunctionExecutable::fromGlobalCode):

  • Plumbed startColumn.
  • runtime/Executable.h:

(JSC::ScriptExecutable::startColumn):
(JSC::ScriptExecutable::recordParse):
(JSC::FunctionExecutable::create):

  • Plumbed startColumn.

Source/WebCore:

Test: fast/js/line-column-numbers.html

Updated the bindings to use StackFrame::computeLineAndColumn(). The old
StackFrame::line() and StackFrame::column() has been removed. The new
algorithm always computes the 2 values together anyway. Hence it is more
efficient to return them as a pair instead of doing the same computation
twice for each half of the result.

  • bindings/js/ScriptCallStackFactory.cpp:

(WebCore::createScriptCallStack):
(WebCore::createScriptCallStackFromException):

  • bindings/js/ScriptSourceCode.h:

(WebCore::ScriptSourceCode::ScriptSourceCode):

LayoutTests:

The fix now computes line and column numbers more accurately. As a result,
some of the test results need to be re-baselined. Among other fixes, one
major source of difference is that the old code was incorrectly computing
0-based column numbers. This has now been fixed to be 1-based.
Note: line numbers were always 1-based.

Also added a new test: fast/js/line-column-numbers.html, which tests line
and column numbers for source code in various configurations.

  • editing/execCommand/outdent-blockquote-test1-expected.txt:
  • editing/execCommand/outdent-blockquote-test2-expected.txt:
  • editing/execCommand/outdent-blockquote-test3-expected.txt:
  • editing/execCommand/outdent-blockquote-test4-expected.txt:
  • editing/pasteboard/copy-paste-float-expected.txt:
  • editing/pasteboard/paste-blockquote-before-blockquote-expected.txt:
  • editing/pasteboard/paste-double-nested-blockquote-before-blockquote-expected.txt:
  • fast/dom/Window/window-resize-contents-expected.txt:
  • fast/events/remove-target-with-shadow-in-drag-expected.txt:
  • fast/js/line-column-numbers-expected.txt: Added.
  • fast/js/line-column-numbers.html: Added.
  • fast/js/script-tests/line-column-numbers.js: Added.

(try.doThrow4b):
(doThrow5b.try.innerFunc):
(doThrow5b):
(doThrow6b.try.innerFunc):
(doThrow6b):
(catch):
(try.doThrow11b):
(try.doThrow14b):

  • fast/js/stack-trace-expected.txt:
  • inspector/console/console-url-line-column-expected.txt:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r149247 r152494  
    8888RegisterID* ThrowableExpressionData::emitThrowReferenceError(BytecodeGenerator& generator, const String& message)
    8989{
    90     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     90    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    9191    generator.emitThrowReferenceError(message);
    9292    return generator.newTemporary();
     
    154154    }
    155155   
    156     generator.emitExpressionInfo(m_startOffset + m_ident.length(), m_ident.length(), 0);
     156    unsigned divot = m_startOffset + m_ident.length();
     157    generator.emitExpressionInfo(divot, m_ident.length(), 0, m_divotLine, m_divotLineStart);
    157158    return generator.emitResolve(generator.finalDestination(dst), resolveResult, m_ident);
    158159}
     
    202203}
    203204
    204 ArgumentListNode* ArrayNode::toArgumentList(VM* vm, int lineNumber, int charPosition) const
     205ArgumentListNode* ArrayNode::toArgumentList(VM* vm, int lineNumber, int startPosition, unsigned sourceOffset) const
    205206{
    206207    ASSERT(!m_elision && !m_optional);
     
    208209    if (!ptr)
    209210        return 0;
    210     JSTokenLocation location;
     211    JSTokenLocation location(sourceOffset);
    211212    location.line = lineNumber;
    212     location.charPosition = charPosition;
     213    location.startOffset = startPosition;
     214    location.sourceOffset = sourceOffset;
    213215    ArgumentListNode* head = new (vm) ArgumentListNode(location, ptr->value());
    214216    ArgumentListNode* tail = head;
     
    325327        && !generator.symbolTable().slowArguments()) {
    326328        RegisterID* property = generator.emitNode(m_subscript);
    327         generator.emitExpressionInfo(divot(), startOffset(), endOffset());   
     329        generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    328330        return generator.emitGetArgumentByVal(generator.finalDestination(dst), generator.uncheckedRegisterForArguments(), property);
    329331    }
     
    331333    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
    332334    RegisterID* property = generator.emitNode(m_subscript);
    333     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     335    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    334336    return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
    335337}
     
    345347        if (!generator.willResolveToArguments(resolveNode->identifier()))
    346348            goto nonArgumentsPath;
    347         generator.emitExpressionInfo(divot(), startOffset(), endOffset());   
     349        generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    348350        return generator.emitGetArgumentsLength(generator.finalDestination(dst), generator.uncheckedRegisterForArguments());
    349351    }
     
    351353nonArgumentsPath:
    352354    RegisterID* base = generator.emitNode(m_base);
    353     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     355    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    354356    return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
    355357}
     
    374376    RefPtr<RegisterID> func = generator.emitNode(m_expr);
    375377    CallArguments callArguments(generator, m_args);
    376     return generator.emitConstruct(generator.finalDestinationOrIgnored(dst), func.get(), expectedFunction, callArguments, divot(), startOffset(), endOffset());
     378    return generator.emitConstruct(generator.finalDestinationOrIgnored(dst), func.get(), expectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    377379}
    378380
     
    409411    RefPtr<RegisterID> func = generator.tempDestination(dst);
    410412    CallArguments callArguments(generator, m_args);
    411     generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
     413    generator.emitExpressionInfo(divot() - divotStartOffset() + 4, 4, 0, divotLine(), divotLineStart());
    412414    generator.emitResolveWithThis(callArguments.thisRegister(), func.get(), generator.resolve(generator.propertyNames().eval), generator.propertyNames().eval);
    413     return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset());
     415    return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    414416}
    415417
     
    421423    CallArguments callArguments(generator, m_args);
    422424    generator.emitLoad(callArguments.thisRegister(), jsUndefined());
    423     return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     425    return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    424426}
    425427
     
    437439        // This passes NoExpectedFunction because we expect that if the function is in a
    438440        // local variable, then it's not one of our built-in constructors.
    439         return generator.emitCall(generator.finalDestinationOrIgnored(dst, callArguments.thisRegister()), func.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     441        return generator.emitCall(generator.finalDestinationOrIgnored(dst, callArguments.thisRegister()), func.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    440442    }
    441443
     
    445447        generator.emitGetStaticVar(func.get(), resolveResult, m_ident);
    446448        generator.emitLoad(callArguments.thisRegister(), jsUndefined());
    447         return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), expectedFunction, callArguments, divot(), startOffset(), endOffset());
     449        return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), expectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    448450    }
    449451
    450452    RefPtr<RegisterID> func = generator.newTemporary();
    451453    CallArguments callArguments(generator, m_args);
    452     int identifierStart = divot() - startOffset();
    453 
    454     generator.emitExpressionInfo(identifierStart + m_ident.length(), m_ident.length(), 0);
     454    int identifierStart = divot() - divotStartOffset();
     455
     456    generator.emitExpressionInfo(identifierStart + m_ident.length(), m_ident.length(), 0, divotLine(), divotLineStart());
    455457    generator.emitResolveWithThis(callArguments.thisRegister(), func.get(), resolveResult, m_ident);
    456     return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), expectedFunction, callArguments, divot(), startOffset(), endOffset());
     458    return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), expectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    457459}
    458460
     
    463465    RefPtr<RegisterID> base = generator.emitNode(m_base);
    464466    RegisterID* property = generator.emitNode(m_subscript);
    465     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     467    generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
    466468    RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
    467469    CallArguments callArguments(generator, m_args);
    468470    generator.emitMove(callArguments.thisRegister(), base.get());
    469     return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     471    return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    470472}
    471473
     
    477479    CallArguments callArguments(generator, m_args);
    478480    generator.emitNode(callArguments.thisRegister(), m_base);
    479     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     481    generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
    480482    generator.emitGetById(function.get(), callArguments.thisRegister(), m_ident);
    481     return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     483    return generator.emitCall(generator.finalDestinationOrIgnored(dst, function.get()), function.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    482484}
    483485
     
    487489    RefPtr<Label> end = generator.newLabel();
    488490    RefPtr<RegisterID> base = generator.emitNode(m_base);
    489     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     491    generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
    490492    RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
    491493    RefPtr<RegisterID> finalDestinationOrIgnored = generator.finalDestinationOrIgnored(dst, function.get());
     
    499501            CallArguments callArguments(generator, m_args);
    500502            generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
    501             generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     503            generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    502504            generator.emitJump(end.get());
    503505
     
    507509            CallArguments callArguments(generator, m_args);
    508510            generator.emitLoad(callArguments.thisRegister(), jsUndefined());
    509             generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     511            generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    510512            generator.emitJump(end.get());
    511513        }
     
    515517        CallArguments callArguments(generator, m_args);
    516518        generator.emitMove(callArguments.thisRegister(), base.get());
    517         generator.emitCall(finalDestinationOrIgnored.get(), function.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     519        generator.emitCall(finalDestinationOrIgnored.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    518520    }
    519521    generator.emitLabel(end.get());
     
    537539    RefPtr<Label> end = generator.newLabel();
    538540    RefPtr<RegisterID> base = generator.emitNode(m_base);
    539     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     541    generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
    540542    RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
    541543    RefPtr<RegisterID> finalDestinationOrIgnored = generator.finalDestinationOrIgnored(dst, function.get());
     
    548550                    ASSERT(m_args->m_listNode->m_next->m_expr->isSimpleArray());
    549551                    ASSERT(!m_args->m_listNode->m_next->m_next);
    550                     m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.vm(), 0, 0);
     552                    m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_next->m_expr)->toArgumentList(generator.vm(), 0, 0, 0);
    551553                    RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
    552554                    CallArguments callArguments(generator, m_args);
    553555                    generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
    554                     generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     556                    generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    555557                } else {
    556558                    m_args->m_listNode = m_args->m_listNode->m_next;
     
    558560                    CallArguments callArguments(generator, m_args);
    559561                    generator.emitNode(callArguments.thisRegister(), oldList->m_expr);
    560                     generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     562                    generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    561563                }
    562564                m_args->m_listNode = oldList;
     
    565567                CallArguments callArguments(generator, m_args);
    566568                generator.emitLoad(callArguments.thisRegister(), jsUndefined());
    567                 generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     569                generator.emitCall(finalDestinationOrIgnored.get(), realFunction.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    568570            }
    569571        } else {
     
    586588                generator.emitNode(args->m_expr);
    587589
    588             generator.emitCallVarargs(finalDestinationOrIgnored.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), profileHookRegister.get(), divot(), startOffset(), endOffset());
     590            generator.emitCallVarargs(finalDestinationOrIgnored.get(), realFunction.get(), thisRegister.get(), argsRegister.get(), generator.newTemporary(), profileHookRegister.get(), divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    589591        }
    590592        generator.emitJump(end.get());
     
    594596        CallArguments callArguments(generator, m_args);
    595597        generator.emitMove(callArguments.thisRegister(), base.get());
    596         generator.emitCall(finalDestinationOrIgnored.get(), function.get(), NoExpectedFunction, callArguments, divot(), startOffset(), endOffset());
     598        generator.emitCall(finalDestinationOrIgnored.get(), function.get(), NoExpectedFunction, callArguments, divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    597599    }
    598600    generator.emitLabel(end.get());
     
    642644    }
    643645
    644     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     646    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    645647    RefPtr<RegisterID> value = generator.newTemporary();
    646648    NonlocalResolveInfo resolveInfo;
     
    664666    RefPtr<RegisterID> property = generator.emitNode(subscript);
    665667
    666     generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->startOffset(), bracketAccessor->endOffset());
     668    generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStartOffset(), bracketAccessor->divotEndOffset(), bracketAccessor->divotLine(), bracketAccessor->divotLineStart());
    667669    RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
    668670    RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
    669     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     671    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    670672    generator.emitPutByVal(base.get(), property.get(), value.get());
    671673    return generator.moveToDestinationIfNeeded(dst, oldValue);
     
    684686    RefPtr<RegisterID> base = generator.emitNode(baseNode);
    685687
    686     generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->startOffset(), dotAccessor->endOffset());
     688    generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStartOffset(), dotAccessor->divotEndOffset(), dotAccessor->divotLine(), dotAccessor->divotLineStart());
    687689    RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), ident);
    688690    RegisterID* oldValue = emitPostIncOrDec(generator, generator.tempDestination(dst), value.get(), m_operator);
    689     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     691    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    690692    generator.emitPutById(base.get(), ident, value.get());
    691693    return generator.moveToDestinationIfNeeded(dst, oldValue);
     
    716718        return generator.emitLoad(generator.finalDestination(dst), false);
    717719
    718     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     720    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    719721    RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), resolveResult, m_ident);
    720722    return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
     
    728730    RegisterID* r1 = generator.emitNode(m_subscript);
    729731
    730     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     732    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    731733    return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
    732734}
     
    738740    RegisterID* r0 = generator.emitNode(m_base);
    739741
    740     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     742    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    741743    return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
    742744}
     
    824826    }
    825827
    826     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     828    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    827829    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
    828830    NonlocalResolveInfo resolveVerifier;
     
    844846    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
    845847
    846     generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->startOffset(), bracketAccessor->endOffset());
     848    generator.emitExpressionInfo(bracketAccessor->divot(), bracketAccessor->divotStartOffset(), bracketAccessor->divotEndOffset(), bracketAccessor->divotLine(), bracketAccessor->divotLineStart());
    847849    RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
    848850    emitIncOrDec(generator, value, m_operator);
    849     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     851    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    850852    generator.emitPutByVal(base.get(), property.get(), value);
    851853    return generator.moveToDestinationIfNeeded(dst, propDst.get());
     
    862864    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
    863865
    864     generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->startOffset(), dotAccessor->endOffset());
     866    generator.emitExpressionInfo(dotAccessor->divot(), dotAccessor->divotStartOffset(), dotAccessor->divotEndOffset(), dotAccessor->divotLine(), dotAccessor->divotLineStart());
    865867    RegisterID* value = generator.emitGetById(propDst.get(), base.get(), ident);
    866868    emitIncOrDec(generator, value, m_operator);
    867     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     869    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    868870    generator.emitPutById(base.get(), ident, value);
    869871    return generator.moveToDestinationIfNeeded(dst, propDst.get());
     
    891893{
    892894    RegisterID* src = generator.emitNode(m_expr);
     895    generator.emitExpressionInfo(startOffset(), 0, 0, lineNo(), lineStartOffset());
    893896    return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
    894897}
     
    10221025    // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
    10231026    if (emitExpressionInfoForMe)
    1024         generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
     1027        generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStartOffset(), emitExpressionInfoForMe->divotEndOffset(), emitExpressionInfoForMe->divotLine(), emitExpressionInfoForMe->divotLineStart());
    10251028
    10261029    // If there is an assignment convert the lhs now.  This will also copy lhs to
     
    11621165    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
    11631166    RegisterID* src2 = generator.emitNode(m_expr2);
    1164     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     1167    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    11651168    return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
    11661169}
     
    11741177    RefPtr<Label> target = generator.newLabel();
    11751178
    1176     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     1179    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    11771180    generator.emitCheckHasInstance(dstReg.get(), src1.get(), src2.get(), target.get());
    11781181
    1179     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     1182    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    11801183    generator.emitGetById(prototype.get(), src2.get(), generator.vm()->propertyNames->prototype);
    11811184
    1182     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     1185    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    11831186    RegisterID* result = generator.emitInstanceOf(dstReg.get(), src1.get(), prototype.get());
    11841187    generator.emitLabel(target.get());
     
    12911294    // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
    12921295    if (emitExpressionInfoForMe)
    1293         generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
     1296        generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->divotStartOffset(), emitExpressionInfoForMe->divotEndOffset(), emitExpressionInfoForMe->divotLine(), emitExpressionInfoForMe->divotLineStart());
    12941297
    12951298    return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
     
    13261329
    13271330    RefPtr<RegisterID> src1 = generator.tempDestination(dst);
    1328     generator.emitExpressionInfo(divot() - startOffset() + m_ident.length(), m_ident.length(), 0);
     1331    generator.emitExpressionInfo(divot() - divotStartOffset() + m_ident.length(), m_ident.length(), 0, divotLine(), divotLineStart());
    13291332    NonlocalResolveInfo resolveVerifier;
    13301333    RefPtr<RegisterID> base = generator.emitResolveWithBaseForPut(generator.newTemporary(), src1.get(), resolveResult, m_ident, resolveVerifier);
     
    13611364        dst = 0;
    13621365    RegisterID* value = generator.emitNode(dst, m_right);
    1363     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     1366    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    13641367    return generator.emitPutToBase(base.get(), m_ident, value, resolveVerifier);
    13651368}
     
    13721375    RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
    13731376    RegisterID* result = generator.emitNode(value.get(), m_right);
    1374     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     1377    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    13751378    RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result : generator.moveToDestinationIfNeeded(generator.tempDestination(result), result);
    13761379    generator.emitPutById(base.get(), m_ident, forwardResult);
     
    13841387    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
    13851388
    1386     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     1389    generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
    13871390    RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
    13881391    RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
    13891392
    1390     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     1393    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    13911394    return generator.emitPutById(base.get(), m_ident, updatedValue);
    13921395}
     
    14081411    RegisterID* result = generator.emitNode(value.get(), m_right);
    14091412
    1410     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     1413    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    14111414    RegisterID* forwardResult = (dst == generator.ignoredResult()) ? result : generator.moveToDestinationIfNeeded(generator.tempDestination(result), result);
    14121415    generator.emitPutByVal(base.get(), property.get(), forwardResult);
     
    14211424    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
    14221425
    1423     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     1426    generator.emitExpressionInfo(subexpressionDivot(), subexpressionStartOffset(), subexpressionEndOffset(), subexpressionLine(), subexpressionLineStart());
    14241427    RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
    14251428    RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
    14261429
    1427     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     1430    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    14281431    generator.emitPutByVal(base.get(), property.get(), updatedValue);
    14291432
     
    14811484void ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    14821485{
    1483     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1486    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    14841487    generator.emitNode(m_next);
    14851488}
     
    15241527void EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    15251528{
    1526     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1529    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    15271530}
    15281531
     
    15311534void DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    15321535{
    1533     generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine(), charPosition());
     1536    generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine(), startOffset(), lineStartOffset());
    15341537}
    15351538
     
    15391542{
    15401543    ASSERT(m_expr);
    1541     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1544    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    15421545    generator.emitNode(dst, m_expr);
    15431546}
     
    15481551{
    15491552    ASSERT(m_expr);
    1550     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1553    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    15511554    generator.emitNode(m_expr);
    15521555}
     
    15931596void IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    15941597{
    1595     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1598    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    15961599   
    15971600    RefPtr<Label> beforeThen = generator.newLabel();
     
    16301633    generator.emitLabel(topOfLoop.get());
    16311634    generator.emitLoopHint();
    1632     generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), charPosition());
     1635    generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), startOffset(), lineStartOffset());
    16331636
    16341637    generator.emitNode(dst, m_statement);
    16351638
    16361639    generator.emitLabel(scope->continueTarget());
    1637     generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), charPosition());
     1640    generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), startOffset(), lineStartOffset());
    16381641    generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
    16391642
     
    16481651    RefPtr<Label> topOfLoop = generator.newLabel();
    16491652
    1650     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), m_expr->charPosition());
     1653    generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), m_expr->startOffset(), m_expr->lineStartOffset());
    16511654    generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansTrue);
    16521655
     
    16571660
    16581661    generator.emitLabel(scope->continueTarget());
    1659     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1662    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    16601663
    16611664    generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), FallThroughMeansFalse);
     
    16701673    LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
    16711674
    1672     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1675    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    16731676
    16741677    if (m_expr1)
     
    16851688
    16861689    generator.emitLabel(scope->continueTarget());
    1687     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1690    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    16881691    if (m_expr3)
    16891692        generator.emitNode(generator.ignoredResult(), m_expr3);
     
    17081711    }
    17091712
    1710     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1713    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    17111714
    17121715    if (m_init)
     
    17371740            RegisterID* base = generator.emitResolveBaseForPut(generator.newTemporary(), resolveResult, ident, resolveVerifier);
    17381741
    1739             generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     1742            generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    17401743            generator.emitPutToBase(base, ident, propertyName, resolveVerifier);
    17411744        } else {
     
    17511754        RegisterID* base = generator.emitNode(assignNode->base());
    17521755
    1753         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
     1756        generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStartOffset(), assignNode->divotEndOffset(), assignNode->divotLine(), assignNode->divotLineStart());
    17541757        generator.emitPutById(base, ident, propertyName);
    17551758    } else {
     
    17611764        RegisterID* subscript = generator.emitNode(assignNode->subscript());
    17621765       
    1763         generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
     1766        generator.emitExpressionInfo(assignNode->divot(), assignNode->divotStartOffset(), assignNode->divotEndOffset(), assignNode->divotLine(), assignNode->divotLineStart());
    17641767        generator.emitPutByVal(base.get(), subscript, propertyName);
    17651768    }   
     
    17721775    generator.emitLabel(scope->continueTarget());
    17731776    generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get());
    1774     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1777    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    17751778    generator.emitLabel(scope->breakTarget());
    17761779}
     
    17941797void ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    17951798{
    1796     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1799    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    17971800   
    17981801    LabelScope* scope = generator.continueTarget(m_ident);
     
    18211824void BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    18221825{
    1823     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1826    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    18241827   
    18251828    LabelScope* scope = generator.breakTarget(m_ident);
     
    18341837void ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    18351838{
    1836     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1839    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    18371840    ASSERT(generator.codeType() == FunctionCode);
    18381841
     
    18461849    }
    18471850
    1848     generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), charPosition());
     1851    generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), startOffset(), lineStartOffset());
    18491852    generator.emitReturn(returnRegister.get());
    18501853}
     
    18541857void WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    18551858{
    1856     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     1859    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    18571860
    18581861    RefPtr<RegisterID> scope = generator.emitNode(m_expr);
    1859     generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
     1862    generator.emitExpressionInfo(m_divot, m_expressionLength, 0, m_divotLine, m_divotLineStart);
    18601863    generator.emitPushWithScope(scope.get());
    18611864    generator.emitNode(dst, m_statement);
     
    20282031void SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    20292032{
    2030     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     2033    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    20312034   
    20322035    LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
     
    20422045void LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    20432046{
    2044     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     2047    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    20452048
    20462049    ASSERT(!generator.breakTarget(m_name));
     
    20562059void ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
    20572060{
    2058     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     2061    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    20592062
    20602063    if (dst == generator.ignoredResult())
    20612064        dst = 0;
    20622065    RefPtr<RegisterID> expr = generator.emitNode(m_expr);
    2063     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     2066    generator.emitExpressionInfo(divot(), divotStartOffset(), divotEndOffset(), divotLine(), divotLineStart());
    20642067    generator.emitThrow(expr.get());
    20652068}
     
    20722075    // optimizer knows they may be jumped to from anywhere.
    20732076
    2074     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
     2077    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), startOffset(), lineStartOffset());
    20752078
    20762079    ASSERT(m_catchBlock || m_finallyBlock);
     
    21402143void ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    21412144{
    2142     generator.emitDebugHook(WillExecuteProgram, startLine(), startLine(), startCharPosition());
     2145    generator.emitDebugHook(WillExecuteProgram, startLine(), startLine(), startStartOffset(), startLineStartOffset());
    21432146
    21442147    RefPtr<RegisterID> dstRegister = generator.newTemporary();
     
    21462149    emitStatementsBytecode(generator, dstRegister.get());
    21472150
    2148     generator.emitDebugHook(DidExecuteProgram, lastLine(), lastLine(), charPosition() - 1);
     2151    generator.emitDebugHook(DidExecuteProgram, lastLine(), lastLine(), startOffset(), lineStartOffset());
    21492152    generator.emitEnd(dstRegister.get());
    21502153}
     
    21542157void EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    21552158{
    2156     generator.emitDebugHook(WillExecuteProgram, startLine(), startLine(), startCharPosition());
     2159    generator.emitDebugHook(WillExecuteProgram, startLine(), startLine(), startStartOffset(), startLineStartOffset());
    21572160
    21582161    RefPtr<RegisterID> dstRegister = generator.newTemporary();
     
    21602163    emitStatementsBytecode(generator, dstRegister.get());
    21612164
    2162     generator.emitDebugHook(DidExecuteProgram, lastLine(), lastLine(), charPosition() - 1);
     2165    generator.emitDebugHook(DidExecuteProgram, lastLine(), lastLine(), startOffset(), lineStartOffset());
    21632166    generator.emitEnd(dstRegister.get());
    21642167}
     
    21682171void FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
    21692172{
    2170     generator.emitDebugHook(DidEnterCallFrame, startLine(), startLine(), startCharPosition());
     2173    generator.emitDebugHook(DidEnterCallFrame, startLine(), startLine(), startStartOffset(), startLineStartOffset());
    21712174    emitStatementsBytecode(generator, generator.ignoredResult());
    21722175
     
    21842187    if (!returnNode) {
    21852188        RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined());
    2186         ASSERT((charPosition() -  1) >= 0);
    2187         generator.emitDebugHook(WillLeaveCallFrame, lastLine(), lastLine(), charPosition() - 1);
     2189        ASSERT((startOffset() -  1) >= lineStartOffset());
     2190        generator.emitDebugHook(WillLeaveCallFrame, lastLine(), lastLine(), startOffset() - 1, lineStartOffset());
    21882191        generator.emitReturn(r0);
    21892192        return;
Note: See TracChangeset for help on using the changeset viewer.