Source/JavaScriptCore: Fix incorrect debugger column number value.
https://bugs.webkit.org/show_bug.cgi?id=112741.
Reviewed by Oliver Hunt.
1. In lexer, parser, and debugger code, renamed column to charPosition.
2. Convert the charPosition to the equivalent column number before
passing it to the debugger.
3. Changed ScopeNodes to take both a startLocation and an endLocation.
This allows FunctionBodyNodes, ProgramNodes, and EvalNodess to emit
correct debug hooks with correct starting line and column numbers.
4. Fixed the Lexer to not reset the charPosition (previously
columnNumber) in Lexer::lex().
* JavaScriptCore.order:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreExports.def:
* JavaScriptCore.vcxproj/JavaScriptCoreExportGenerator/JavaScriptCoreExports.def.in:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitDebugHook):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitExpressionInfo):
* bytecompiler/NodesCodegen.cpp:
(JSC::ArrayNode::toArgumentList):
(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):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::debug):
- convert charPosition to column for the debugger.
* interpreter/Interpreter.h:
* jit/JITStubs.cpp:
(DEFINE_STUB_FUNCTION(void, op_debug)):
* llint/LLIntSlowPaths.cpp:
(LLINT_SLOW_PATH_DECL(slow_op_debug)):
* parser/ASTBuilder.h:
(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::createWithStatement):
(JSC::ASTBuilder::createThrowStatement):
(JSC::ASTBuilder::createDebugger):
(JSC::ASTBuilder::createConstStatement):
* parser/Lexer.cpp:
(JSC::::setCode):
(JSC::::internalShift):
(JSC::::shift):
(JSC::::lex):
* parser/Lexer.h:
(JSC::Lexer::currentCharPosition):
(Lexer):
(JSC::::lexExpectIdentifier):
* parser/NodeConstructors.h:
(JSC::Node::Node):
* parser/Nodes.cpp:
(JSC::StatementNode::setLoc):
(JSC::ScopeNode::ScopeNode):
(JSC::ProgramNode::ProgramNode):
(JSC::ProgramNode::create):
(JSC::EvalNode::EvalNode):
(JSC::EvalNode::create):
(JSC::FunctionBodyNode::FunctionBodyNode):
(JSC::FunctionBodyNode::create):
* parser/Nodes.h:
(JSC::Node::charPosition):
(Node):
(StatementNode):
(JSC::StatementNode::lastLine):
(ScopeNode):
(JSC::ScopeNode::startLine):
(JSC::ScopeNode::startCharPosition):
(ProgramNode):
(EvalNode):
(FunctionBodyNode):
* parser/Parser.cpp:
(JSC::::Parser):
(JSC::::parseFunctionBody):
(JSC::::parseFunctionInfo):
* parser/Parser.h:
(JSC::::parse):
* parser/ParserTokens.h:
(JSC::JSTokenLocation::JSTokenLocation):
(JSTokenLocation):
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createFunctionBody):
Source/WTF: Introducing String::reverseFindLineTerminator().
https://bugs.webkit.org/show_bug.cgi?id=112741.
Reviewed by Oliver Hunt.
This is needed by the JSC debugger code for computing column numbers.
* wtf/text/StringImpl.cpp:
(WTF::StringImpl::reverseFindLineTerminator):
* wtf/text/StringImpl.h:
(StringImpl):
(WTF::reverseFindLineTerminator):
* wtf/text/WTFString.h:
(WTF::String::reverseFindLineTerminator):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@146318 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 58fae82..bf3de32 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
* Copyright (C) 2012 Igalia, S.L.
*
@@ -2121,7 +2121,7 @@
m_dynamicScopeDepth--;
}
-void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine, int column)
+void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine, int charPosition)
{
#if ENABLE(DEBUG_WITH_BREAKPOINT)
if (debugHookID != DidReachBreakpoint)
@@ -2134,7 +2134,7 @@
instructions().append(debugHookID);
instructions().append(firstLine);
instructions().append(lastLine);
- instructions().append(column);
+ instructions().append(charPosition);
}
void BytecodeGenerator::pushFinallyContext(StatementNode* finallyBlock)
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index f9d2ab7..9a394ab 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
* Copyright (C) 2012 Igalia, S.L.
*
@@ -374,7 +374,7 @@
} else if (startOffset > ExpressionRangeInfo::MaxOffset) {
// If the start offset is out of bounds we clear both offsets
// so we only get the divot marker. Error message will have to be reduced
- // to line and column number.
+ // to line and charPosition number.
startOffset = 0;
endOffset = 0;
} else if (endOffset > ExpressionRangeInfo::MaxOffset) {
@@ -511,7 +511,7 @@
RegisterID* emitPushWithScope(RegisterID* scope);
void emitPopScope();
- void emitDebugHook(DebugHookID, int firstLine, int lastLine, int column);
+ void emitDebugHook(DebugHookID, int firstLine, int lastLine, int charPosition);
int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; }
bool hasFinaliser() { return m_finallyDepth != 0; }
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 3c234d9..60ef2d8 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
-* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
+* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
* Copyright (C) 2007 Maks Orlovich
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -201,7 +201,7 @@
return true;
}
-ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData, int lineNumber, int columnNumber) const
+ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData, int lineNumber, int charPosition) const
{
ASSERT(!m_elision && !m_optional);
ElementNode* ptr = m_element;
@@ -209,7 +209,7 @@
return 0;
JSTokenLocation location;
location.line = lineNumber;
- location.column = columnNumber;
+ location.charPosition = charPosition;
ArgumentListNode* head = new (globalData) ArgumentListNode(location, ptr->value());
ArgumentListNode* tail = head;
ptr = ptr->next();
@@ -1462,7 +1462,7 @@
RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
return generator.emitNode(m_next);
}
@@ -1505,7 +1505,7 @@
RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
return dst;
}
@@ -1513,7 +1513,7 @@
RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine(), column());
+ generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine(), charPosition());
return dst;
}
@@ -1522,7 +1522,7 @@
RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
ASSERT(m_expr);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
return generator.emitNode(dst, m_expr);
}
@@ -1531,7 +1531,7 @@
RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
ASSERT(m_expr);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
return generator.emitNode(m_expr);
}
@@ -1539,7 +1539,7 @@
RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
RefPtr<Label> afterThen = generator.newLabel();
@@ -1563,7 +1563,7 @@
RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
RefPtr<Label> beforeElse = generator.newLabel();
RefPtr<Label> afterElse = generator.newLabel();
@@ -1599,12 +1599,12 @@
RefPtr<Label> topOfLoop = generator.newLabel();
generator.emitLabel(topOfLoop.get());
generator.emitLoopHint();
- generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), charPosition());
RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
generator.emitLabel(scope->continueTarget());
- generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, lastLine(), lastLine(), charPosition());
if (m_expr->hasConditionContextCodegen())
generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
else {
@@ -1623,7 +1623,7 @@
LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
RefPtr<Label> topOfLoop = generator.newLabel();
- generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), m_expr->columnNo());
+ generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo(), m_expr->charPosition());
if (m_expr->hasConditionContextCodegen())
generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), true);
else {
@@ -1637,7 +1637,7 @@
generator.emitNode(dst, m_statement);
generator.emitLabel(scope->continueTarget());
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
if (m_expr->hasConditionContextCodegen())
generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false);
@@ -1658,7 +1658,7 @@
{
LabelScopePtr scope = generator.newLabelScope(LabelScope::Loop);
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
if (m_expr1)
generator.emitNode(generator.ignoredResult(), m_expr1);
@@ -1679,7 +1679,7 @@
RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
generator.emitLabel(scope->continueTarget());
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
if (m_expr3)
generator.emitNode(generator.ignoredResult(), m_expr3);
@@ -1706,7 +1706,7 @@
if (!m_lexpr->isLocation())
return emitThrowReferenceError(generator, "Left side of for-in statement is not a reference.");
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
if (m_init)
generator.emitNode(generator.ignoredResult(), m_init);
@@ -1770,7 +1770,7 @@
generator.emitLabel(scope->continueTarget());
generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get());
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
generator.emitLabel(scope->breakTarget());
return dst;
}
@@ -1780,7 +1780,7 @@
// ECMA 12.7
RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
LabelScope* scope = generator.continueTarget(m_ident);
ASSERT(scope);
@@ -1794,7 +1794,7 @@
// ECMA 12.8
RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
LabelScope* scope = generator.breakTarget(m_ident);
ASSERT(scope);
@@ -1807,7 +1807,7 @@
RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
ASSERT(generator.codeType() == FunctionCode);
if (dst == generator.ignoredResult())
@@ -1823,7 +1823,7 @@
generator.emitJumpScopes(l0.get(), 0);
generator.emitLabel(l0.get());
}
- generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine(), charPosition());
return generator.emitReturn(r0);
}
@@ -1831,7 +1831,7 @@
RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
RefPtr<RegisterID> scope = generator.emitNode(m_expr);
generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
@@ -2008,7 +2008,7 @@
RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
LabelScopePtr scope = generator.newLabelScope(LabelScope::Switch);
@@ -2023,7 +2023,7 @@
RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
ASSERT(!generator.breakTarget(m_name));
@@ -2038,7 +2038,7 @@
RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
if (dst == generator.ignoredResult())
dst = 0;
@@ -2055,7 +2055,7 @@
// 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(), column());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), charPosition());
ASSERT(m_catchBlock || m_finallyBlock);
@@ -2124,13 +2124,13 @@
RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteProgram, startLine(), startLine(), startCharPosition());
RefPtr<RegisterID> dstRegister = generator.newTemporary();
generator.emitLoad(dstRegister.get(), jsUndefined());
emitStatementsBytecode(generator, dstRegister.get());
- generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine(), column());
+ generator.emitDebugHook(DidExecuteProgram, lastLine(), lastLine(), charPosition() - 1);
generator.emitEnd(dstRegister.get());
return 0;
}
@@ -2139,13 +2139,13 @@
RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine(), column());
+ generator.emitDebugHook(WillExecuteProgram, startLine(), startLine(), startCharPosition());
RefPtr<RegisterID> dstRegister = generator.newTemporary();
generator.emitLoad(dstRegister.get(), jsUndefined());
emitStatementsBytecode(generator, dstRegister.get());
- generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine(), column());
+ generator.emitDebugHook(DidExecuteProgram, lastLine(), lastLine(), charPosition() - 1);
generator.emitEnd(dstRegister.get());
return 0;
}
@@ -2154,7 +2154,7 @@
RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
- generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine(), column());
+ generator.emitDebugHook(DidEnterCallFrame, startLine(), startLine(), startCharPosition());
emitStatementsBytecode(generator, generator.ignoredResult());
StatementNode* singleStatement = this->singleStatement();
@@ -2170,7 +2170,8 @@
// 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(), column());
+ ASSERT((charPosition() - 1) >= 0);
+ generator.emitDebugHook(WillLeaveCallFrame, lastLine(), lastLine(), charPosition() - 1);
generator.emitReturn(r0);
return 0;
}