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/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;
     }