diff options
Diffstat (limited to 'Source/JavaScriptCore/parser')
-rw-r--r-- | Source/JavaScriptCore/parser/ASTBuilder.h | 231 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/Lexer.cpp | 7 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/Lexer.h | 17 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/NodeConstructors.h | 101 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/Nodes.cpp | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/Nodes.h | 187 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/Parser.cpp | 240 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/Parser.h | 59 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/ParserTokens.h | 19 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/SyntaxChecker.h | 51 |
10 files changed, 426 insertions, 492 deletions
diff --git a/Source/JavaScriptCore/parser/ASTBuilder.h b/Source/JavaScriptCore/parser/ASTBuilder.h index 43d9b4f1b..4281e7ccd 100644 --- a/Source/JavaScriptCore/parser/ASTBuilder.h +++ b/Source/JavaScriptCore/parser/ASTBuilder.h @@ -33,20 +33,12 @@ namespace JSC { class ASTBuilder { - struct PositionInfo { - unsigned startPos; - unsigned line; - unsigned lineStartPos; - }; - struct BinaryOpInfo { BinaryOpInfo() {} - BinaryOpInfo(int otherStart, int otherDivot, int otherEnd, unsigned otherDivotLine, unsigned otherDivotLineStart, bool rhsHasAssignment) + BinaryOpInfo(const JSTextPosition& otherStart, const JSTextPosition& otherDivot, const JSTextPosition& otherEnd, bool rhsHasAssignment) : start(otherStart) , divot(otherDivot) , end(otherEnd) - , divotLine(otherDivotLine) - , divotLineStart(otherDivotLineStart) , hasAssignment(rhsHasAssignment) { } @@ -54,39 +46,31 @@ class ASTBuilder { : start(lhs.start) , divot(rhs.start) , end(rhs.end) - , divotLine(rhs.divotLine) - , divotLineStart(rhs.divotLineStart) , hasAssignment(lhs.hasAssignment || rhs.hasAssignment) { } - int start; - int divot; - int end; - unsigned divotLine; - unsigned divotLineStart; + JSTextPosition start; + JSTextPosition divot; + JSTextPosition end; bool hasAssignment; }; struct AssignmentInfo { AssignmentInfo() {} - AssignmentInfo(ExpressionNode* node, unsigned start, unsigned divot, unsigned divotLine, unsigned divotLineStart, int initAssignments, Operator op) + AssignmentInfo(ExpressionNode* node, const JSTextPosition& start, const JSTextPosition& divot, int initAssignments, Operator op) : m_node(node) , m_start(start) , m_divot(divot) - , m_divotLine(divotLine) - , m_divotLineStart(divotLineStart) , m_initAssignments(initAssignments) , m_op(op) { - ASSERT(m_divot >= m_divotLineStart); - ASSERT(m_start >= m_divotLineStart); + ASSERT(m_divot.offset >= m_divot.lineStartOffset); + ASSERT(m_start.offset >= m_start.lineStartOffset); } ExpressionNode* m_node; - unsigned m_start; - unsigned m_divot; - unsigned m_divotLine; - unsigned m_divotLineStart; + JSTextPosition m_start; + JSTextPosition m_divot; int m_initAssignments; Operator m_op; }; @@ -131,7 +115,7 @@ public: static const int DontBuildStrings = 0; ExpressionNode* makeBinaryNode(const JSTokenLocation&, int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>); - ExpressionNode* makeFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, ArgumentsNode* args, int start, unsigned divot, int end, unsigned divotLine, unsigned divotLineStart); + ExpressionNode* makeFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd); JSC::SourceElements* createSourceElements() { return new (m_vm) JSC::SourceElements(); } @@ -144,11 +128,11 @@ public: CommaNode* createCommaExpr(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* rhs) { return new (m_vm) CommaNode(location, lhs, rhs); } - ExpressionNode* makeAssignNode(const JSTokenLocation&, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart); - ExpressionNode* makePrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart); - ExpressionNode* makePostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart); + ExpressionNode* makeAssignNode(const JSTokenLocation&, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end); + ExpressionNode* makePrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end); + ExpressionNode* makePostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end); ExpressionNode* makeTypeOfNode(const JSTokenLocation&, ExpressionNode*); - ExpressionNode* makeDeleteNode(const JSTokenLocation&, ExpressionNode*, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart); + ExpressionNode* makeDeleteNode(const JSTokenLocation&, ExpressionNode*, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end); ExpressionNode* makeNegateNode(const JSTokenLocation&, ExpressionNode*); ExpressionNode* makeBitwiseNotNode(const JSTokenLocation&, ExpressionNode*); ExpressionNode* makeMultNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments); @@ -181,11 +165,11 @@ public: usesThis(); return new (m_vm) ThisNode(location); } - ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier* ident, unsigned start, unsigned divotLine, unsigned divotLineStart) + ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start) { if (m_vm->propertyNames->arguments == *ident) usesArguments(); - return new (m_vm) ResolveNode(location, *ident, start, divotLine, divotLineStart); + return new (m_vm) ResolveNode(location, *ident, start); } ExpressionNode* createObjectLiteral(const JSTokenLocation& location) { return new (m_vm) ObjectLiteralNode(location); } ExpressionNode* createObjectLiteral(const JSTokenLocation& location, PropertyListNode* properties) { return new (m_vm) ObjectLiteralNode(location, properties); } @@ -228,41 +212,42 @@ public: return new (m_vm) NullNode(location); } - ExpressionNode* createBracketAccess(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart) + ExpressionNode* createBracketAccess(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end) { BracketAccessorNode* node = new (m_vm) BracketAccessorNode(location, base, property, propertyHasAssignments); - setExceptionLocation(node, start, divot, end, divotLine, divotLineStart); + setExceptionLocation(node, start, divot, end); return node; } - ExpressionNode* createDotAccess(const JSTokenLocation& location, ExpressionNode* base, const Identifier* property, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart) + ExpressionNode* createDotAccess(const JSTokenLocation& location, ExpressionNode* base, const Identifier* property, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end) { DotAccessorNode* node = new (m_vm) DotAccessorNode(location, base, *property); - setExceptionLocation(node, start, divot, end, divotLine, divotLineStart); + setExceptionLocation(node, start, divot, end); return node; } - ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, int start, unsigned divotLine, unsigned divotLineStart) + ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, const JSTextPosition& start) { if (Yarr::checkSyntax(pattern.string())) return 0; RegExpNode* node = new (m_vm) RegExpNode(location, pattern, flags); int size = pattern.length() + 2; // + 2 for the two /'s - setExceptionLocation(node, start, start + size, start + size, divotLine, divotLineStart); + JSTextPosition end = start + size; + setExceptionLocation(node, start, end, end); return node; } - ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* arguments, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart) + ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* arguments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end) { NewExprNode* node = new (m_vm) NewExprNode(location, expr, arguments); - setExceptionLocation(node, start, divot, end, divotLine, divotLineStart); + setExceptionLocation(node, start, divot, end); return node; } - ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, int start, int end, unsigned divotLine, unsigned divotLineStart) + ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end) { NewExprNode* node = new (m_vm) NewExprNode(location, expr); - setExceptionLocation(node, start, end, end, divotLine, divotLineStart); + setExceptionLocation(node, start, end, end); return node; } @@ -271,12 +256,12 @@ public: return new (m_vm) ConditionalNode(location, condition, lhs, rhs); } - ExpressionNode* createAssignResolve(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* rhs, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart) + ExpressionNode* createAssignResolve(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* rhs, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end) { if (rhs->isFuncExprNode()) static_cast<FuncExprNode*>(rhs)->body()->setInferredName(ident); AssignResolveNode* node = new (m_vm) AssignResolveNode(location, ident, rhs); - setExceptionLocation(node, start, divot, end, divotLine, divotLineStart); + setExceptionLocation(node, start, divot, end); return node; } @@ -355,10 +340,10 @@ public: return block; } - StatementNode* createExprStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end) + StatementNode* createExprStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, int end) { ExprStatementNode* result = new (m_vm) ExprStatementNode(location, expr); - result->setLoc(start, end, location.startOffset, location.lineStartOffset); + result->setLoc(start.line, end, start.offset, start.lineStartOffset); return result; } @@ -376,19 +361,19 @@ public: return result; } - StatementNode* createForInLoop(const JSTokenLocation& location, const Identifier* ident, ExpressionNode* initializer, ExpressionNode* iter, StatementNode* statements, int start, int divot, int end, int initStart, int initEnd, int startLine, int endLine, unsigned divotLine, unsigned divotLineStart) + StatementNode* createForInLoop(const JSTokenLocation& location, const Identifier* ident, ExpressionNode* initializer, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end, const JSTextPosition& initStart, const JSTextPosition& initEnd, int startLine, int endLine) { - ForInNode* result = new (m_vm) ForInNode(m_vm, location, *ident, initializer, iter, statements, initStart, initStart - start, initEnd - initStart, divotLine, divotLineStart); + ForInNode* result = new (m_vm) ForInNode(m_vm, location, *ident, initializer, iter, statements, initStart, start, initEnd); result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset); - setExceptionLocation(result, start, divot + 1, end, divotLine, divotLineStart); + setExceptionLocation(result, start, divot + 1, end); return result; } - StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, int eStart, int eDivot, int eEnd, int start, int end, unsigned divotLine, unsigned divotLineStart) + StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end) { ForInNode* result = new (m_vm) ForInNode(location, lhs, iter, statements); result->setLoc(start, end, location.startOffset, location.lineStartOffset); - setExceptionLocation(result, eStart, eDivot, eEnd, divotLine, divotLineStart); + setExceptionLocation(result, eStart, eDivot, eEnd); return result; } @@ -405,43 +390,43 @@ public: return result; } - StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, int eStart, int eEnd, int startLine, int endLine, unsigned divotLine, unsigned divotLineStart) + StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& end) { ReturnNode* result = new (m_vm) ReturnNode(location, expression); - setExceptionLocation(result, eStart, eEnd, eEnd, divotLine, divotLineStart); - result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset); + setExceptionLocation(result, start, end, end); + result->setLoc(start.line, end.line, start.offset, start.lineStartOffset); return result; } - StatementNode* createBreakStatement(const JSTokenLocation& location, int eStart, int eEnd, int startLine, int endLine, unsigned endLineStart) + StatementNode* createBreakStatement(const JSTokenLocation& location, const JSTextPosition& start, const JSTextPosition& end) { BreakNode* result = new (m_vm) BreakNode(m_vm, location); - setExceptionLocation(result, eStart, eEnd, eEnd, endLine, endLineStart); - result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset); + setExceptionLocation(result, start, end, end); + result->setLoc(start.line, end.line, start.offset, start.lineStartOffset); return result; } - StatementNode* createBreakStatement(const JSTokenLocation& location, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine, unsigned endLineStart) + StatementNode* createBreakStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end) { BreakNode* result = new (m_vm) BreakNode(location, *ident); - setExceptionLocation(result, eStart, eEnd, eEnd, endLine, endLineStart); - result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset); + setExceptionLocation(result, start, end, end); + result->setLoc(start.line, end.line, start.offset, start.lineStartOffset); return result; } - StatementNode* createContinueStatement(const JSTokenLocation& location, int eStart, int eEnd, int startLine, int endLine, unsigned endLineStart) + StatementNode* createContinueStatement(const JSTokenLocation& location, const JSTextPosition& start, const JSTextPosition& end) { ContinueNode* result = new (m_vm) ContinueNode(m_vm, location); - setExceptionLocation(result, eStart, eEnd, eEnd, endLine, endLineStart); - result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset); + setExceptionLocation(result, start, end, end); + result->setLoc(start.line, end.line, start.offset, start.lineStartOffset); return result; } - StatementNode* createContinueStatement(const JSTokenLocation& location, const Identifier* ident, int eStart, int eEnd, int startLine, int endLine, unsigned endLineStart) + StatementNode* createContinueStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end) { ContinueNode* result = new (m_vm) ContinueNode(location, *ident); - setExceptionLocation(result, eStart, eEnd, eEnd, endLine, endLineStart); - result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset); + setExceptionLocation(result, start, end, end); + result->setLoc(start.line, end.line, start.offset, start.lineStartOffset); return result; } @@ -476,26 +461,26 @@ public: return result; } - StatementNode* createLabelStatement(const JSTokenLocation& location, const Identifier* ident, StatementNode* statement, unsigned start, unsigned end, unsigned divotLine, unsigned divotLineStart) + StatementNode* createLabelStatement(const JSTokenLocation& location, const Identifier* ident, StatementNode* statement, const JSTextPosition& start, const JSTextPosition& end) { LabelNode* result = new (m_vm) LabelNode(location, *ident, statement); - setExceptionLocation(result, start, end, end, divotLine, divotLineStart); + setExceptionLocation(result, start, end, end); return result; } - StatementNode* createWithStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, unsigned start, unsigned end, unsigned startLine, unsigned endLine, unsigned divotLine, unsigned divotLineStart) + StatementNode* createWithStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, unsigned start, const JSTextPosition& end, unsigned startLine, unsigned endLine) { usesWith(); - WithNode* result = new (m_vm) WithNode(location, expr, statement, end, divotLine, divotLineStart, end - start); + WithNode* result = new (m_vm) WithNode(location, expr, statement, end, end - start); result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset); return result; } - StatementNode* createThrowStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end, int startLine, int endLine, unsigned divotLine, unsigned divotLineStart) + StatementNode* createThrowStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end) { ThrowNode* result = new (m_vm) ThrowNode(location, expr); - result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset); - setExceptionLocation(result, start, end, end, divotLine, divotLineStart); + result->setLoc(start.line, end.line, start.offset, start.lineStartOffset); + setExceptionLocation(result, start, end, end); return result; } @@ -546,10 +531,10 @@ public: int evalCount() const { return m_evalCount; } - void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, unsigned divotLine, unsigned divotLineStart, bool hasAssignments) + void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, const JSTextPosition& exprStart, const JSTextPosition& lhs, const JSTextPosition& rhs, bool hasAssignments) { operandStackDepth++; - m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, divotLine, divotLineStart, hasAssignments))); + m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, hasAssignments))); } // Logic to handle datastructures used during parsing of binary expressions @@ -586,11 +571,10 @@ public: return result; } - void appendUnaryToken(int& tokenStackDepth, int type, unsigned start, unsigned divotLine, unsigned divotLineStart) + void appendUnaryToken(int& tokenStackDepth, int type, const JSTextPosition& start) { tokenStackDepth++; - PositionInfo position = { start, divotLine, divotLineStart }; - m_unaryTokenStack.append(std::make_pair(type, position)); + m_unaryTokenStack.append(std::make_pair(type, start)); } int unaryTokenStackLastType(int&) @@ -598,34 +582,29 @@ public: return m_unaryTokenStack.last().first; } - unsigned unaryTokenStackLastStart(int&) + const JSTextPosition& unaryTokenStackLastStart(int&) { - return m_unaryTokenStack.last().second.startPos; + return m_unaryTokenStack.last().second; } - unsigned unaryTokenStackLastLineStartPosition(int&) - { - return m_unaryTokenStack.last().second.lineStartPos; - } - void unaryTokenStackRemoveLast(int& tokenStackDepth) { tokenStackDepth--; m_unaryTokenStack.removeLast(); } - void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, unsigned start, unsigned divot, unsigned divotLine, unsigned divotLineStart, int assignmentCount, Operator op) + void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, const JSTextPosition& start, const JSTextPosition& divot, int assignmentCount, Operator op) { assignmentStackDepth++; - ASSERT(start >= divotLineStart); - ASSERT(divot >= divotLineStart); - m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, divotLine, divotLineStart, assignmentCount, op)); + ASSERT(start.offset >= start.lineStartOffset); + ASSERT(divot.offset >= divot.lineStartOffset); + m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op)); } - ExpressionNode* createAssignment(const JSTokenLocation& location, int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, int lastTokenEnd) + ExpressionNode* createAssignment(const JSTokenLocation& location, int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, const JSTextPosition& lastTokenEnd) { AssignmentInfo& info = m_assignmentInfoStack.last(); - ExpressionNode* result = makeAssignNode(location, info.m_node, info.m_op, rhs, info.m_initAssignments != initialAssignmentCount, info.m_initAssignments != currentAssignmentCount, info.m_start, info.m_divot + 1, lastTokenEnd, info.m_divotLine, info.m_divotLineStart); + ExpressionNode* result = makeAssignNode(location, info.m_node, info.m_op, rhs, info.m_initAssignments != initialAssignmentCount, info.m_initAssignments != currentAssignmentCount, info.m_start, info.m_divot + 1, lastTokenEnd); m_assignmentInfoStack.removeLast(); assignmentStackDepth--; return result; @@ -651,10 +630,10 @@ private: int m_numConstants; }; - static void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end, unsigned divotLine, unsigned divotLineStart) + static void setExceptionLocation(ThrowableExpressionData* node, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd) { - ASSERT(divot >= divotLineStart); - node->setExceptionSourceCode(divot, divot - start, end - divot, divotLine, divotLineStart); + ASSERT(divot.offset >= divot.lineStartOffset); + node->setExceptionSourceCode(divot, divotStart, divotEnd); } void incConstants() { m_scope.m_numConstants++; } @@ -678,7 +657,7 @@ private: Vector<BinaryOperand, 10, UnsafeVectorOverflow> m_binaryOperandStack; Vector<AssignmentInfo, 10, UnsafeVectorOverflow> m_assignmentInfoStack; Vector<pair<int, int>, 10, UnsafeVectorOverflow> m_binaryOperatorStack; - Vector<pair<int, PositionInfo>, 10, UnsafeVectorOverflow> m_unaryTokenStack; + Vector<pair<int, JSTextPosition>, 10, UnsafeVectorOverflow> m_unaryTokenStack; int m_evalCount; }; @@ -691,21 +670,21 @@ ExpressionNode* ASTBuilder::makeTypeOfNode(const JSTokenLocation& location, Expr return new (m_vm) TypeOfValueNode(location, expr); } -ExpressionNode* ASTBuilder::makeDeleteNode(const JSTokenLocation& location, ExpressionNode* expr, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart) +ExpressionNode* ASTBuilder::makeDeleteNode(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end) { if (!expr->isLocation()) return new (m_vm) DeleteValueNode(location, expr); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(expr); - return new (m_vm) DeleteResolveNode(location, resolve->identifier(), divot, divot - start, end - divot, divotLine, divotLineStart); + return new (m_vm) DeleteResolveNode(location, resolve->identifier(), divot, start, end); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr); - return new (m_vm) DeleteBracketNode(location, bracket->base(), bracket->subscript(), divot, divot - start, end - divot, divotLine, divotLineStart); + return new (m_vm) DeleteBracketNode(location, bracket->base(), bracket->subscript(), divot, start, end); } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr); - return new (m_vm) DeleteDotNode(location, dot->base(), dot->identifier(), divot, divot - start, end - divot, divotLine, divotLineStart); + return new (m_vm) DeleteDotNode(location, dot->base(), dot->identifier(), divot, start, end); } ExpressionNode* ASTBuilder::makeNegateNode(const JSTokenLocation& location, ExpressionNode* n) @@ -822,36 +801,36 @@ ExpressionNode* ASTBuilder::makeBitXOrNode(const JSTokenLocation& location, Expr return new (m_vm) BitXOrNode(location, expr1, expr2, rightHasAssignments); } -ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, ArgumentsNode* args, int start, unsigned divot, int end, unsigned divotLine, unsigned divotLineStart) +ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd) { - ASSERT(divot >= divotLineStart); + ASSERT(divot.offset >= divot.lineStartOffset); if (!func->isLocation()) - return new (m_vm) FunctionCallValueNode(location, func, args, divot, divot - start, end - divot, divotLine, divotLineStart); + return new (m_vm) FunctionCallValueNode(location, func, args, divot, divotStart, divotEnd); if (func->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(func); const Identifier& identifier = resolve->identifier(); if (identifier == m_vm->propertyNames->eval) { usesEval(); - return new (m_vm) EvalFunctionCallNode(location, args, divot, divot - start, end - divot, divotLine, divotLineStart); + return new (m_vm) EvalFunctionCallNode(location, args, divot, divotStart, divotEnd); } - return new (m_vm) FunctionCallResolveNode(location, identifier, args, divot, divot - start, end - divot, divotLine, divotLineStart); + return new (m_vm) FunctionCallResolveNode(location, identifier, args, divot, divotStart, divotEnd); } if (func->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func); - FunctionCallBracketNode* node = new (m_vm) FunctionCallBracketNode(location, bracket->base(), bracket->subscript(), args, divot, divot - start, end - divot, divotLine, divotLineStart); - node->setSubexpressionInfo(bracket->divot(), bracket->divotEndOffset(), bracket->divotLine(), bracket->divotLineStart()); + FunctionCallBracketNode* node = new (m_vm) FunctionCallBracketNode(location, bracket->base(), bracket->subscript(), args, divot, divotStart, divotEnd); + node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset); return node; } ASSERT(func->isDotAccessorNode()); DotAccessorNode* dot = static_cast<DotAccessorNode*>(func); FunctionCallDotNode* node; if (dot->identifier() == m_vm->propertyNames->call) - node = new (m_vm) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot, divotLine, divotLineStart); + node = new (m_vm) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd); else if (dot->identifier() == m_vm->propertyNames->apply) - node = new (m_vm) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot, divotLine, divotLineStart); + node = new (m_vm) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd); else - node = new (m_vm) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divot - start, end - divot, divotLine, divotLineStart); - node->setSubexpressionInfo(dot->divot(), dot->divotEndOffset(), dot->divotLine(), dot->divotLineStart()); + node = new (m_vm) FunctionCallDotNode(location, dot->base(), dot->identifier(), args, divot, divotStart, divotEnd); + node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset); return node; } @@ -899,13 +878,13 @@ ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int case INSTANCEOF: { InstanceOfNode* node = new (m_vm) InstanceOfNode(location, lhs.first, rhs.first, rhs.second.hasAssignment); - setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end, rhs.second.divotLine, rhs.second.divotLineStart); + setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end); return node; } case INTOKEN: { InNode* node = new (m_vm) InNode(location, lhs.first, rhs.first, rhs.second.hasAssignment); - setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end, rhs.second.divotLine, rhs.second.divotLineStart); + setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end); return node; } @@ -937,10 +916,10 @@ ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int return 0; } -ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart) +ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end) { if (!loc->isLocation()) - return new (m_vm) AssignErrorNode(location, divot, divot - start, end - divot, divotLine, divotLineStart); + return new (m_vm) AssignErrorNode(location, divot, start, end); if (loc->isResolveNode()) { ResolveNode* resolve = static_cast<ResolveNode*>(loc); @@ -948,17 +927,17 @@ ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, Expr if (expr->isFuncExprNode()) static_cast<FuncExprNode*>(expr)->body()->setInferredName(resolve->identifier()); AssignResolveNode* node = new (m_vm) AssignResolveNode(location, resolve->identifier(), expr); - setExceptionLocation(node, start, divot, end, divotLine, divotLineStart); + setExceptionLocation(node, start, divot, end); return node; } - return new (m_vm) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot, divotLine, divotLineStart); + return new (m_vm) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, start, end); } if (loc->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc); if (op == OpEqual) - return new (m_vm) AssignBracketNode(location, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot(), bracket->divotLine(), bracket->divotLineStart()); - ReadModifyBracketNode* node = new (m_vm) ReadModifyBracketNode(location, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot, divotLine, divotLineStart); - node->setSubexpressionInfo(bracket->divot(), bracket->divotEndOffset(), bracket->divotLine(), bracket->divotLineStart()); + return new (m_vm) AssignBracketNode(location, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), start, end); + ReadModifyBracketNode* node = new (m_vm) ReadModifyBracketNode(location, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, start, end); + node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset); return node; } ASSERT(loc->isDotAccessorNode()); @@ -966,22 +945,22 @@ ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, Expr if (op == OpEqual) { if (expr->isFuncExprNode()) static_cast<FuncExprNode*>(expr)->body()->setInferredName(dot->identifier()); - return new (m_vm) AssignDotNode(location, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot(), dot->divotLine(), dot->divotLineStart()); + return new (m_vm) AssignDotNode(location, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), start, end); } - ReadModifyDotNode* node = new (m_vm) ReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot, divotLine, divotLineStart); - node->setSubexpressionInfo(dot->divot(), dot->divotEndOffset(), dot->divotLine(), dot->divotLineStart()); + ReadModifyDotNode* node = new (m_vm) ReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, start, end); + node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset); return node; } -ExpressionNode* ASTBuilder::makePrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart) +ExpressionNode* ASTBuilder::makePrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end) { - return new (m_vm) PrefixNode(location, expr, op, divot, divot - start, end - divot, divotLine, divotLineStart); + return new (m_vm) PrefixNode(location, expr, op, divot, start, end); } -ExpressionNode* ASTBuilder::makePostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, int start, int divot, int end, unsigned divotLine, unsigned divotLineStart) +ExpressionNode* ASTBuilder::makePostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end) { - return new (m_vm) PostfixNode(location, expr, op, divot, divot - start, end - divot, divotLine, divotLineStart); + return new (m_vm) PostfixNode(location, expr, op, divot, start, end); } } diff --git a/Source/JavaScriptCore/parser/Lexer.cpp b/Source/JavaScriptCore/parser/Lexer.cpp index 4925656a7..37ab20689 100644 --- a/Source/JavaScriptCore/parser/Lexer.cpp +++ b/Source/JavaScriptCore/parser/Lexer.cpp @@ -1306,8 +1306,10 @@ bool Lexer<T>::nextTokenIsColon() } template <typename T> -JSTokenType Lexer<T>::lex(JSTokenData* tokenData, JSTokenLocation* tokenLocation, unsigned lexerFlags, bool strictMode) +JSTokenType Lexer<T>::lex(JSToken* tokenRecord, unsigned lexerFlags, bool strictMode) { + JSTokenData* tokenData = &tokenRecord->m_data; + JSTokenLocation* tokenLocation = &tokenRecord->m_location; ASSERT(!m_error); ASSERT(m_buffer8.isEmpty()); ASSERT(m_buffer16.isEmpty()); @@ -1324,6 +1326,7 @@ start: tokenLocation->startOffset = currentOffset(); ASSERT(currentOffset() >= currentLineStartOffset()); + tokenRecord->m_startPosition = currentPosition(); CharacterType type; if (LIKELY(isLatin1(m_current))) @@ -1699,6 +1702,7 @@ returnToken: tokenLocation->endOffset = currentOffset(); tokenLocation->lineStartOffset = currentLineStartOffset(); ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset); + tokenRecord->m_endPosition = currentPosition(); m_lastToken = token; return token; @@ -1708,6 +1712,7 @@ returnError: tokenLocation->endOffset = currentOffset(); tokenLocation->lineStartOffset = currentLineStartOffset(); ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset); + tokenRecord->m_endPosition = currentPosition(); RELEASE_ASSERT(token & ErrorTokenFlag); return token; } diff --git a/Source/JavaScriptCore/parser/Lexer.h b/Source/JavaScriptCore/parser/Lexer.h index 5ecdcc650..137ff5fb6 100644 --- a/Source/JavaScriptCore/parser/Lexer.h +++ b/Source/JavaScriptCore/parser/Lexer.h @@ -86,11 +86,15 @@ public: void setIsReparsing() { m_isReparsing = true; } bool isReparsing() const { return m_isReparsing; } - JSTokenType lex(JSTokenData*, JSTokenLocation*, unsigned, bool strictMode); + JSTokenType lex(JSToken*, unsigned, bool strictMode); bool nextTokenIsColon(); int lineNumber() const { return m_lineNumber; } ALWAYS_INLINE int currentOffset() const { return offsetFromSourcePtr(m_code); } ALWAYS_INLINE int currentLineStartOffset() const { return offsetFromSourcePtr(m_lineStart); } + ALWAYS_INLINE JSTextPosition currentPosition() const + { + return JSTextPosition(m_lineNumber, currentOffset(), currentLineStartOffset()); + } void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; } int lastLineNumber() const { return m_lastLineNumber; } bool prevTerminator() const { return m_terminator; } @@ -125,7 +129,7 @@ public: SourceProvider* sourceProvider() const { return m_source->provider(); } - JSTokenType lexExpectIdentifier(JSTokenData*, JSTokenLocation*, unsigned, bool strictMode); + JSTokenType lexExpectIdentifier(JSToken*, unsigned, bool strictMode); private: void record8(int); @@ -331,12 +335,15 @@ ALWAYS_INLINE const Identifier* Lexer<T>::makeLCharIdentifier(const UChar* chara } template <typename T> -ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSTokenData* tokenData, JSTokenLocation* tokenLocation, unsigned lexerFlags, bool strictMode) +ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSToken* tokenRecord, unsigned lexerFlags, bool strictMode) { + JSTokenData* tokenData = &tokenRecord->m_data; + JSTokenLocation* tokenLocation = &tokenRecord->m_location; ASSERT((lexerFlags & LexerFlagsIgnoreReservedWords)); const T* start = m_code; const T* ptr = start; const T* end = m_codeEnd; + JSTextPosition startPosition = currentPosition(); if (ptr >= end) { ASSERT(ptr == end); goto slowCase; @@ -371,11 +378,13 @@ ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSTokenData* tokenData, tokenLocation->startOffset = offsetFromSourcePtr(start); tokenLocation->endOffset = currentOffset(); ASSERT(tokenLocation->startOffset >= tokenLocation->lineStartOffset); + tokenRecord->m_startPosition = startPosition; + tokenRecord->m_endPosition = currentPosition(); m_lastToken = IDENT; return IDENT; slowCase: - return lex(tokenData, tokenLocation, lexerFlags, strictMode); + return lex(tokenRecord, lexerFlags, strictMode); } } // namespace JSC diff --git a/Source/JavaScriptCore/parser/NodeConstructors.h b/Source/JavaScriptCore/parser/NodeConstructors.h index 47f6eea09..b31c01432 100644 --- a/Source/JavaScriptCore/parser/NodeConstructors.h +++ b/Source/JavaScriptCore/parser/NodeConstructors.h @@ -43,9 +43,7 @@ namespace JSC { } inline Node::Node(const JSTokenLocation& location) - : m_lineNumber(location.line) - , m_startOffset(location.startOffset) - , m_lineStartOffset(location.lineStartOffset) + : m_position(location.line, location.startOffset, location.lineStartOffset) { ASSERT(location.startOffset >= location.lineStartOffset); } @@ -102,14 +100,12 @@ namespace JSC { { } -inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifier& ident, unsigned startOffset, unsigned divotLine, unsigned divotLineStart) +inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifier& ident, const JSTextPosition& start) : ExpressionNode(location) , m_ident(ident) - , m_startOffset(startOffset) - , m_divotLine(divotLine) - , m_divotLineStart(divotLineStart) + , m_start(start) { - ASSERT(m_startOffset >= m_divotLineStart); + ASSERT(m_start.offset >= m_start.lineStartOffset); } inline ElementNode::ElementNode(int elision, ExpressionNode* node) @@ -246,81 +242,81 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie { } - inline EvalFunctionCallNode::EvalFunctionCallNode(const JSTokenLocation& location, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline EvalFunctionCallNode::EvalFunctionCallNode(const JSTokenLocation& location, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableExpressionData(divot, divotStart, divotEnd) , m_args(args) { - ASSERT(divot >= divotLineStart); } - inline FunctionCallValueNode::FunctionCallValueNode(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline FunctionCallValueNode::FunctionCallValueNode(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableExpressionData(divot, divotStart, divotEnd) , m_expr(expr) , m_args(args) { + ASSERT(divot.offset >= divotStart.offset); } - inline FunctionCallResolveNode::FunctionCallResolveNode(const JSTokenLocation& location, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline FunctionCallResolveNode::FunctionCallResolveNode(const JSTokenLocation& location, const Identifier& ident, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableExpressionData(divot, divotStart, divotEnd) , m_ident(ident) , m_args(args) { } - inline FunctionCallBracketNode::FunctionCallBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline FunctionCallBracketNode::FunctionCallBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableSubExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableSubExpressionData(divot, divotStart, divotEnd) , m_base(base) , m_subscript(subscript) , m_args(args) { } - inline FunctionCallDotNode::FunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline FunctionCallDotNode::FunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableSubExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableSubExpressionData(divot, divotStart, divotEnd) , m_base(base) , m_ident(ident) , m_args(args) { } - inline CallFunctionCallDotNode::CallFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) - : FunctionCallDotNode(location, base, ident, args, divot, startOffset, endOffset, divotLine, divotLineStart) + inline CallFunctionCallDotNode::CallFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) + : FunctionCallDotNode(location, base, ident, args, divot, divotStart, divotEnd) { } - inline ApplyFunctionCallDotNode::ApplyFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) - : FunctionCallDotNode(location, base, ident, args, divot, startOffset, endOffset, divotLine, divotLineStart) + inline ApplyFunctionCallDotNode::ApplyFunctionCallDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) + : FunctionCallDotNode(location, base, ident, args, divot, divotStart, divotEnd) { } - inline PostfixNode::PostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) - : PrefixNode(location, expr, oper, divot, startOffset, endOffset, divotLine, divotLineStart) + inline PostfixNode::PostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator oper, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) + : PrefixNode(location, expr, oper, divot, divotStart, divotEnd) { } - inline DeleteResolveNode::DeleteResolveNode(const JSTokenLocation& location, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline DeleteResolveNode::DeleteResolveNode(const JSTokenLocation& location, const Identifier& ident, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableExpressionData(divot, divotStart, divotEnd) , m_ident(ident) { } - inline DeleteBracketNode::DeleteBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline DeleteBracketNode::DeleteBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableExpressionData(divot, divotStart, divotEnd) , m_base(base) , m_subscript(subscript) { } - inline DeleteDotNode::DeleteDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline DeleteDotNode::DeleteDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableExpressionData(divot, divotStart, divotEnd) , m_base(base) , m_ident(ident) { @@ -350,9 +346,9 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie { } - inline PrefixNode::PrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline PrefixNode::PrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator oper, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowablePrefixedSubExpressionData(divot, divotStart, divotEnd) , m_expr(expr) , m_operator(oper) { @@ -536,16 +532,14 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie { } - inline ReadModifyResolveNode::ReadModifyResolveNode(const JSTokenLocation& location, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline ReadModifyResolveNode::ReadModifyResolveNode(const JSTokenLocation& location, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableExpressionData(divot, divotStart, divotEnd) , m_ident(ident) , m_right(right) , m_operator(oper) , m_rightHasAssignments(rightHasAssignments) { - ASSERT(divot >= divotLineStart); - ASSERT(divot - startOffset >= divotLineStart); } inline AssignResolveNode::AssignResolveNode(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* right) @@ -555,9 +549,10 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie { } - inline ReadModifyBracketNode::ReadModifyBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + + inline ReadModifyBracketNode::ReadModifyBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableSubExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableSubExpressionData(divot, divotStart, divotEnd) , m_base(base) , m_subscript(subscript) , m_right(right) @@ -567,9 +562,9 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie { } - inline AssignBracketNode::AssignBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline AssignBracketNode::AssignBracketNode(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableExpressionData(divot, divotStart, divotEnd) , m_base(base) , m_subscript(subscript) , m_right(right) @@ -578,9 +573,9 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie { } - inline AssignDotNode::AssignDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline AssignDotNode::AssignDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableExpressionData(divot, divotStart, divotEnd) , m_base(base) , m_ident(ident) , m_right(right) @@ -588,9 +583,9 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie { } - inline ReadModifyDotNode::ReadModifyDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline ReadModifyDotNode::ReadModifyDotNode(const JSTokenLocation& location, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableSubExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableSubExpressionData(divot, divotStart, divotEnd) , m_base(base) , m_ident(ident) , m_right(right) @@ -599,9 +594,9 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie { } - inline AssignErrorNode::AssignErrorNode(const JSTokenLocation& location, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + inline AssignErrorNode::AssignErrorNode(const JSTokenLocation& location, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : ExpressionNode(location) - , ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + , ThrowableExpressionData(divot, divotStart, divotEnd) { } @@ -706,13 +701,11 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie { } - inline WithNode::WithNode(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, uint32_t divot, unsigned divotLine, unsigned divotLineStart, uint32_t expressionLength) + inline WithNode::WithNode(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, const JSTextPosition& divot, uint32_t expressionLength) : StatementNode(location) , m_expr(expr) , m_statement(statement) , m_divot(divot) - , m_divotLine(divotLine) - , m_divotLineStart(divotLineStart) , m_expressionLength(expressionLength) { } @@ -822,17 +815,17 @@ inline ResolveNode::ResolveNode(const JSTokenLocation& location, const Identifie { } - inline ForInNode::ForInNode(VM* vm, const JSTokenLocation& location, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, unsigned divot, int startOffset, int endOffset, unsigned divotLine, unsigned divotLineStart) + inline ForInNode::ForInNode(VM* vm, const JSTokenLocation& location, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) : StatementNode(location) , m_init(0) - , m_lexpr(new (vm) ResolveNode(location, ident, divot - startOffset, divotLine, divotLineStart)) + , m_lexpr(new (vm) ResolveNode(location, ident, divotStart)) , m_expr(expr) , m_statement(statement) { if (in) { AssignResolveNode* node = new (vm) AssignResolveNode(location, ident, in); - ASSERT(divot >= divotLineStart); - node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot, divotLine, divotLineStart); + ASSERT(divot.offset >= divot.lineStartOffset); + node->setExceptionSourceCode(divot, divotStart, divotEnd); m_init = node; } // for( var foo = bar in baz ) diff --git a/Source/JavaScriptCore/parser/Nodes.cpp b/Source/JavaScriptCore/parser/Nodes.cpp index 97ffaa163..36ded3863 100644 --- a/Source/JavaScriptCore/parser/Nodes.cpp +++ b/Source/JavaScriptCore/parser/Nodes.cpp @@ -54,11 +54,9 @@ namespace JSC { void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset) { - m_lineNumber = firstLine; m_lastLine = lastLine; - m_startOffset = startOffset; - m_lineStartOffset = lineStartOffset; - ASSERT(m_startOffset >= m_lineStartOffset); + m_position = JSTextPosition(firstLine, startOffset, lineStartOffset); + ASSERT(m_position.offset >= m_position.lineStartOffset); } // ------------------------------ SourceElements -------------------------------- diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h index 2eeaae9d9..e9b88a1a0 100644 --- a/Source/JavaScriptCore/parser/Nodes.h +++ b/Source/JavaScriptCore/parser/Nodes.h @@ -129,14 +129,13 @@ namespace JSC { public: virtual ~Node() { } - int lineNo() const { return m_lineNumber; } - int startOffset() const { return m_startOffset; } - int lineStartOffset() const { return m_lineStartOffset; } + int lineNo() const { return m_position.line; } + int startOffset() const { return m_position.offset; } + int lineStartOffset() const { return m_position.lineStartOffset; } + const JSTextPosition& position() const { return m_position; } protected: - int m_lineNumber; - int m_startOffset; - int m_lineStartOffset; + JSTextPosition m_position; }; class ExpressionNode : public Node { @@ -254,49 +253,43 @@ namespace JSC { class ThrowableExpressionData { public: ThrowableExpressionData() - : m_divot(static_cast<uint32_t>(-1)) - , m_divotStartOffset(static_cast<uint16_t>(-1)) - , m_divotEndOffset(static_cast<uint16_t>(-1)) - , m_divotLine(static_cast<uint32_t>(-1)) - , m_divotLineStart(static_cast<uint32_t>(-1)) + : m_divot(-1, -1, -1) + , m_divotStart(-1, -1, -1) + , m_divotEnd(-1, -1, -1) { } - ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + ThrowableExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end) : m_divot(divot) - , m_divotStartOffset(startOffset) - , m_divotEndOffset(endOffset) - , m_divotLine(divotLine) - , m_divotLineStart(divotLineStart) + , m_divotStart(start) + , m_divotEnd(end) { - ASSERT(m_divot >= m_divotLineStart); + ASSERT(m_divot.offset >= m_divot.lineStartOffset); + ASSERT(m_divotStart.offset >= m_divotStart.lineStartOffset); + ASSERT(m_divotEnd.offset >= m_divotEnd.lineStartOffset); } - - void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) + + void setExceptionSourceCode(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) { - ASSERT(divot >= divotLineStart); + ASSERT(divot.offset >= divot.lineStartOffset); + ASSERT(divotStart.offset >= divotStart.lineStartOffset); + ASSERT(divotEnd.offset >= divotEnd.lineStartOffset); m_divot = divot; - m_divotStartOffset = startOffset; - m_divotEndOffset = endOffset; - m_divotLine = divotLine; - m_divotLineStart = divotLineStart; + m_divotStart = divotStart; + m_divotEnd = divotEnd; } - uint32_t divot() const { return m_divot; } - uint16_t divotStartOffset() const { return m_divotStartOffset; } - uint16_t divotEndOffset() const { return m_divotEndOffset; } - uint32_t divotLine() const { return m_divotLine; } - uint32_t divotLineStart() const { return m_divotLineStart; } + const JSTextPosition& divot() const { return m_divot; } + const JSTextPosition& divotStart() const { return m_divotStart; } + const JSTextPosition& divotEnd() const { return m_divotEnd; } protected: RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message); private: - uint32_t m_divot; - uint16_t m_divotStartOffset; - uint16_t m_divotEndOffset; - uint32_t m_divotLine; - uint32_t m_divotLineStart; + JSTextPosition m_divot; + JSTextPosition m_divotStart; + JSTextPosition m_divotEnd; }; class ThrowableSubExpressionData : public ThrowableExpressionData { @@ -309,8 +302,8 @@ namespace JSC { { } - ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) - : ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + ThrowableSubExpressionData(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) + : ThrowableExpressionData(divot, divotStart, divotEnd) , m_subexpressionDivotOffset(0) , m_subexpressionEndOffset(0) , m_subexpressionLineOffset(0) @@ -318,28 +311,34 @@ namespace JSC { { } - void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset, uint32_t subexpressionLine, uint32_t subexpressionLineStart) + void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset) { - ASSERT(subexpressionDivot <= divot()); + ASSERT(subexpressionDivot.offset <= divot().offset); // Overflow means we can't do this safely, so just point at the primary divot, // divotLine, or divotLineStart. - if ((divot() - subexpressionDivot) & ~0xFFFF) + if ((divot() - subexpressionDivot.offset) & ~0xFFFF) return; - if ((divotLine() - subexpressionLine) & ~0xFFFF) + if ((divot().line - subexpressionDivot.line) & ~0xFFFF) return; - if ((divotLineStart() - subexpressionLineStart) & ~0xFFFF) + if ((divot().lineStartOffset - subexpressionDivot.lineStartOffset) & ~0xFFFF) return; - m_subexpressionDivotOffset = divot() - subexpressionDivot; - m_subexpressionEndOffset = subexpressionOffset; - m_subexpressionLineOffset = divotLine() - subexpressionLine; - m_subexpressionLineStartOffset = divotLineStart() - subexpressionLineStart; + if ((divotEnd() - subexpressionOffset) & ~0xFFFF) + return; + m_subexpressionDivotOffset = divot() - subexpressionDivot.offset; + m_subexpressionEndOffset = divotEnd() - subexpressionOffset; + m_subexpressionLineOffset = divot().line - subexpressionDivot.line; + m_subexpressionLineStartOffset = divot().lineStartOffset - subexpressionDivot.lineStartOffset; } - unsigned subexpressionDivot() { return divot() - m_subexpressionDivotOffset; } - unsigned subexpressionStartOffset() { return divotStartOffset() - m_subexpressionDivotOffset; } - unsigned subexpressionEndOffset() { return m_subexpressionEndOffset; } - unsigned subexpressionLine() { return divotLine() - m_subexpressionLineOffset; } - unsigned subexpressionLineStart() { return divotLineStart() - m_subexpressionLineStartOffset; } + JSTextPosition subexpressionDivot() + { + int newLine = divot().line - m_subexpressionLineOffset; + int newOffset = divot().offset - m_subexpressionDivotOffset; + int newLineStartOffset = divot().lineStartOffset - m_subexpressionLineStartOffset; + return JSTextPosition(newLine, newOffset, newLineStartOffset); + } + JSTextPosition subexpressionStart() { return divotStart(); } + JSTextPosition subexpressionEnd() { return divotEnd() - static_cast<int>(m_subexpressionEndOffset); } protected: uint16_t m_subexpressionDivotOffset; @@ -358,8 +357,8 @@ namespace JSC { { } - ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart) - : ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart) + ThrowablePrefixedSubExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end) + : ThrowableExpressionData(divot, start, end) , m_subexpressionDivotOffset(0) , m_subexpressionStartOffset(0) , m_subexpressionLineOffset(0) @@ -367,28 +366,34 @@ namespace JSC { { } - void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset, uint32_t subexpressionLine, uint32_t subexpressionLineStart) + void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset) { - ASSERT(subexpressionDivot >= divot()); + ASSERT(subexpressionDivot.offset >= divot().offset); // Overflow means we can't do this safely, so just point at the primary divot, // divotLine, or divotLineStart. - if ((subexpressionDivot - divot()) & ~0xFFFF) + if ((subexpressionDivot.offset - divot()) & ~0xFFFF) + return; + if ((subexpressionDivot.line - divot().line) & ~0xFFFF) return; - if ((subexpressionLine - divotLine()) & ~0xFFFF) + if ((subexpressionDivot.lineStartOffset - divot().lineStartOffset) & ~0xFFFF) return; - if ((subexpressionLineStart - divotLineStart()) & ~0xFFFF) + if ((subexpressionOffset - divotStart()) & ~0xFFFF) return; - m_subexpressionDivotOffset = subexpressionDivot - divot(); - m_subexpressionStartOffset = subexpressionOffset; - m_subexpressionLineOffset = subexpressionLine - divotLine(); - m_subexpressionLineStartOffset = subexpressionLineStart - divotLineStart(); + m_subexpressionDivotOffset = subexpressionDivot.offset - divot(); + m_subexpressionStartOffset = subexpressionOffset - divotStart(); + m_subexpressionLineOffset = subexpressionDivot.line - divot().line; + m_subexpressionLineStartOffset = subexpressionDivot.lineStartOffset - divot().lineStartOffset; } - unsigned subexpressionDivot() { return divot() + m_subexpressionDivotOffset; } - unsigned subexpressionStartOffset() { return m_subexpressionStartOffset; } - unsigned subexpressionEndOffset() { return divotEndOffset() + m_subexpressionDivotOffset; } - unsigned subexpressionLine() { return divotLine() + m_subexpressionLineOffset; } - unsigned subexpressionLineStart() { return divotLineStart() + m_subexpressionLineStartOffset; } + JSTextPosition subexpressionDivot() + { + int newLine = divot().line + m_subexpressionLineOffset; + int newOffset = divot().offset + m_subexpressionDivotOffset; + int newLineStartOffset = divot().lineStartOffset + m_subexpressionLineStartOffset; + return JSTextPosition(newLine, newOffset, newLineStartOffset); + } + JSTextPosition subexpressionStart() { return divotStart() + static_cast<int>(m_subexpressionStartOffset); } + JSTextPosition subexpressionEnd() { return divotEnd(); } protected: uint16_t m_subexpressionDivotOffset; @@ -418,7 +423,7 @@ namespace JSC { class ResolveNode : public ExpressionNode { public: - ResolveNode(const JSTokenLocation&, const Identifier&, unsigned startOffset, unsigned divotLine, unsigned divotLineStart); + ResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& start); const Identifier& identifier() const { return m_ident; } @@ -430,9 +435,7 @@ namespace JSC { virtual bool isResolveNode() const { return true; } const Identifier& m_ident; - uint32_t m_startOffset; - uint32_t m_divotLine; - uint32_t m_divotLineStart; + JSTextPosition m_start; }; class ElementNode : public ParserArenaFreeable { @@ -579,7 +582,7 @@ namespace JSC { class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData { public: - EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -589,7 +592,7 @@ namespace JSC { class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData { public: - FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -600,7 +603,7 @@ namespace JSC { class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData { public: - FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -611,7 +614,7 @@ namespace JSC { class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData { public: - FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -623,7 +626,7 @@ namespace JSC { class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData { public: - FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -636,7 +639,7 @@ namespace JSC { class CallFunctionCallDotNode : public FunctionCallDotNode { public: - CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -644,7 +647,7 @@ namespace JSC { class ApplyFunctionCallDotNode : public FunctionCallDotNode { public: - ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -652,7 +655,7 @@ namespace JSC { class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData { public: - DeleteResolveNode(const JSTokenLocation&, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + DeleteResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -662,7 +665,7 @@ namespace JSC { class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData { public: - DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -673,7 +676,7 @@ namespace JSC { class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData { public: - DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -726,7 +729,7 @@ namespace JSC { class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData { public: - PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); protected: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -740,7 +743,7 @@ namespace JSC { class PostfixNode : public PrefixNode { public: - PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -983,7 +986,7 @@ namespace JSC { class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData { public: - ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart); + ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -1007,7 +1010,7 @@ namespace JSC { class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData { public: - ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -1022,7 +1025,7 @@ namespace JSC { class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData { public: - AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -1036,7 +1039,7 @@ namespace JSC { class AssignDotNode : public ExpressionNode, public ThrowableExpressionData { public: - AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -1049,7 +1052,7 @@ namespace JSC { class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData { public: - ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -1063,7 +1066,7 @@ namespace JSC { class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData { public: - AssignErrorNode(const JSTokenLocation&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart); + AssignErrorNode(const JSTokenLocation&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -1239,7 +1242,7 @@ namespace JSC { class ForInNode : public StatementNode, public ThrowableExpressionData { public: ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*); - ForInNode(VM*, const JSTokenLocation&, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, unsigned divot, int startOffset, int endOffset, unsigned divotLine, unsigned divotLineStart); + ForInNode(VM*, const JSTokenLocation&, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); private: virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -1292,16 +1295,14 @@ namespace JSC { class WithNode : public StatementNode { public: - WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, uint32_t divot, unsigned divotLine, unsigned divotLineStart, uint32_t expressionLength); + WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, const JSTextPosition& divot, uint32_t expressionLength); private: virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0); ExpressionNode* m_expr; StatementNode* m_statement; - uint32_t m_divot; - uint32_t m_divotLine; - uint32_t m_divotLineStart; + JSTextPosition m_divot; uint32_t m_expressionLength; }; diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp index aefba302f..07bd59576 100644 --- a/Source/JavaScriptCore/parser/Parser.cpp +++ b/Source/JavaScriptCore/parser/Parser.cpp @@ -69,8 +69,6 @@ Parser<LexerType>::Parser(VM* vm, const SourceCode& source, FunctionParameters* , m_stack(*vm, wtfThreadData().stack()) , m_hasStackOverflow(false) , m_allowsIn(true) - , m_lastLine(0) - , m_lastTokenEnd(0) , m_assignmentCount(0) , m_nonLHSCount(0) , m_syntaxAlreadyValidated(source.provider()->isValid()) @@ -131,21 +129,20 @@ String Parser<LexerType>::parseInner() features |= ShadowsArgumentsFeature; didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features, - m_lastLine, context.numConstants(), capturedVariables); + context.numConstants(), capturedVariables); return parseError; } template <typename LexerType> void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack, - ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants, IdentifierSet& capturedVars) + ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int numConstants, IdentifierSet& capturedVars) { m_sourceElements = sourceElements; m_varDeclarations = varStack; m_funcDeclarations = funcStack; m_capturedVariables.swap(capturedVars); m_features = features; - m_lastLine = lastLine; m_numConstants = numConstants; } @@ -203,7 +200,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVarDeclaratio int scratch; const Identifier* scratch1 = 0; TreeExpression scratch2 = 0; - int scratch3 = 0; + JSTextPosition scratch3; TreeExpression varDecls = parseVarDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3); failIfTrue(hasError()); failIfFalse(autoSemiColon()); @@ -269,7 +266,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWhileStatemen } template <typename LexerType> -template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarationList(TreeBuilder& context, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, int& identStart, int& initStart, int& initEnd) +template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarationList(TreeBuilder& context, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd) { TreeExpression varDecls = 0; do { @@ -278,7 +275,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarati next(); matchOrFail(IDENT); - int varStart = tokenStart(); + JSTextPosition varStart = tokenStartPosition(); identStart = varStart; const Identifier* name = m_token.m_data.ident; lastIdent = name; @@ -287,17 +284,15 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarati failIfFalseIfStrictWithNameAndMessage(declareVariable(name), "Cannot declare a variable named", name->impl(), "in strict mode."); context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0); if (hasInitializer) { - int varDivot = tokenStart() + 1; - unsigned varLine = tokenLine(); - unsigned varLineStart = tokenLineStart(); - initStart = tokenStart(); + JSTextPosition varDivot = tokenStartPosition() + 1; + initStart = tokenStartPosition(); next(TreeBuilder::DontBuildStrings); // consume '=' TreeExpression initializer = parseAssignmentExpression(context); - initEnd = lastTokenEnd(); + initEnd = lastTokenEndPosition(); lastInitializer = initializer; failIfFalse(initializer); - TreeExpression node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEnd(), varLine, varLineStart); + TreeExpression node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEndPosition()); if (!varDecls) varDecls = node; else @@ -345,10 +340,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement( consumeOrFail(OPENPAREN); int nonLHSCount = m_nonLHSCount; int declarations = 0; - int declsStart = 0; - int declsEnd = 0; - unsigned declsLine = 0; - unsigned declsLineStart = 0; + JSTextPosition declsStart; + JSTextPosition declsEnd; TreeExpression decls = 0; if (match(VAR)) { /* @@ -359,8 +352,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement( const Identifier* forInTarget = 0; TreeExpression forInInitializer = 0; m_allowsIn = false; - int initStart = 0; - int initEnd = 0; + JSTextPosition initStart; + JSTextPosition initEnd; decls = parseVarDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd); m_allowsIn = true; failIfTrue(hasError()); @@ -372,14 +365,12 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement( failIfFalse(declarations == 1); // Handle for-in with var declaration - int inLocation = tokenStart(); - unsigned inLine = tokenLine(); - unsigned inLineStart = tokenLineStart(); + JSTextPosition inLocation = tokenStartPosition(); consumeOrFail(INTOKEN); TreeExpression expr = parseExpression(context); failIfFalse(expr); - int exprEnd = lastTokenEnd(); + JSTextPosition exprEnd = lastTokenEndPosition(); int endLine = tokenLine(); consumeOrFail(CLOSEPAREN); @@ -390,16 +381,14 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement( endLoop(); failIfFalse(statement); - return context.createForInLoop(location, forInTarget, forInInitializer, expr, statement, declsStart, inLocation, exprEnd, initStart, initEnd, startLine, endLine, inLine, inLineStart); + return context.createForInLoop(location, forInTarget, forInInitializer, expr, statement, declsStart, inLocation, exprEnd, initStart, initEnd, startLine, endLine); } if (!match(SEMICOLON)) { m_allowsIn = false; - declsStart = tokenStart(); + declsStart = tokenStartPosition(); decls = parseExpression(context); - declsEnd = lastTokenEnd(); - declsLine = lastTokenLine(); - declsLineStart = lastTokenLineStart(); + declsEnd = lastTokenEndPosition(); m_allowsIn = true; failIfFalse(decls); } @@ -436,7 +425,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement( consumeOrFail(INTOKEN); TreeExpression expr = parseExpression(context); failIfFalse(expr); - int exprEnd = lastTokenEnd(); + JSTextPosition exprEnd = lastTokenEndPosition(); int endLine = tokenLine(); consumeOrFail(CLOSEPAREN); const Identifier* unused = 0; @@ -445,7 +434,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement( endLoop(); failIfFalse(statement); - return context.createForInLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine, declsLine, declsLineStart); + return context.createForInLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine); } template <typename LexerType> @@ -453,26 +442,21 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBreakStatemen { ASSERT(match(BREAK)); JSTokenLocation location(tokenLocation()); - int startCol = tokenStart(); - int endCol = tokenEnd(); - int startLine = tokenLine(); - int endLine = tokenLine(); - unsigned endLineStart = tokenLineStart(); + JSTextPosition start = tokenStartPosition(); + JSTextPosition end = tokenEndPosition(); next(); if (autoSemiColon()) { failIfFalseWithMessage(breakIsValid(), "'break' is only valid inside a switch or loop statement"); - return context.createBreakStatement(location, startCol, endCol, startLine, endLine, endLineStart); + return context.createBreakStatement(location, start, end); } matchOrFail(IDENT); const Identifier* ident = m_token.m_data.ident; failIfFalseWithNameAndMessage(getLabel(ident), "Label", ident->impl(), "is not defined"); - endCol = tokenEnd(); - endLine = tokenLine(); - endLineStart = tokenLineStart(); + end = tokenEndPosition(); next(); failIfFalse(autoSemiColon()); - return context.createBreakStatement(location, ident, startCol, endCol, startLine, endLine, endLineStart); + return context.createBreakStatement(location, ident, start, end); } template <typename LexerType> @@ -480,28 +464,23 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseContinueState { ASSERT(match(CONTINUE)); JSTokenLocation location(tokenLocation()); - int startCol = tokenStart(); - int endCol = tokenEnd(); - int startLine = tokenLine(); - int endLine = tokenLine(); - unsigned endLineStart = tokenLineStart(); + JSTextPosition start = tokenStartPosition(); + JSTextPosition end = tokenEndPosition(); next(); if (autoSemiColon()) { failIfFalseWithMessage(continueIsValid(), "'continue' is only valid inside a loop statement"); - return context.createContinueStatement(location, startCol, endCol, startLine, endLine, endLineStart); + return context.createContinueStatement(location, start, end); } matchOrFail(IDENT); const Identifier* ident = m_token.m_data.ident; ScopeLabelInfo* label = getLabel(ident); failIfFalseWithNameAndMessage(label, "Label", ident->impl(), "is not defined"); failIfFalseWithMessage(label->m_isLoop, "'continue' is only valid inside a loop statement"); - endCol = tokenEnd(); - endLine = tokenLine(); - endLineStart = tokenLineStart(); + end = tokenEndPosition(); next(); failIfFalse(autoSemiColon()); - return context.createContinueStatement(location, ident, startCol, endCol, startLine, endLine, endLineStart); + return context.createContinueStatement(location, ident, start, end); } template <typename LexerType> @@ -510,29 +489,24 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseReturnStateme ASSERT(match(RETURN)); JSTokenLocation location(tokenLocation()); failIfFalse(currentScope()->isFunction()); - int startLine = tokenLine(); - int endLine = startLine; - int start = tokenStart(); - int end = tokenEnd(); - unsigned divotLine = tokenLine(); - unsigned divotLineStart = tokenLineStart(); + JSTextPosition start = tokenStartPosition(); + JSTextPosition end = tokenEndPosition(); next(); // We do the auto semicolon check before attempting to parse an expression // as we need to ensure the a line break after the return correctly terminates // the statement if (match(SEMICOLON)) - endLine = tokenLine(); + end = tokenEndPosition(); + if (autoSemiColon()) - return context.createReturnStatement(location, 0, start, end, startLine, endLine, divotLine, divotLineStart); + return context.createReturnStatement(location, 0, start, end); TreeExpression expr = parseExpression(context); failIfFalse(expr); - end = lastTokenEnd(); - divotLine = lastTokenLine(); - divotLineStart = lastTokenLineStart(); + end = lastTokenEndPosition(); if (match(SEMICOLON)) - endLine = tokenLine(); + end = tokenEndPosition(); failIfFalse(autoSemiColon()); - return context.createReturnStatement(location, expr, start, end, startLine, endLine, divotLine, divotLineStart); + return context.createReturnStatement(location, expr, start, end); } template <typename LexerType> @@ -540,21 +514,17 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseThrowStatemen { ASSERT(match(THROW)); JSTokenLocation location(tokenLocation()); - int eStart = tokenStart(); - int startLine = tokenLine(); + JSTextPosition start = tokenStartPosition(); next(); failIfTrue(autoSemiColon()); TreeExpression expr = parseExpression(context); failIfFalse(expr); - int eEnd = lastTokenEnd(); - unsigned divotLine = lastTokenLine(); - unsigned divotLineStart = lastTokenLineStart(); - int endLine = tokenLine(); + JSTextPosition end = lastTokenEndPosition(); failIfFalse(autoSemiColon()); - return context.createThrowStatement(location, expr, eStart, eEnd, startLine, endLine, divotLine, divotLineStart); + return context.createThrowStatement(location, expr, start, end); } template <typename LexerType> @@ -570,16 +540,14 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement int start = tokenStart(); TreeExpression expr = parseExpression(context); failIfFalse(expr); - int end = lastTokenEnd(); - unsigned divotLine = lastTokenLine(); - unsigned divotLineStart = lastTokenLineStart(); + JSTextPosition end = lastTokenEndPosition(); int endLine = tokenLine(); consumeOrFail(CLOSEPAREN); const Identifier* unused = 0; TreeStatement statement = parseStatement(context, unused); failIfFalse(statement); - return context.createWithStatement(location, expr, statement, start, end, startLine, endLine, divotLine, divotLineStart); + return context.createWithStatement(location, expr, statement, start, end, startLine, endLine); } template <typename LexerType> @@ -666,7 +634,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement( tryBlock = parseBlockStatement(context); failIfFalse(tryBlock); - int lastLine = m_lastLine; + int lastLine = m_lastTokenEndPosition.line; if (match(CATCH)) { currentScope()->setNeedsFullActivation(); @@ -718,13 +686,13 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBlockStatemen next(); if (match(CLOSEBRACE)) { next(); - return context.createBlockStatement(location, 0, start, m_lastLine); + return context.createBlockStatement(location, 0, start, m_lastTokenEndPosition.line); } TreeSourceElements subtree = parseSourceElements<DontCheckForStrictMode>(context); failIfFalse(subtree); matchOrFail(CLOSEBRACE); next(); - return context.createBlockStatement(location, subtree, start, m_lastLine); + return context.createBlockStatement(location, subtree, start, m_lastTokenEndPosition.line); } template <typename LexerType> @@ -937,24 +905,20 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn))); failIfFalse(name); failIfFalseIfStrict(declareVariable(name)); - return context.createFuncDeclStatement(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastLine, bodyStartColumn); + return context.createFuncDeclStatement(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn); } struct LabelInfo { - LabelInfo(const Identifier* ident, unsigned start, unsigned end, unsigned divotLine, unsigned divotLineStart) + LabelInfo(const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end) : m_ident(ident) , m_start(start) , m_end(end) - , m_divotLine(divotLine) - , m_divotLineStart(divotLineStart) { } const Identifier* m_ident; - unsigned m_start; - unsigned m_end; - unsigned m_divotLine; - unsigned m_divotLineStart; + JSTextPosition m_start; + JSTextPosition m_end; }; template <typename LexerType> @@ -967,8 +931,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL Vector<LabelInfo> labels; JSTokenLocation location; do { - int start = tokenStart(); - int startingLine = tokenLine(); + JSTextPosition start = tokenStartPosition(); location = tokenLocation(); if (!nextTokenIsColon()) { // If we hit this path we're making a expression statement, which @@ -977,12 +940,10 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL TreeExpression expression = parseExpression(context); failIfFalse(expression); failIfFalse(autoSemiColon()); - return context.createExprStatement(location, expression, startingLine, m_lastLine); + return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line); } const Identifier* ident = m_token.m_data.ident; - int end = tokenEnd(); - unsigned divotLine = tokenLine(); - unsigned divotLineStart = tokenLineStart(); + JSTextPosition end = tokenEndPosition(); next(); consumeOrFail(COLON); if (!m_syntaxAlreadyValidated) { @@ -991,7 +952,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL for (size_t i = 0; i < labels.size(); i++) failIfTrue(ident->impl() == labels[i].m_ident->impl()); failIfTrue(getLabel(ident)); - labels.append(LabelInfo(ident, start, end, divotLine, divotLineStart)); + labels.append(LabelInfo(ident, start, end)); } } while (match(IDENT)); bool isLoop = false; @@ -1018,7 +979,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL failIfFalse(statement); for (size_t i = 0; i < labels.size(); i++) { const LabelInfo& info = labels[labels.size() - i - 1]; - statement = context.createLabelStatement(location, info.m_ident, statement, info.m_start, info.m_end, info.m_divotLine, info.m_divotLineStart); + statement = context.createLabelStatement(location, info.m_ident, statement, info.m_start, info.m_end); } return statement; } @@ -1026,12 +987,12 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL template <typename LexerType> template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionStatement(TreeBuilder& context) { - int startLine = tokenLine(); + JSTextPosition start = tokenStartPosition(); JSTokenLocation location(tokenLocation()); TreeExpression expression = parseExpression(context); failIfFalse(expression); failIfFalse(autoSemiColon()); - return context.createExprStatement(location, expression, startLine, m_lastLine); + return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line); } template <typename LexerType> @@ -1147,9 +1108,7 @@ template <typename LexerType> template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpression(TreeBuilder& context) { failIfStackOverflow(); - int start = tokenStart(); - unsigned line = tokenLine(); - unsigned lineStart = tokenLineStart(); + JSTextPosition start = tokenStartPosition(); JSTokenLocation location(tokenLocation()); int initialAssignmentCount = m_assignmentCount; int initialNonLHSCount = m_nonLHSCount; @@ -1180,10 +1139,8 @@ template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen } m_nonTrivialExpressionCount++; hadAssignment = true; - context.assignmentStackAppend(assignmentStack, lhs, start, tokenStart(), line, lineStart, m_assignmentCount, op); - start = tokenStart(); - line = tokenLine(); - lineStart = tokenLineStart(); + context.assignmentStackAppend(assignmentStack, lhs, start, tokenStartPosition(), m_assignmentCount, op); + start = tokenStartPosition(); m_assignmentCount++; next(TreeBuilder::DontBuildStrings); if (strictMode() && m_lastIdentifier && context.isResolve(lhs)) { @@ -1205,7 +1162,7 @@ end: return lhs; while (assignmentStack) - lhs = context.createAssignment(location, assignmentStack, lhs, initialAssignmentCount, m_assignmentCount, lastTokenEnd()); + lhs = context.createAssignment(location, assignmentStack, lhs, initialAssignmentCount, m_assignmentCount, lastTokenEndPosition()); return lhs; } @@ -1251,12 +1208,12 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseBinaryExpres typename TreeBuilder::BinaryExprContext binaryExprContext(context); JSTokenLocation location(tokenLocation()); while (true) { - int exprStart = tokenStart(); + JSTextPosition exprStart = tokenStartPosition(); int initialAssignments = m_assignmentCount; TreeExpression current = parseUnaryExpression(context); failIfFalse(current); - context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEnd(), lastTokenEnd(), lastTokenLine(), lastTokenLineStart(), initialAssignments != m_assignmentCount); + context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEndPosition(), lastTokenEndPosition(), initialAssignments != m_assignmentCount); int precedence = isBinaryOperator(m_token.m_type); if (!precedence) break; @@ -1336,8 +1293,8 @@ template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::pars next(); failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, accessorName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn))); if (stringPropertyName) - return context.template createGetterOrSetterProperty<complete>(location, type, stringPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastLine, bodyStartColumn); - return context.template createGetterOrSetterProperty<complete>(const_cast<VM*>(m_vm), location, type, numericPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastLine, bodyStartColumn); + return context.template createGetterOrSetterProperty<complete>(location, type, stringPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn); + return context.template createGetterOrSetterProperty<complete>(const_cast<VM*>(m_vm), location, type, numericPropertyName, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn); } case NUMBER: { double propertyName = m_token.m_data.doubleValue; @@ -1535,15 +1492,13 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre return context.thisExpr(location); } case IDENT: { - int start = tokenStart(); - int line = tokenLine(); - int lineStart = tokenLineStart(); + JSTextPosition start = tokenStartPosition(); const Identifier* ident = m_token.m_data.ident; JSTokenLocation location(tokenLocation()); next(); currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident); m_lastIdentifier = ident; - return context.createResolve(location, ident, start, line, lineStart); + return context.createResolve(location, ident, start); } case STRING: { const Identifier* ident = m_token.m_data.ident; @@ -1582,12 +1537,10 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre else failIfFalse(m_lexer->scanRegExp(pattern, flags)); - int start = tokenStart(); - int line = tokenLine(); - int lineStart = tokenLineStart(); + JSTextPosition start = tokenStartPosition(); JSTokenLocation location(tokenLocation()); next(); - TreeExpression re = context.createRegExp(location, *pattern, *flags, start, line, lineStart); + TreeExpression re = context.createRegExp(location, *pattern, *flags, start); if (!re) { const char* yarrErrorMsg = Yarr::checkSyntax(pattern->string()); failWithMessage(yarrErrorMsg); @@ -1628,10 +1581,7 @@ template <typename LexerType> template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpression(TreeBuilder& context) { TreeExpression base = 0; - int start = tokenStart(); - int expressionStart = start; - int expressionLine = tokenLine(); - int expressionLineStart = tokenLineStart(); + JSTextPosition expressionStart = tokenStartPosition(); int newCount = 0; JSTokenLocation location; while (match(NEW)) { @@ -1650,7 +1600,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres location = tokenLocation(); next(); failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, name, parameters, body, openBraceOffset, closeBraceOffset, bodyStartLine, bodyStartColumn))); - base = context.createFunctionExpr(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastLine, bodyStartColumn); + base = context.createFunctionExpr(location, name, body, parameters, openBraceOffset, closeBraceOffset, bodyStartLine, m_lastTokenEndPosition.line, bodyStartColumn); } else base = parsePrimaryExpression(context); @@ -1660,15 +1610,13 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres switch (m_token.m_type) { case OPENBRACKET: { m_nonTrivialExpressionCount++; - int expressionEnd = lastTokenEnd(); - int expressionLine = lastTokenLine(); - int expressionLineStart = lastTokenLineStart(); + JSTextPosition expressionEnd = lastTokenEndPosition(); next(); int nonLHSCount = m_nonLHSCount; int initialAssignments = m_assignmentCount; TreeExpression property = parseExpression(context); failIfFalse(property); - base = context.createBracketAccess(location, base, property, initialAssignments != m_assignmentCount, expressionStart, expressionEnd, tokenEnd(), expressionLine, expressionLineStart); + base = context.createBracketAccess(location, base, property, initialAssignments != m_assignmentCount, expressionStart, expressionEnd, tokenEndPosition()); consumeOrFail(CLOSEBRACKET); m_nonLHSCount = nonLHSCount; break; @@ -1678,30 +1626,25 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres int nonLHSCount = m_nonLHSCount; if (newCount) { newCount--; - int exprEnd = lastTokenEnd(); - unsigned expressionLine = lastTokenLine(); - unsigned expressionLineStart = lastTokenLineStart(); + JSTextPosition expressionEnd = lastTokenEndPosition(); TreeArguments arguments = parseArguments(context); failIfFalse(arguments); - base = context.createNewExpr(location, base, arguments, start, exprEnd, lastTokenEnd(), expressionLine, expressionLineStart); + base = context.createNewExpr(location, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition()); } else { - int expressionEnd = lastTokenEnd(); - unsigned expressionLine = lastTokenLine(); - int expressionLineStart = lastTokenLineStart(); + JSTextPosition expressionEnd = lastTokenEndPosition(); TreeArguments arguments = parseArguments(context); failIfFalse(arguments); - base = context.makeFunctionCallNode(location, base, arguments, expressionStart, expressionEnd, lastTokenEnd(), expressionLine, expressionLineStart); + base = context.makeFunctionCallNode(location, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition()); } m_nonLHSCount = nonLHSCount; break; } case DOT: { m_nonTrivialExpressionCount++; - int expressionEnd = lastTokenEnd(); - expressionLineStart = lastTokenLineStart(); + JSTextPosition expressionEnd = lastTokenEndPosition(); nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords); matchOrFail(IDENT); - base = context.createDotAccess(location, base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEnd(), expressionLine, expressionLineStart); + base = context.createDotAccess(location, base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEndPosition()); next(); break; } @@ -1711,7 +1654,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres } endMemberExpression: while (newCount--) - base = context.createNewExpr(location, base, start, lastTokenEnd(), expressionLine, expressionLineStart); + base = context.createNewExpr(location, base, expressionStart, lastTokenEndPosition()); return base; } @@ -1744,14 +1687,12 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress } } m_nonLHSCount++; - context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStart(), tokenLine(), tokenLineStart()); + context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStartPosition()); next(); m_nonTrivialExpressionCount++; } - int subExprStart = tokenStart(); - int subExprLine = tokenLine(); - int subExprLineStartPosition = tokenLineStart(); - ASSERT(subExprStart >= subExprLineStartPosition); + JSTextPosition subExprStart = tokenStartPosition(); + ASSERT(subExprStart.offset >= subExprStart.lineStartOffset); JSTokenLocation location(tokenLocation()); TreeExpression expr = parseMemberExpression(context); failIfFalse(expr); @@ -1765,7 +1706,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress case PLUSPLUS: m_nonTrivialExpressionCount++; m_nonLHSCount++; - expr = context.makePostfixNode(location, expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd(), tokenLine(), tokenLineStart()); + expr = context.makePostfixNode(location, expr, OpPlusPlus, subExprStart, lastTokenEndPosition(), tokenEndPosition()); m_assignmentCount++; failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode"); failIfTrueIfStrict(requiresLExpr); @@ -1774,7 +1715,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress case MINUSMINUS: m_nonTrivialExpressionCount++; m_nonLHSCount++; - expr = context.makePostfixNode(location, expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd(), tokenLine(), tokenLineStart()); + expr = context.makePostfixNode(location, expr, OpMinusMinus, subExprStart, lastTokenEndPosition(), tokenEndPosition()); m_assignmentCount++; failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode"); failIfTrueIfStrict(requiresLExpr); @@ -1784,9 +1725,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress break; } - int end = lastTokenEnd(); - int endLine = lastTokenLine(); - int endLineStartPosition = lastTokenLineStart(); + JSTextPosition end = lastTokenEndPosition(); if (!TreeBuilder::CreatesAST && (m_syntaxAlreadyValidated || !strictMode())) return expr; @@ -1809,12 +1748,12 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress break; case PLUSPLUS: case AUTOPLUSPLUS: - expr = context.makePrefixNode(location, expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end, subExprLine, subExprLineStartPosition); + expr = context.makePrefixNode(location, expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end); m_assignmentCount++; break; case MINUSMINUS: case AUTOMINUSMINUS: - expr = context.makePrefixNode(location, expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end, subExprLine, subExprLineStartPosition); + expr = context.makePrefixNode(location, expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end); m_assignmentCount++; break; case TYPEOF: @@ -1825,14 +1764,13 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress break; case DELETETOKEN: failIfTrueIfStrictWithNameAndMessage(context.isResolve(expr), "Cannot delete unqualified property", m_lastIdentifier->impl(), "in strict mode"); - expr = context.makeDeleteNode(location, expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end, endLine, endLineStartPosition); + expr = context.makeDeleteNode(location, expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end); break; default: // If we get here something has gone horribly horribly wrong CRASH(); } subExprStart = context.unaryTokenStackLastStart(tokenStackDepth); - subExprLineStartPosition = context.unaryTokenStackLastLineStartPosition(tokenStackDepth); context.unaryTokenStackRemoveLast(tokenStackDepth); } return expr; diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h index e0a56754d..87d523404 100644 --- a/Source/JavaScriptCore/parser/Parser.h +++ b/Source/JavaScriptCore/parser/Parser.h @@ -475,8 +475,7 @@ private: String parseInner(); void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, - ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures, - int, int, IdentifierSet&); + ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures, int, IdentifierSet&); // Used to determine type of error to report. bool isFunctionBodyNode(ScopeNode*) { return false; } @@ -484,20 +483,22 @@ private: ALWAYS_INLINE void next(unsigned lexerFlags = 0) { - m_lastLine = m_token.m_location.line; - m_lastTokenEnd = m_token.m_location.endOffset; - m_lastTokenLineStart = m_token.m_location.lineStartOffset; - m_lexer->setLastLineNumber(m_lastLine); - m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_location, lexerFlags, strictMode()); + int lastLine = m_token.m_location.line; + int lastTokenEnd = m_token.m_location.endOffset; + int lastTokenLineStart = m_token.m_location.lineStartOffset; + m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart); + m_lexer->setLastLineNumber(lastLine); + m_token.m_type = m_lexer->lex(&m_token, lexerFlags, strictMode()); } ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0) { - m_lastLine = m_token.m_location.line; - m_lastTokenEnd = m_token.m_location.endOffset; - m_lastTokenLineStart = m_token.m_location.lineStartOffset; - m_lexer->setLastLineNumber(m_lastLine); - m_token.m_type = m_lexer->lexExpectIdentifier(&m_token.m_data, &m_token.m_location, lexerFlags, strictMode()); + int lastLine = m_token.m_location.line; + int lastTokenEnd = m_token.m_location.endOffset; + int lastTokenLineStart = m_token.m_location.lineStartOffset; + m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart); + m_lexer->setLastLineNumber(lastLine); + m_token.m_type = m_lexer->lexExpectIdentifier(&m_token, lexerFlags, strictMode()); } ALWAYS_INLINE bool nextTokenIsColon() @@ -515,7 +516,7 @@ private: ALWAYS_INLINE String getToken() { SourceProvider* sourceProvider = m_source->provider(); - return sourceProvider->getRange(tokenStart(), tokenEnd()); + return sourceProvider->getRange(tokenStart(), tokenEndPosition().offset); } ALWAYS_INLINE bool match(JSTokenType expected) @@ -528,6 +529,11 @@ private: return m_token.m_location.startOffset; } + ALWAYS_INLINE const JSTextPosition& tokenStartPosition() + { + return m_token.m_startPosition; + } + ALWAYS_INLINE int tokenLine() { return m_token.m_location.line; @@ -538,9 +544,9 @@ private: return tokenStart() - tokenLineStart(); } - ALWAYS_INLINE unsigned tokenEnd() + ALWAYS_INLINE const JSTextPosition& tokenEndPosition() { - return m_token.m_location.endOffset; + return m_token.m_endPosition; } ALWAYS_INLINE unsigned tokenLineStart() @@ -915,7 +921,7 @@ private: template <bool strict, class TreeBuilder> ALWAYS_INLINE TreeProperty parseProperty(TreeBuilder&); template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&); template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&); - template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, int& identStart, int& initStart, int& initEnd); + template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd); template <class TreeBuilder> ALWAYS_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder& context); template <FunctionRequirements, bool nameIsInContainingScope, class TreeBuilder> bool parseFunctionInfo(TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn); ALWAYS_INLINE int isBinaryOperator(JSTokenType); @@ -935,19 +941,9 @@ private: return m_stack.isSafeToRecurse(); } - int lastTokenEnd() const - { - return m_lastTokenEnd; - } - - unsigned lastTokenLine() const - { - return m_lastLine; - } - - unsigned lastTokenLineStart() const + const JSTextPosition& lastTokenEndPosition() const { - return m_lastTokenLineStart; + return m_lastTokenEndPosition; } bool hasError() const @@ -965,10 +961,7 @@ private: String m_errorMessage; JSToken m_token; bool m_allowsIn; - unsigned m_lastLine; - int m_lastTokenEnd; - unsigned m_lastTokenLine; - unsigned m_lastTokenLineStart; + JSTextPosition m_lastTokenEndPosition; int m_assignmentCount; int m_nonLHSCount; bool m_syntaxAlreadyValidated; @@ -1051,7 +1044,7 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error) *m_source, m_features, m_numConstants); - result->setLoc(m_source->firstLine(), m_lastLine, m_lexer->currentOffset(), m_lexer->currentLineStartOffset()); + result->setLoc(m_source->firstLine(), m_lastTokenEndPosition.line, m_lexer->currentOffset(), m_lexer->currentLineStartOffset()); } else { // We can never see a syntax error when reparsing a function, since we should have // reported the error when parsing the containing program or eval code. So if we're diff --git a/Source/JavaScriptCore/parser/ParserTokens.h b/Source/JavaScriptCore/parser/ParserTokens.h index ed9780b52..898fe62cb 100644 --- a/Source/JavaScriptCore/parser/ParserTokens.h +++ b/Source/JavaScriptCore/parser/ParserTokens.h @@ -150,6 +150,23 @@ enum JSTokenType { INVALID_STRING_LITERAL_ERRORTOK = 9 | ErrorTokenFlag, }; +struct JSTextPosition { + JSTextPosition() : line(0), offset(0), lineStartOffset(0) { } + JSTextPosition(int _line, int _offset, int _lineStartOffset) : line(_line), offset(_offset), lineStartOffset(_lineStartOffset) { } + JSTextPosition(const JSTextPosition& other) : line(other.line), offset(other.offset), lineStartOffset(other.lineStartOffset) { } + + JSTextPosition operator+(int adjustment) const { return JSTextPosition(line, offset + adjustment, lineStartOffset); } + JSTextPosition operator+(unsigned adjustment) const { return *this + static_cast<int>(adjustment); } + JSTextPosition operator-(int adjustment) const { return *this + (- adjustment); } + JSTextPosition operator-(unsigned adjustment) const { return *this + (- static_cast<int>(adjustment)); } + + operator int() const { return offset; } + + int line; + int offset; + int lineStartOffset; +}; + union JSTokenData { struct { uint32_t line; @@ -180,6 +197,8 @@ struct JSToken { JSTokenType m_type; JSTokenData m_data; JSTokenLocation m_location; + JSTextPosition m_startPosition; + JSTextPosition m_endPosition; }; } // namespace JSC diff --git a/Source/JavaScriptCore/parser/SyntaxChecker.h b/Source/JavaScriptCore/parser/SyntaxChecker.h index 7f902c0fd..6e600ebbb 100644 --- a/Source/JavaScriptCore/parser/SyntaxChecker.h +++ b/Source/JavaScriptCore/parser/SyntaxChecker.h @@ -119,21 +119,21 @@ public: static const unsigned DontBuildStrings = LexerFlagsDontBuildStrings; int createSourceElements() { return 1; } - ExpressionType makeFunctionCallNode(const JSTokenLocation&, int, int, int, int, int, int, int) { return CallExpr; } + ExpressionType makeFunctionCallNode(const JSTokenLocation&, int, int, int, int, int) { return CallExpr; } void appendToComma(ExpressionType& base, ExpressionType right) { base = right; } ExpressionType createCommaExpr(const JSTokenLocation&, ExpressionType, ExpressionType right) { return right; } - ExpressionType makeAssignNode(const JSTokenLocation&, ExpressionType, Operator, ExpressionType, bool, bool, int, int, int, int, int) { return AssignmentExpr; } - ExpressionType makePrefixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int, int, int) { return PreExpr; } - ExpressionType makePostfixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int, int, int) { return PostExpr; } + ExpressionType makeAssignNode(const JSTokenLocation&, ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; } + ExpressionType makePrefixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int) { return PreExpr; } + ExpressionType makePostfixNode(const JSTokenLocation&, ExpressionType, Operator, int, int, int) { return PostExpr; } ExpressionType makeTypeOfNode(const JSTokenLocation&, ExpressionType) { return TypeofExpr; } - ExpressionType makeDeleteNode(const JSTokenLocation&, ExpressionType, int, int, int, int, int) { return DeleteExpr; } + ExpressionType makeDeleteNode(const JSTokenLocation&, ExpressionType, int, int, int) { return DeleteExpr; } ExpressionType makeNegateNode(const JSTokenLocation&, ExpressionType) { return UnaryExpr; } ExpressionType makeBitwiseNotNode(const JSTokenLocation&, ExpressionType) { return UnaryExpr; } ExpressionType createLogicalNot(const JSTokenLocation&, ExpressionType) { return UnaryExpr; } ExpressionType createUnaryPlus(const JSTokenLocation&, ExpressionType) { return UnaryExpr; } ExpressionType createVoid(const JSTokenLocation&, ExpressionType) { return UnaryExpr; } ExpressionType thisExpr(const JSTokenLocation&) { return ThisExpr; } - ExpressionType createResolve(const JSTokenLocation&, const Identifier*, int, int, int) { return ResolveExpr; } + ExpressionType createResolve(const JSTokenLocation&, const Identifier*, int) { return ResolveExpr; } ExpressionType createObjectLiteral(const JSTokenLocation&) { return ObjectLiteralExpr; } ExpressionType createObjectLiteral(const JSTokenLocation&, int) { return ObjectLiteralExpr; } ExpressionType createArray(const JSTokenLocation&, int) { return ArrayLiteralExpr; } @@ -142,13 +142,13 @@ public: ExpressionType createString(const JSTokenLocation&, const Identifier*) { return StringExpr; } ExpressionType createBoolean(const JSTokenLocation&, bool) { return BoolExpr; } ExpressionType createNull(const JSTokenLocation&) { return NullExpr; } - ExpressionType createBracketAccess(const JSTokenLocation&, ExpressionType, ExpressionType, bool, int, int, int, int, int) { return BracketExpr; } - ExpressionType createDotAccess(const JSTokenLocation&, ExpressionType, const Identifier*, int, int, int, int, int) { return DotExpr; } - ExpressionType createRegExp(const JSTokenLocation&, const Identifier& pattern, const Identifier&, int, int, int) { return Yarr::checkSyntax(pattern.string()) ? 0 : RegExpExpr; } - ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int, int, int, int, int) { return NewExpr; } + ExpressionType createBracketAccess(const JSTokenLocation&, ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; } + ExpressionType createDotAccess(const JSTokenLocation&, ExpressionType, const Identifier*, int, int, int) { return DotExpr; } + ExpressionType createRegExp(const JSTokenLocation&, const Identifier& pattern, const Identifier&, int) { return Yarr::checkSyntax(pattern.string()) ? 0 : RegExpExpr; } ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int, int, int) { return NewExpr; } + ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int) { return NewExpr; } ExpressionType createConditionalExpr(const JSTokenLocation&, ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; } - ExpressionType createAssignResolve(const JSTokenLocation&, const Identifier&, ExpressionType, int, int, int, int, int) { return AssignmentExpr; } + ExpressionType createAssignResolve(const JSTokenLocation&, const Identifier&, ExpressionType, int, int, int) { return AssignmentExpr; } ExpressionType createFunctionExpr(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int) { return FunctionExpr; } int createFunctionBody(const JSTokenLocation&, const JSTokenLocation&, int, bool) { return 1; } void setFunctionStart(int, int) { } @@ -185,22 +185,22 @@ public: int createIfStatement(const JSTokenLocation&, int, int, int, int) { return 1; } int createIfStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; } int createForLoop(const JSTokenLocation&, int, int, int, int, int, int) { return 1; } - int createForInLoop(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int, int, int, int, int, int) { return 1; } - int createForInLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int, int, int) { return 1; } + int createForInLoop(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int, int, int, int, int) { return 1; } + int createForInLoop(const JSTokenLocation&, int, int, int, int, int, int, int, int) { return 1; } int createEmptyStatement(const JSTokenLocation&) { return 1; } int createVarStatement(const JSTokenLocation&, int, int, int) { return 1; } - int createReturnStatement(const JSTokenLocation&, int, int, int, int, int, int, int) { return 1; } - int createBreakStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; } - int createBreakStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int) { return 1; } - int createContinueStatement(const JSTokenLocation&, int, int, int, int, int) { return 1; } - int createContinueStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int) { return 1; } + int createReturnStatement(const JSTokenLocation&, int, int, int) { return 1; } + int createBreakStatement(const JSTokenLocation&, int, int) { return 1; } + int createBreakStatement(const JSTokenLocation&, const Identifier*, int, int) { return 1; } + int createContinueStatement(const JSTokenLocation&, int, int) { return 1; } + int createContinueStatement(const JSTokenLocation&, const Identifier*, int, int) { return 1; } int createTryStatement(const JSTokenLocation&, int, const Identifier*, int, int, int, int) { return 1; } int createSwitchStatement(const JSTokenLocation&, int, int, int, int, int, int) { return 1; } int createWhileStatement(const JSTokenLocation&, int, int, int, int) { return 1; } - int createWithStatement(const JSTokenLocation&, int, int, int, int, int, int, int, int) { return 1; } + int createWithStatement(const JSTokenLocation&, int, int, int, int, int, int) { return 1; } int createDoWhileStatement(const JSTokenLocation&, int, int, int, int) { return 1; } - int createLabelStatement(const JSTokenLocation&, const Identifier*, int, int, int, int, int) { return 1; } - int createThrowStatement(const JSTokenLocation&, int, int, int, int, int, int, int) { return 1; } + int createLabelStatement(const JSTokenLocation&, const Identifier*, int, int, int) { return 1; } + int createThrowStatement(const JSTokenLocation&, int, int, int) { return 1; } int createDebugger(const JSTokenLocation&, int, int) { return 1; } int createConstStatement(const JSTokenLocation&, int, int, int) { return 1; } int appendConstDecl(const JSTokenLocation&, int, const Identifier*, int) { return 1; } @@ -222,7 +222,7 @@ public: void addVar(const Identifier*, bool) { } int combineCommaNodes(const JSTokenLocation&, int, int) { return 1; } int evalCount() const { return 0; } - void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, int, int, bool) + void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool) { if (!m_topBinaryExpr) m_topBinaryExpr = expr; @@ -240,13 +240,12 @@ public: void operatorStackAppend(int& operatorStackDepth, int, int) { operatorStackDepth++; } int popOperandStack(int&) { int res = m_topBinaryExpr; m_topBinaryExpr = 0; return res; } - void appendUnaryToken(int& stackDepth, int tok, int, int, int) { stackDepth = 1; m_topUnaryToken = tok; } + void appendUnaryToken(int& stackDepth, int tok, int) { stackDepth = 1; m_topUnaryToken = tok; } int unaryTokenStackLastType(int&) { return m_topUnaryToken; } - unsigned unaryTokenStackLastStart(int&) { return 0; } - unsigned unaryTokenStackLastLineStartPosition(int&) { return 0; } + JSTextPosition unaryTokenStackLastStart(int&) { return JSTextPosition(0, 0, 0); } void unaryTokenStackRemoveLast(int& stackDepth) { stackDepth = 0; } - void assignmentStackAppend(int, int, int, int, int, int, int, Operator) { } + void assignmentStackAppend(int, int, int, int, int, Operator) { } int createAssignment(const JSTokenLocation&, int, int, int, int, int) { RELEASE_ASSERT_NOT_REACHED(); return 1; } const Identifier& getName(const Property& property) const { ASSERT(property.name); return *property.name; } PropertyNode::Type getType(const Property& property) const { return property.type; } |