Index: trunk/JavaScriptCore/kjs/JSObject.h =================================================================== --- trunk/JavaScriptCore/kjs/JSObject.h (revision 387) +++ trunk/JavaScriptCore/kjs/JSObject.h (revision 404) @@ -324,4 +324,6 @@ virtual bool isWatchdogException() const { return false; } + + virtual bool isNotAnObjectErrorStub() const { return false; } protected: Index: trunk/JavaScriptCore/kjs/lexer.cpp =================================================================== --- trunk/JavaScriptCore/kjs/lexer.cpp (revision 396) +++ trunk/JavaScriptCore/kjs/lexer.cpp (revision 404) @@ -75,4 +75,8 @@ , m_next2(0) , m_next3(0) + , m_currentOffset(0) + , m_nextOffset1(0) + , m_nextOffset2(0) + , m_nextOffset3(0) , m_globalData(globalData) , m_mainTable(KJS::mainTable) @@ -120,10 +124,15 @@ m_next1 = m_next2; m_next2 = m_next3; + m_currentOffset = m_nextOffset1; + m_nextOffset1 = m_nextOffset2; + m_nextOffset2 = m_nextOffset3; do { if (m_position >= m_length) { + m_nextOffset3 = m_position; m_position++; m_next3 = -1; break; } + m_nextOffset3 = m_position; m_next3 = m_code[m_position++]; } while (m_next3 == 0xFEFF); @@ -165,5 +174,5 @@ m_stackToken = 0; } - + int startOffset = m_currentOffset; while (!m_done) { if (m_skipLF && m_current != '\n') // found \r but not \n afterwards @@ -178,4 +187,5 @@ switch (m_state) { case Start: + startOffset = m_currentOffset; if (isWhiteSpace()) { // do nothing @@ -522,5 +532,6 @@ llocp->first_line = yylineno; llocp->last_line = yylineno; - + llocp->first_column = startOffset; + llocp->last_column = m_currentOffset; switch (m_state) { case Eof: Index: trunk/JavaScriptCore/kjs/DateConstructor.cpp =================================================================== --- trunk/JavaScriptCore/kjs/DateConstructor.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/DateConstructor.cpp (revision 404) @@ -129,5 +129,5 @@ { callData.native.function = callDate; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/ArrayConstructor.cpp =================================================================== --- trunk/JavaScriptCore/kjs/ArrayConstructor.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/ArrayConstructor.cpp (revision 404) @@ -78,5 +78,5 @@ // equivalent to 'new Array(....)' callData.native.function = callArrayConstructor; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/BooleanConstructor.cpp =================================================================== --- trunk/JavaScriptCore/kjs/BooleanConstructor.cpp (revision 355) +++ trunk/JavaScriptCore/kjs/BooleanConstructor.cpp (revision 404) @@ -64,5 +64,5 @@ { callData.native.function = callBooleanConstructor; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/Error.cpp =================================================================== --- trunk/JavaScriptCore/kjs/Error.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/Error.cpp (revision 404) @@ -33,4 +33,8 @@ namespace KJS { + +const char* expressionBeginOffsetPropertyName = "expressionBeginOffset"; +const char* expressionCaretOffsetPropertyName = "expressionCaretOffset"; +const char* expressionEndOffsetPropertyName = "expressionEndOffset"; JSObject* Error::create(ExecState* exec, ErrorType type, const UString& message, int lineNumber, int sourceId, const UString& sourceURL) @@ -79,9 +83,9 @@ if (lineNumber != -1) - error->put(exec, Identifier(exec, "line"), jsNumber(exec, lineNumber)); + error->putWithAttributes(exec, Identifier(exec, "line"), jsNumber(exec, lineNumber), ReadOnly | DontDelete); if (sourceId != -1) - error->put(exec, Identifier(exec, "sourceId"), jsNumber(exec, sourceId)); + error->putWithAttributes(exec, Identifier(exec, "sourceId"), jsNumber(exec, sourceId), ReadOnly | DontDelete); if (!sourceURL.isNull()) - error->put(exec, Identifier(exec, "sourceURL"), jsString(exec, sourceURL)); + error->putWithAttributes(exec, Identifier(exec, "sourceURL"), jsString(exec, sourceURL), ReadOnly | DontDelete); return error; Index: trunk/JavaScriptCore/kjs/NativeErrorConstructor.cpp =================================================================== --- trunk/JavaScriptCore/kjs/NativeErrorConstructor.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/NativeErrorConstructor.cpp (revision 404) @@ -66,5 +66,5 @@ { callData.native.function = callNativeErrorConstructor; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/PrototypeFunction.cpp =================================================================== --- trunk/JavaScriptCore/kjs/PrototypeFunction.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/PrototypeFunction.cpp (revision 404) @@ -51,5 +51,5 @@ { callData.native.function = m_function; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/PropertySlot.cpp =================================================================== --- trunk/JavaScriptCore/kjs/PropertySlot.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/PropertySlot.cpp (revision 404) @@ -41,5 +41,5 @@ CallData callData; CallType callType = slot.m_data.getterFunc->getCallData(callData); - if (callType == CallTypeNative) + if (callType == CallTypeHost) return callData.native.function(exec, slot.m_data.getterFunc, slot.slotBase(), exec->emptyList()); ASSERT(callType == CallTypeJS); Index: trunk/JavaScriptCore/kjs/nodes.cpp =================================================================== --- trunk/JavaScriptCore/kjs/nodes.cpp (revision 402) +++ trunk/JavaScriptCore/kjs/nodes.cpp (revision 404) @@ -163,6 +163,7 @@ } -RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg) -{ +RegisterID* ThrowableExpressionData::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg) +{ + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalExec(), msg)); generator.emitThrow(exception); @@ -170,8 +171,9 @@ } -RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label) +RegisterID* ThrowableExpressionData::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label) { UString message = msg; substitute(message, label.ustring()); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalExec(), message)); generator.emitThrow(exception); @@ -185,5 +187,4 @@ , m_lastLine(-1) { - m_line = -1; } @@ -289,5 +290,6 @@ return generator.moveToDestinationIfNeeded(dst, local); } - + + generator.emitExpressionInfo(m_startOffset + m_ident.size(), m_ident.size(), 0); return generator.emitResolve(generator.finalDestination(dst), m_ident); } @@ -376,5 +378,5 @@ RefPtr base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments, m_subscript->isPure(generator)); RegisterID* property = generator.emitNode(m_subscript.get()); - + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property); } @@ -385,4 +387,5 @@ { RegisterID* base = generator.emitNode(m_base.get()); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); return generator.emitGetById(generator.finalDestination(dst), base, m_ident); } @@ -401,4 +404,5 @@ { RegisterID* r0 = generator.emitNode(m_expr.get()); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); return generator.emitConstruct(generator.finalDestination(dst), r0, m_args.get()); } @@ -409,5 +413,5 @@ RegisterID* func = generator.newTemporary(); generator.emitResolveWithBase(base.get(), func, generator.propertyNames().eval); - return generator.emitCallEval(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get()); + return generator.emitCallEval(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset); } @@ -415,5 +419,5 @@ { RegisterID* func = generator.emitNode(m_expr.get()); - return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get()); + return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get(), m_divot, m_startOffset, m_endOffset); } @@ -421,5 +425,5 @@ { if (RegisterID* local = generator.registerForLocal(m_ident)) - return generator.emitCall(generator.finalDestination(dst), local, 0, m_args.get()); + return generator.emitCall(generator.finalDestination(dst), local, 0, m_args.get(), m_divot, m_startOffset, m_endOffset); int index = 0; @@ -427,11 +431,13 @@ if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) { RegisterID* func = generator.emitGetScopedVar(generator.newTemporary(), depth, index); - return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get()); + return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get(), m_divot, m_startOffset, m_endOffset); } RefPtr base = generator.tempDestination(dst); RegisterID* func = generator.newTemporary(); + int identifierStart = m_divot - m_startOffset; + generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0); generator.emitResolveFunction(base.get(), func, m_ident); - return generator.emitCall(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get()); + return generator.emitCall(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset); } @@ -440,6 +446,7 @@ RefPtr base = generator.emitNode(m_base.get()); RegisterID* property = generator.emitNode(m_subscript.get()); + generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset); RegisterID* function = generator.emitGetByVal(generator.newTemporary(), base.get(), property); - return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get()); + return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset); } @@ -447,6 +454,7 @@ { RefPtr base = generator.emitNode(m_base.get()); + generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset); RegisterID* function = generator.emitGetById(generator.newTemporary(), base.get(), m_ident); - return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get()); + return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset); } @@ -492,4 +500,5 @@ } + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); RefPtr value = generator.newTemporary(); RefPtr base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident); @@ -511,4 +520,6 @@ RefPtr base = generator.emitNode(m_base.get()); RefPtr property = generator.emitNode(m_subscript.get()); + + generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset); RefPtr value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get()); RegisterID* oldValue; @@ -522,4 +533,5 @@ oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get()); } + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); generator.emitPutByVal(base.get(), property.get(), value.get()); return oldValue; @@ -531,4 +543,6 @@ { RefPtr base = generator.emitNode(m_base.get()); + + generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset); RefPtr value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident); RegisterID* oldValue; @@ -542,4 +556,5 @@ oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get()); } + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); generator.emitPutById(base.get(), m_ident, value.get()); return oldValue; @@ -560,4 +575,5 @@ return generator.emitLoad(generator.finalDestination(dst), false); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident); return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident); @@ -570,4 +586,6 @@ RefPtr r0 = generator.emitNode(m_base.get()); RefPtr r1 = generator.emitNode(m_subscript.get()); + + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get()); } @@ -578,4 +596,6 @@ { RegisterID* r0 = generator.emitNode(m_base.get()); + + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident); } @@ -657,4 +677,5 @@ } + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); RefPtr propDst = generator.tempDestination(dst); RefPtr base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident); @@ -671,4 +692,6 @@ RefPtr property = generator.emitNode(m_subscript.get()); RefPtr propDst = generator.tempDestination(dst); + + generator.emitExpressionInfo(m_divot + m_subexpressionDivotOffset, m_subexpressionStartOffset, m_endOffset - m_subexpressionDivotOffset); RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get()); if (m_operator == OpPlusPlus) @@ -676,4 +699,5 @@ else generator.emitPreDec(value); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); generator.emitPutByVal(base.get(), property.get(), value); return generator.moveToDestinationIfNeeded(dst, propDst.get()); @@ -686,4 +710,6 @@ RefPtr base = generator.emitNode(m_base.get()); RefPtr propDst = generator.tempDestination(dst); + + generator.emitExpressionInfo(m_divot + m_subexpressionDivotOffset, m_subexpressionStartOffset, m_endOffset - m_subexpressionDivotOffset); RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident); if (m_operator == OpPlusPlus) @@ -691,4 +717,5 @@ else generator.emitPreDec(value); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); generator.emitPutById(base.get(), m_ident, value); return generator.moveToDestinationIfNeeded(dst, propDst.get()); @@ -724,4 +751,12 @@ RegisterID* src2 = generator.emitNode(m_term2.get()); return generator.emitBinaryOp(opcode(), generator.finalDestination(dst, src1.get()), src2, src1.get()); +} + +RegisterID* ThrowableBinaryOpNode::emitCode(CodeGenerator& generator, RegisterID* dst) +{ + RefPtr src1 = generator.emitNodeForLeftHandSide(m_term1.get(), m_rightHasAssignments, m_term2->isPure(generator)); + RegisterID* src2 = generator.emitNode(m_term2.get()); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); + return generator.emitBinaryOp(opcode(), generator.finalDestination(dst, src1.get()), src1.get(), src2); } @@ -847,6 +882,8 @@ RefPtr src1 = generator.tempDestination(dst); + generator.emitExpressionInfo(m_divot - m_startOffset + m_ident.size(), m_ident.size(), 0); RefPtr base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident); RegisterID* src2 = generator.emitNode(m_right.get()); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator); return generator.emitPutById(base.get(), m_ident, result); @@ -879,4 +916,5 @@ dst = 0; RegisterID* value = generator.emitNode(dst, m_right.get()); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); return generator.emitPutById(base.get(), m_ident, value); } @@ -889,4 +927,5 @@ RefPtr value = generator.destinationForAssignResult(dst); RegisterID* result = generator.emitNode(value.get(), m_right.get()); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); generator.emitPutById(base.get(), m_ident, result); return generator.moveToDestinationIfNeeded(dst, result); @@ -898,7 +937,11 @@ { RefPtr base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator)); + + generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset); RefPtr value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident); RegisterID* change = generator.emitNode(m_right.get()); RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator); + + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); return generator.emitPutById(base.get(), m_ident, updatedValue); } @@ -919,4 +962,6 @@ RefPtr value = generator.destinationForAssignResult(dst); RegisterID* result = generator.emitNode(value.get(), m_right.get()); + + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); generator.emitPutByVal(base.get(), property.get(), result); return generator.moveToDestinationIfNeeded(dst, result); @@ -928,8 +973,10 @@ RefPtr property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator)); + generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset); RefPtr value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get()); RegisterID* change = generator.emitNode(m_right.get()); RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); generator.emitPutByVal(base.get(), property.get(), updatedValue); @@ -1197,14 +1244,17 @@ } -ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement) +ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset) : StatementNode(globalData) , m_ident(ident) - , m_lexpr(new ResolveNode(globalData, ident)) + , m_lexpr(new ResolveNode(globalData, ident, divot - startOffset)) , m_expr(expr) , m_statement(statement) , m_identIsVarDecl(true) { - if (in) - m_init = new AssignResolveNode(globalData, ident, in, true); + if (in) { + AssignResolveNode* node = new AssignResolveNode(globalData, ident, in, true); + node->setExceptionSourceRange(divot, divot - startOffset, endOffset - divot); + m_init = node; + } // for( var foo = bar in baz ) } @@ -1230,4 +1280,6 @@ RefPtr protect = propertyName; RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident); + + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); generator.emitPutById(base, ident, propertyName); } @@ -1238,4 +1290,6 @@ RefPtr protect = propertyName; RegisterID* base = generator.emitNode(assignNode->base()); + + generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset()); generator.emitPutById(base, ident, propertyName); } else { @@ -1246,4 +1300,6 @@ RefPtr base = generator.emitNode(assignNode->base()); RegisterID* subscript = generator.emitNode(assignNode->subscript()); + + generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset()); generator.emitPutByVal(base.get(), subscript, propertyName); } @@ -1330,4 +1386,5 @@ { RefPtr scope = generator.emitNode(m_expr.get()); // scope must be protected until popped + generator.emitExpressionInfo(m_divot, m_expressionLength, 0); generator.emitPushScope(scope.get()); RegisterID* result = generator.emitNode(dst, m_statement.get()); @@ -1410,5 +1467,5 @@ if (generator.jumpContextForBreak(m_label)) return emitThrowError(generator, SyntaxError, "Duplicated label %s found.", m_label); - + RefPtr l0 = generator.newLabel(); m_labelStack.push(m_label); @@ -1428,5 +1485,7 @@ RegisterID* ThrowNode::emitCode(CodeGenerator& generator, RegisterID* dst) { - generator.emitThrow(generator.emitNode(dst, m_expr.get())); + RefPtr expr = generator.emitNode(dst, m_expr.get()); + generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset); + generator.emitThrow(expr.get()); return dst; } @@ -1507,18 +1566,20 @@ // ------------------------------ ProgramNode ----------------------------- -ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure) +ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure) : ScopeNode(globalData, children, varStack, funcStack, usesEval, needsClosure) -{ -} - -ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure) -{ - return new ProgramNode(globalData, children, varStack, funcStack, usesEval, needsClosure); + , m_sourceProvider(sourceProvider) +{ +} + +ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure) +{ + return new ProgramNode(globalData, children, varStack, funcStack, sourceProvider, usesEval, needsClosure); } // ------------------------------ EvalNode ----------------------------- -EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure) +EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure) : ScopeNode(globalData, children, varStack, funcStack, usesEval, needsClosure) + , m_sourceProvider(sourceProvider) { } @@ -1543,6 +1604,6 @@ SymbolTable symbolTable; - - m_code.set(new EvalCodeBlock(this, globalObject)); + ASSERT(m_sourceProvider); + m_code.set(new EvalCodeBlock(this, globalObject, m_sourceProvider)); CodeGenerator generator(this, globalObject->debugger(), scopeChain, &symbolTable, m_code.get()); @@ -1550,7 +1611,7 @@ } -EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure) -{ - return new EvalNode(globalData, children, varStack, funcStack, usesEval, needsClosure); +EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure) +{ + return new EvalNode(globalData, children, varStack, funcStack, sourceProvider, usesEval, needsClosure); } @@ -1573,4 +1634,9 @@ } +FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider*, bool usesEval, bool needsClosure) +{ + return new FunctionBodyNode(globalData, children, varStack, funcStack, usesEval, needsClosure); +} + void FunctionBodyNode::generateCode(ScopeChainNode* sc) { @@ -1578,5 +1644,6 @@ JSGlobalObject* globalObject = scopeChain.globalObject(); - m_code.set(new CodeBlock(this, FunctionCode)); + ASSERT(m_source.sourceProvider()); + m_code.set(new CodeBlock(this, FunctionCode, m_source.sourceProvider(), m_source.startOffset())); CodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_symbolTable, m_code.get()); @@ -1614,5 +1681,6 @@ JSGlobalObject* globalObject = scopeChain.globalObject(); - m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject)); + ASSERT(m_sourceProvider); + m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, m_sourceProvider)); CodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get(), m_varStack, m_functionStack); Index: trunk/JavaScriptCore/kjs/ObjectConstructor.cpp =================================================================== --- trunk/JavaScriptCore/kjs/ObjectConstructor.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/ObjectConstructor.cpp (revision 404) @@ -66,5 +66,5 @@ { callData.native.function = callObjectConstructor; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/StringConstructor.cpp =================================================================== --- trunk/JavaScriptCore/kjs/StringConstructor.cpp (revision 402) +++ trunk/JavaScriptCore/kjs/StringConstructor.cpp (revision 404) @@ -84,5 +84,5 @@ { callData.native.function = callStringConstructor; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/grammar.y =================================================================== --- trunk/JavaScriptCore/kjs/grammar.y (revision 402) +++ trunk/JavaScriptCore/kjs/grammar.y (revision 404) @@ -58,4 +58,5 @@ #define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*LEXER, yychar)) YYABORT; } while (0) +#define SET_EXCEPTION_LOCATION(node, start, divot, end) node->setExceptionSourceRange((divot), (divot) - (start), (end) - (divot)) #define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line) @@ -63,11 +64,11 @@ using namespace std; -static ExpressionNode* makeAssignNode(void*, ExpressionNode* loc, Operator, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments); -static ExpressionNode* makePrefixNode(void*, ExpressionNode* expr, Operator); -static ExpressionNode* makePostfixNode(void*, ExpressionNode* expr, Operator); +static ExpressionNode* makeAssignNode(void*, ExpressionNode* loc, Operator, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end); +static ExpressionNode* makePrefixNode(void*, ExpressionNode* expr, Operator, int start, int divot, int end); +static ExpressionNode* makePostfixNode(void*, ExpressionNode* expr, Operator, int start, int divot, int end); static PropertyNode* makeGetterOrSetterPropertyNode(void*, const Identifier &getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceRange&); -static ExpressionNodeInfo makeFunctionCallNode(void*, ExpressionNodeInfo func, ArgumentsNodeInfo); +static ExpressionNodeInfo makeFunctionCallNode(void*, ExpressionNodeInfo func, ArgumentsNodeInfo, int start, int divot, int end); static ExpressionNode* makeTypeOfNode(void*, ExpressionNode*); -static ExpressionNode* makeDeleteNode(void*, ExpressionNode*); +static ExpressionNode* makeDeleteNode(void*, ExpressionNode*, int start, int divot, int end); static ExpressionNode* makeNegateNode(void*, ExpressionNode*); static NumberNode* makeNumberNode(void*, double); @@ -288,5 +289,8 @@ if (!l.scanRegExp()) YYABORT; - $$ = createNodeFeatureInfo(new RegExpNode(GLOBAL_DATA, l.pattern(), l.flags()), 0); + RegExpNode* node = new RegExpNode(GLOBAL_DATA, l.pattern(), l.flags()); + int size = l.pattern().size() + 2; // + 2 for the two /'s + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.first_column + size, @1.first_column + size); + $$ = createNodeFeatureInfo(node, 0); } | DIVEQUAL /* regexp with /= */ { @@ -294,5 +298,8 @@ if (!l.scanRegExp()) YYABORT; - $$ = createNodeFeatureInfo(new RegExpNode(GLOBAL_DATA, "=" + l.pattern(), l.flags()), 0); + RegExpNode* node = new RegExpNode(GLOBAL_DATA, l.pattern(), l.flags()); + int size = l.pattern().size() + 2; // + 2 for the two /'s + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.first_column + size, @1.first_column + size); + $$ = createNodeFeatureInfo(node, 0); } ; @@ -328,5 +335,5 @@ | Literal | ArrayLiteral - | IDENT { $$ = createNodeFeatureInfo(new ResolveNode(GLOBAL_DATA, *$1), 0); } + | IDENT { $$ = createNodeFeatureInfo(new ResolveNode(GLOBAL_DATA, *$1, @1.first_column), 0); } | '(' Expr ')' { $$ = $2; } ; @@ -361,38 +368,73 @@ PrimaryExpr | FunctionExpr { $$ = createNodeFeatureInfo($1.m_node, $1.m_featureInfo); } - | MemberExpr '[' Expr ']' { $$ = createNodeFeatureInfo(new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } - | MemberExpr '.' IDENT { $$ = createNodeFeatureInfo(new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3), $1.m_featureInfo); } - | NEW MemberExpr Arguments { $$ = createNodeFeatureInfo(new NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node), $2.m_featureInfo | $3.m_featureInfo); } + | MemberExpr '[' Expr ']' { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo | $3.m_featureInfo); + } + | MemberExpr '.' IDENT { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo); + } + | NEW MemberExpr Arguments { NewExprNode* node = new NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $2.m_featureInfo | $3.m_featureInfo); + } ; MemberExprNoBF: PrimaryExprNoBrace - | MemberExprNoBF '[' Expr ']' { $$ = createNodeFeatureInfo(new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } - | MemberExprNoBF '.' IDENT { $$ = createNodeFeatureInfo(new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3), $1.m_featureInfo); } - | NEW MemberExpr Arguments { $$ = createNodeFeatureInfo(new NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node), $2.m_featureInfo | $3.m_featureInfo); } + | MemberExprNoBF '[' Expr ']' { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo | $3.m_featureInfo); + } + | MemberExprNoBF '.' IDENT { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo); + } + | NEW MemberExpr Arguments { NewExprNode* node = new NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $2.m_featureInfo | $3.m_featureInfo); + } ; NewExpr: MemberExpr - | NEW NewExpr { $$ = createNodeFeatureInfo(new NewExprNode(GLOBAL_DATA, $2.m_node), $2.m_featureInfo); } + | NEW NewExpr { NewExprNode* node = new NewExprNode(GLOBAL_DATA, $2.m_node); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeFeatureInfo(node, $2.m_featureInfo); + } ; NewExprNoBF: MemberExprNoBF - | NEW NewExpr { $$ = createNodeFeatureInfo(new NewExprNode(GLOBAL_DATA, $2.m_node), $2.m_featureInfo); } + | NEW NewExpr { NewExprNode* node = new NewExprNode(GLOBAL_DATA, $2.m_node); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeFeatureInfo(node, $2.m_featureInfo); + } ; CallExpr: - MemberExpr Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2); } - | CallExpr Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2); } - | CallExpr '[' Expr ']' { $$ = createNodeFeatureInfo(new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } - | CallExpr '.' IDENT { $$ = createNodeFeatureInfo(new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3), $1.m_featureInfo); } + MemberExpr Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + | CallExpr Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + | CallExpr '[' Expr ']' { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo | $3.m_featureInfo); + } + | CallExpr '.' IDENT { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo); } ; CallExprNoBF: - MemberExprNoBF Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2); } - | CallExprNoBF Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2); } - | CallExprNoBF '[' Expr ']' { $$ = createNodeFeatureInfo(new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } - | CallExprNoBF '.' IDENT { $$ = createNodeFeatureInfo(new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3), $1.m_featureInfo); } + MemberExprNoBF Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + | CallExprNoBF Arguments { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); } + | CallExprNoBF '[' Expr ']' { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo | $3.m_featureInfo); + } + | CallExprNoBF '.' IDENT { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo); + } ; @@ -423,22 +465,22 @@ PostfixExpr: LeftHandSideExpr - | LeftHandSideExpr PLUSPLUS { $$ = createNodeFeatureInfo(makePostfixNode(GLOBAL_DATA, $1.m_node, OpPlusPlus), $1.m_featureInfo | AssignFeature); } - | LeftHandSideExpr MINUSMINUS { $$ = createNodeFeatureInfo(makePostfixNode(GLOBAL_DATA, $1.m_node, OpMinusMinus), $1.m_featureInfo | AssignFeature); } + | LeftHandSideExpr PLUSPLUS { $$ = createNodeFeatureInfo(makePostfixNode(GLOBAL_DATA, $1.m_node, OpPlusPlus, @1.first_column, @1.last_column, @2.last_column), $1.m_featureInfo | AssignFeature); } + | LeftHandSideExpr MINUSMINUS { $$ = createNodeFeatureInfo(makePostfixNode(GLOBAL_DATA, $1.m_node, OpMinusMinus, @1.first_column, @1.last_column, @2.last_column), $1.m_featureInfo | AssignFeature); } ; PostfixExprNoBF: LeftHandSideExprNoBF - | LeftHandSideExprNoBF PLUSPLUS { $$ = createNodeFeatureInfo(makePostfixNode(GLOBAL_DATA, $1.m_node, OpPlusPlus), $1.m_featureInfo | AssignFeature); } - | LeftHandSideExprNoBF MINUSMINUS { $$ = createNodeFeatureInfo(makePostfixNode(GLOBAL_DATA, $1.m_node, OpMinusMinus), $1.m_featureInfo | AssignFeature); } + | LeftHandSideExprNoBF PLUSPLUS { $$ = createNodeFeatureInfo(makePostfixNode(GLOBAL_DATA, $1.m_node, OpPlusPlus, @1.first_column, @1.last_column, @2.last_column), $1.m_featureInfo | AssignFeature); } + | LeftHandSideExprNoBF MINUSMINUS { $$ = createNodeFeatureInfo(makePostfixNode(GLOBAL_DATA, $1.m_node, OpMinusMinus, @1.first_column, @1.last_column, @2.last_column), $1.m_featureInfo | AssignFeature); } ; UnaryExprCommon: - DELETETOKEN UnaryExpr { $$ = createNodeFeatureInfo(makeDeleteNode(GLOBAL_DATA, $2.m_node), $2.m_featureInfo); } + DELETETOKEN UnaryExpr { $$ = createNodeFeatureInfo(makeDeleteNode(GLOBAL_DATA, $2.m_node, @1.first_column, @2.last_column, @2.last_column), $2.m_featureInfo); } | VOIDTOKEN UnaryExpr { $$ = createNodeFeatureInfo(new VoidNode(GLOBAL_DATA, $2.m_node), $2.m_featureInfo); } | TYPEOF UnaryExpr { $$ = createNodeFeatureInfo(makeTypeOfNode(GLOBAL_DATA, $2.m_node), $2.m_featureInfo); } - | PLUSPLUS UnaryExpr { $$ = createNodeFeatureInfo(makePrefixNode(GLOBAL_DATA, $2.m_node, OpPlusPlus), $2.m_featureInfo | AssignFeature); } - | AUTOPLUSPLUS UnaryExpr { $$ = createNodeFeatureInfo(makePrefixNode(GLOBAL_DATA, $2.m_node, OpPlusPlus), $2.m_featureInfo | AssignFeature); } - | MINUSMINUS UnaryExpr { $$ = createNodeFeatureInfo(makePrefixNode(GLOBAL_DATA, $2.m_node, OpMinusMinus), $2.m_featureInfo | AssignFeature); } - | AUTOMINUSMINUS UnaryExpr { $$ = createNodeFeatureInfo(makePrefixNode(GLOBAL_DATA, $2.m_node, OpMinusMinus), $2.m_featureInfo | AssignFeature); } + | PLUSPLUS UnaryExpr { $$ = createNodeFeatureInfo(makePrefixNode(GLOBAL_DATA, $2.m_node, OpPlusPlus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_featureInfo | AssignFeature); } + | AUTOPLUSPLUS UnaryExpr { $$ = createNodeFeatureInfo(makePrefixNode(GLOBAL_DATA, $2.m_node, OpPlusPlus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_featureInfo | AssignFeature); } + | MINUSMINUS UnaryExpr { $$ = createNodeFeatureInfo(makePrefixNode(GLOBAL_DATA, $2.m_node, OpMinusMinus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_featureInfo | AssignFeature); } + | AUTOMINUSMINUS UnaryExpr { $$ = createNodeFeatureInfo(makePrefixNode(GLOBAL_DATA, $2.m_node, OpMinusMinus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_featureInfo | AssignFeature); } | '+' UnaryExpr { $$ = createNodeFeatureInfo(new UnaryPlusNode(GLOBAL_DATA, $2.m_node), $2.m_featureInfo); } | '-' UnaryExpr { $$ = createNodeFeatureInfo(makeNegateNode(GLOBAL_DATA, $2.m_node), $2.m_featureInfo); } @@ -507,6 +549,10 @@ | RelationalExpr LE ShiftExpr { $$ = createNodeFeatureInfo(new LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } | RelationalExpr GE ShiftExpr { $$ = createNodeFeatureInfo(new GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } - | RelationalExpr INSTANCEOF ShiftExpr { $$ = createNodeFeatureInfo(new InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } - | RelationalExpr INTOKEN ShiftExpr { $$ = createNodeFeatureInfo(new InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } + | RelationalExpr INSTANCEOF ShiftExpr { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo | $3.m_featureInfo); } + | RelationalExpr INTOKEN ShiftExpr { InNode* node = new InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo | $3.m_featureInfo); } ; @@ -518,5 +564,7 @@ | RelationalExprNoIn GE ShiftExpr { $$ = createNodeFeatureInfo(new GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } | RelationalExprNoIn INSTANCEOF ShiftExpr - { $$ = createNodeFeatureInfo(new InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } + { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo | $3.m_featureInfo); } ; @@ -528,6 +576,11 @@ | RelationalExprNoBF GE ShiftExpr { $$ = createNodeFeatureInfo(new GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } | RelationalExprNoBF INSTANCEOF ShiftExpr - { $$ = createNodeFeatureInfo(new InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } - | RelationalExprNoBF INTOKEN ShiftExpr { $$ = createNodeFeatureInfo(new InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); } + { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo | $3.m_featureInfo); } + | RelationalExprNoBF INTOKEN ShiftExpr + { InNode* node = new InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column); + $$ = createNodeFeatureInfo(node, $1.m_featureInfo | $3.m_featureInfo); } ; @@ -667,5 +720,7 @@ ConditionalExpr | LeftHandSideExpr AssignmentOperator AssignmentExpr - { $$ = createNodeFeatureInfo(makeAssignNode(GLOBAL_DATA, $1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); } + { $$ = createNodeFeatureInfo(makeAssignNode(GLOBAL_DATA, $1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature, + @1.first_column, @2.first_column + 1, @3.last_column), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); + } ; @@ -673,5 +728,7 @@ ConditionalExprNoIn | LeftHandSideExpr AssignmentOperator AssignmentExprNoIn - { $$ = createNodeFeatureInfo(makeAssignNode(GLOBAL_DATA, $1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); } + { $$ = createNodeFeatureInfo(makeAssignNode(GLOBAL_DATA, $1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature, + @1.first_column, @2.first_column + 1, @3.last_column), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); + } ; @@ -679,5 +736,7 @@ ConditionalExprNoBF | LeftHandSideExprNoBF AssignmentOperator AssignmentExpr - { $$ = createNodeFeatureInfo(makeAssignNode(GLOBAL_DATA, $1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); } + { $$ = createNodeFeatureInfo(makeAssignNode(GLOBAL_DATA, $1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature, + @1.first_column, @2.first_column + 1, @3.last_column), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); + } ; @@ -753,5 +812,7 @@ $$.m_featureInfo = 0; } - | IDENT Initializer { $$.m_node = new AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_featureInfo & AssignFeature); + | IDENT Initializer { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.first_column + 1, @2.last_column); + $$.m_node = node; $$.m_varDeclarations = new ParserRefCountedData(GLOBAL_DATA); appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); @@ -767,5 +828,7 @@ } | VariableDeclarationList ',' IDENT Initializer - { $$.m_node = combineVarInitializers(GLOBAL_DATA, $1.m_node, new AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_featureInfo & AssignFeature)); + { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @3.first_column, @4.first_column + 1, @4.last_column); + $$.m_node = combineVarInitializers(GLOBAL_DATA, $1.m_node, node); $$.m_varDeclarations = $1.m_varDeclarations; appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); @@ -782,5 +845,7 @@ $$.m_featureInfo = 0; } - | IDENT InitializerNoIn { $$.m_node = new AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_featureInfo & AssignFeature); + | IDENT InitializerNoIn { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.first_column + 1, @2.last_column); + $$.m_node = node; $$.m_varDeclarations = new ParserRefCountedData(GLOBAL_DATA); appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); @@ -796,5 +861,7 @@ } | VariableDeclarationListNoIn ',' IDENT InitializerNoIn - { $$.m_node = combineVarInitializers(GLOBAL_DATA, $1.m_node, new AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_featureInfo & AssignFeature)); + { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_featureInfo & AssignFeature); + SET_EXCEPTION_LOCATION(node, @3.first_column, @4.first_column + 1, @4.last_column); + $$.m_node = combineVarInitializers(GLOBAL_DATA, $1.m_node, node); $$.m_varDeclarations = $1.m_varDeclarations; appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); @@ -888,15 +955,19 @@ if (!n->isLocation()) YYABORT; - $$ = createNodeDeclarationInfo(new ForInNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node), $7.m_varDeclarations, $7.m_funcDeclarations, + ForInNode* node = new ForInNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node); + SET_EXCEPTION_LOCATION(node, @3.first_column, @3.last_column, @5.last_column); + $$ = createNodeDeclarationInfo(node, $7.m_varDeclarations, $7.m_funcDeclarations, $3.m_featureInfo | $5.m_featureInfo | $7.m_featureInfo); DBG($$.m_node, @1, @6); } | FOR '(' VAR IDENT INTOKEN Expr ')' Statement - { ForInNode *forIn = new ForInNode(GLOBAL_DATA, *$4, 0, $6.m_node, $8.m_node); + { ForInNode *forIn = new ForInNode(GLOBAL_DATA, *$4, 0, $6.m_node, $8.m_node, @5.first_column, @5.first_column - @4.first_column, @6.last_column - @5.first_column); + SET_EXCEPTION_LOCATION(forIn, @4.first_column, @5.first_column + 1, @6.last_column); appendToVarDeclarationList(GLOBAL_DATA, $8.m_varDeclarations, *$4, DeclarationStacks::HasInitializer); $$ = createNodeDeclarationInfo(forIn, $8.m_varDeclarations, $8.m_funcDeclarations, $6.m_featureInfo | $8.m_featureInfo); DBG($$.m_node, @1, @7); } | FOR '(' VAR IDENT InitializerNoIn INTOKEN Expr ')' Statement - { ForInNode *forIn = new ForInNode(GLOBAL_DATA, *$4, $5.m_node, $7.m_node, $9.m_node); + { ForInNode *forIn = new ForInNode(GLOBAL_DATA, *$4, $5.m_node, $7.m_node, $9.m_node, @5.first_column, @5.first_column - @4.first_column, @5.last_column - @5.first_column); + SET_EXCEPTION_LOCATION(forIn, @4.first_column, @6.first_column + 1, @7.last_column); appendToVarDeclarationList(GLOBAL_DATA, $9.m_varDeclarations, *$4, DeclarationStacks::HasInitializer); $$ = createNodeDeclarationInfo(forIn, $9.m_varDeclarations, $9.m_funcDeclarations, @@ -916,31 +987,55 @@ ContinueStatement: - CONTINUE ';' { $$ = createNodeDeclarationInfo(new ContinueNode(GLOBAL_DATA), 0, 0, 0); + CONTINUE ';' { ContinueNode* node = new ContinueNode(GLOBAL_DATA); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, 0); DBG($$.m_node, @1, @2); } - | CONTINUE error { $$ = createNodeDeclarationInfo(new ContinueNode(GLOBAL_DATA), 0, 0, 0); + | CONTINUE error { ContinueNode* node = new ContinueNode(GLOBAL_DATA); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } - | CONTINUE IDENT ';' { $$ = createNodeDeclarationInfo(new ContinueNode(GLOBAL_DATA, *$2), 0, 0, 0); + | CONTINUE IDENT ';' { ContinueNode* node = new ContinueNode(GLOBAL_DATA, *$2); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, 0); DBG($$.m_node, @1, @3); } - | CONTINUE IDENT error { $$ = createNodeDeclarationInfo(new ContinueNode(GLOBAL_DATA, *$2), 0, 0, 0); + | CONTINUE IDENT error { ContinueNode* node = new ContinueNode(GLOBAL_DATA, *$2); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, 0); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } ; BreakStatement: - BREAK ';' { $$ = createNodeDeclarationInfo(new BreakNode(GLOBAL_DATA), 0, 0, 0); DBG($$.m_node, @1, @2); } - | BREAK error { $$ = createNodeDeclarationInfo(new BreakNode(GLOBAL_DATA), 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } - | BREAK IDENT ';' { $$ = createNodeDeclarationInfo(new BreakNode(GLOBAL_DATA, *$2), 0, 0, 0); DBG($$.m_node, @1, @3); } - | BREAK IDENT error { $$ = createNodeDeclarationInfo(new BreakNode(GLOBAL_DATA, *$2), 0, 0, 0); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + BREAK ';' { BreakNode* node = new BreakNode(GLOBAL_DATA); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, 0); DBG($$.m_node, @1, @2); } + | BREAK error { BreakNode* node = new BreakNode(GLOBAL_DATA); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo(new BreakNode(GLOBAL_DATA), 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + | BREAK IDENT ';' { BreakNode* node = new BreakNode(GLOBAL_DATA, *$2); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, 0); DBG($$.m_node, @1, @3); } + | BREAK IDENT error { BreakNode* node = new BreakNode(GLOBAL_DATA, *$2); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo(new BreakNode(GLOBAL_DATA, *$2), 0, 0, 0); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } ; ReturnStatement: - RETURN ';' { $$ = createNodeDeclarationInfo(new ReturnNode(GLOBAL_DATA, 0), 0, 0, 0); DBG($$.m_node, @1, @2); } - | RETURN error { $$ = createNodeDeclarationInfo(new ReturnNode(GLOBAL_DATA, 0), 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } - | RETURN Expr ';' { $$ = createNodeDeclarationInfo(new ReturnNode(GLOBAL_DATA, $2.m_node), 0, 0, $2.m_featureInfo); DBG($$.m_node, @1, @3); } - | RETURN Expr error { $$ = createNodeDeclarationInfo(new ReturnNode(GLOBAL_DATA, $2.m_node), 0, 0, $2.m_featureInfo); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + RETURN ';' { ReturnNode* node = new ReturnNode(GLOBAL_DATA, 0); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, 0); DBG($$.m_node, @1, @2); } + | RETURN error { ReturnNode* node = new ReturnNode(GLOBAL_DATA, 0); + SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; } + | RETURN Expr ';' { ReturnNode* node = new ReturnNode(GLOBAL_DATA, $2.m_node); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, $2.m_featureInfo); DBG($$.m_node, @1, @3); } + | RETURN Expr error { ReturnNode* node = new ReturnNode(GLOBAL_DATA, $2.m_node); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, $2.m_featureInfo); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } ; WithStatement: - WITH '(' Expr ')' Statement { $$ = createNodeDeclarationInfo(new WithNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, - $3.m_featureInfo | $5.m_featureInfo); + WITH '(' Expr ')' Statement { $$ = createNodeDeclarationInfo(new WithNode(GLOBAL_DATA, $3.m_node, $5.m_node, @3.last_column, @3.last_column - @3.first_column), + $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_featureInfo | $5.m_featureInfo); DBG($$.m_node, @1, @4); } ; @@ -992,10 +1087,18 @@ LabelledStatement: IDENT ':' Statement { $3.m_node->pushLabel(*$1); - $$ = createNodeDeclarationInfo(new LabelNode(GLOBAL_DATA, *$1, $3.m_node), $3.m_varDeclarations, $3.m_funcDeclarations, $3.m_featureInfo); } + LabelNode* node = new LabelNode(GLOBAL_DATA, *$1, $3.m_node); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo(node, $3.m_varDeclarations, $3.m_funcDeclarations, $3.m_featureInfo); } ; ThrowStatement: - THROW Expr ';' { $$ = createNodeDeclarationInfo(new ThrowNode(GLOBAL_DATA, $2.m_node), 0, 0, $2.m_featureInfo); DBG($$.m_node, @1, @3); } - | THROW Expr error { $$ = createNodeDeclarationInfo(new ThrowNode(GLOBAL_DATA, $2.m_node), 0, 0, $2.m_featureInfo); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; } + THROW Expr ';' { ThrowNode* node = new ThrowNode(GLOBAL_DATA, $2.m_node); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, $2.m_featureInfo); DBG($$.m_node, @1, @2); + } + | THROW Expr error { ThrowNode* node = new ThrowNode(GLOBAL_DATA, $2.m_node); + SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); + $$ = createNodeDeclarationInfo(node, 0, 0, $2.m_featureInfo); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; + } ; @@ -1092,85 +1195,106 @@ %% -static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments) +static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end) { if (!loc->isLocation()) - return new AssignErrorNode(GLOBAL_DATA, loc, op, expr); + return new AssignErrorNode(GLOBAL_DATA, loc, op, expr, divot, divot - start, end - divot); if (loc->isResolveNode()) { ResolveNode* resolve = static_cast(loc); - if (op == OpEqual) - return new AssignResolveNode(GLOBAL_DATA, resolve->identifier(), expr, exprHasAssignments); - else - return new ReadModifyResolveNode(GLOBAL_DATA, resolve->identifier(), op, expr, exprHasAssignments); + if (op == OpEqual) { + AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, resolve->identifier(), expr, exprHasAssignments); + SET_EXCEPTION_LOCATION(node, start, divot, end); + return node; + } else + return new ReadModifyResolveNode(GLOBAL_DATA, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); } if (loc->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast(loc); if (op == OpEqual) - return new AssignBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments); - else - return new ReadModifyBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments); + return new AssignBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot()); + else { + ReadModifyBracketNode* node = new ReadModifyBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot); + node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); + return node; + } } ASSERT(loc->isDotAccessorNode()); DotAccessorNode* dot = static_cast(loc); if (op == OpEqual) - return new AssignDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), expr, exprHasAssignments); - return new ReadModifyDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, expr, exprHasAssignments); -} - -static ExpressionNode* makePrefixNode(void* globalPtr, ExpressionNode* expr, Operator op) -{ + return new AssignDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot()); + + ReadModifyDotNode* node = new ReadModifyDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot); + node->setSubexpressionInfo(dot->divot(), dot->endOffset()); + return node; +} + +static ExpressionNode* makePrefixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end) +{ if (!expr->isLocation()) - return new PrefixErrorNode(GLOBAL_DATA, expr, op); + return new PrefixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast(expr); - return new PrefixResolveNode(GLOBAL_DATA, resolve->identifier(), op); + return new PrefixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast(expr); - return new PrefixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op); + PrefixBracketNode* node = new PrefixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); + node->setSubexpressionInfo(bracket->divot(), bracket->startOffset()); + return node; } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast(expr); - return new PrefixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op); -} - -static ExpressionNode* makePostfixNode(void* globalPtr, ExpressionNode* expr, Operator op) + PrefixDotNode* node = new PrefixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); + node->setSubexpressionInfo(dot->divot(), dot->startOffset()); + return node; +} + +static ExpressionNode* makePostfixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end) { if (!expr->isLocation()) - return new PostfixErrorNode(GLOBAL_DATA, expr, op); + return new PostfixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot); if (expr->isResolveNode()) { ResolveNode* resolve = static_cast(expr); - return new PostfixResolveNode(GLOBAL_DATA, resolve->identifier(), op); + return new PostfixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast(expr); - return new PostfixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op); + PostfixBracketNode* node = new PostfixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot); + node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); + return node; + } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast(expr); - return new PostfixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op); -} - -static ExpressionNodeInfo makeFunctionCallNode(void* globalPtr, ExpressionNodeInfo func, ArgumentsNodeInfo args) + PostfixDotNode* node = new PostfixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot); + node->setSubexpressionInfo(dot->divot(), dot->endOffset()); + return node; +} + +static ExpressionNodeInfo makeFunctionCallNode(void* globalPtr, ExpressionNodeInfo func, ArgumentsNodeInfo args, int start, int divot, int end) { FeatureInfo features = func.m_featureInfo | args.m_featureInfo; if (!func.m_node->isLocation()) - return createNodeFeatureInfo(new FunctionCallValueNode(GLOBAL_DATA, func.m_node, args.m_node), features); + return createNodeFeatureInfo(new FunctionCallValueNode(GLOBAL_DATA, func.m_node, args.m_node, divot, divot - start, end - divot), features); if (func.m_node->isResolveNode()) { ResolveNode* resolve = static_cast(func.m_node); const Identifier& identifier = resolve->identifier(); if (identifier == GLOBAL_DATA->propertyNames->eval) - return createNodeFeatureInfo(new EvalFunctionCallNode(GLOBAL_DATA, args.m_node), EvalFeature | features); - return createNodeFeatureInfo(new FunctionCallResolveNode(GLOBAL_DATA, identifier, args.m_node), features); + return createNodeFeatureInfo(new EvalFunctionCallNode(GLOBAL_DATA, args.m_node, divot, divot - start, end - divot), EvalFeature | features); + return createNodeFeatureInfo(new FunctionCallResolveNode(GLOBAL_DATA, identifier, args.m_node, divot, divot - start, end - divot), features); } if (func.m_node->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast(func.m_node); - return createNodeFeatureInfo(new FunctionCallBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), args.m_node), features); + FunctionCallBracketNode* node = new FunctionCallBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot); + node->setSubexpressionInfo(bracket->divot(), bracket->endOffset()); + return createNodeFeatureInfo(node, features); } ASSERT(func.m_node->isDotAccessorNode()); DotAccessorNode* dot = static_cast(func.m_node); - return createNodeFeatureInfo(new FunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node), features); + FunctionCallDotNode* node = new FunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot); + node->setSubexpressionInfo(dot->divot(), dot->endOffset()); + return createNodeFeatureInfo(node, features); } @@ -1184,5 +1308,5 @@ } -static ExpressionNode* makeDeleteNode(void* globalPtr, ExpressionNode* expr) +static ExpressionNode* makeDeleteNode(void* globalPtr, ExpressionNode* expr, int start, int divot, int end) { if (!expr->isLocation()) @@ -1190,13 +1314,13 @@ if (expr->isResolveNode()) { ResolveNode* resolve = static_cast(expr); - return new DeleteResolveNode(GLOBAL_DATA, resolve->identifier()); + return new DeleteResolveNode(GLOBAL_DATA, resolve->identifier(), divot, divot - start, end - divot); } if (expr->isBracketAccessorNode()) { BracketAccessorNode* bracket = static_cast(expr); - return new DeleteBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript()); + return new DeleteBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), divot, divot - start, end - divot); } ASSERT(expr->isDotAccessorNode()); DotAccessorNode* dot = static_cast(expr); - return new DeleteDotNode(GLOBAL_DATA, dot->base(), dot->identifier()); + return new DeleteDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), divot, divot - start, end - divot); } Index: trunk/JavaScriptCore/kjs/JSActivation.cpp =================================================================== --- trunk/JavaScriptCore/kjs/JSActivation.cpp (revision 402) +++ trunk/JavaScriptCore/kjs/JSActivation.cpp (revision 404) @@ -52,5 +52,5 @@ void JSActivation::copyRegisters() { - int numLocals = d()->functionBody->generatedCode().numLocals; + int numLocals = d()->functionBody->generatedByteCode().numLocals; if (!numLocals) return; @@ -157,5 +157,5 @@ JSObject* JSActivation::createArgumentsObject(ExecState* exec) { - Register* callFrame = d()->registers - d()->functionBody->generatedCode().numLocals - RegisterFile::CallFrameHeaderSize; + Register* callFrame = d()->registers - d()->functionBody->generatedByteCode().numLocals - RegisterFile::CallFrameHeaderSize; JSFunction* function; Index: trunk/JavaScriptCore/kjs/FunctionConstructor.cpp =================================================================== --- trunk/JavaScriptCore/kjs/FunctionConstructor.cpp (revision 355) +++ trunk/JavaScriptCore/kjs/FunctionConstructor.cpp (revision 404) @@ -62,5 +62,5 @@ { callData.native.function = callFunctionConstructor; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/Error.h =================================================================== --- trunk/JavaScriptCore/kjs/Error.h (revision 381) +++ trunk/JavaScriptCore/kjs/Error.h (revision 404) @@ -43,5 +43,9 @@ URIError = 6 }; - + + extern const char* expressionBeginOffsetPropertyName; + extern const char* expressionCaretOffsetPropertyName; + extern const char* expressionEndOffsetPropertyName; + class Error { public: Index: trunk/JavaScriptCore/kjs/ErrorConstructor.cpp =================================================================== --- trunk/JavaScriptCore/kjs/ErrorConstructor.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/ErrorConstructor.cpp (revision 404) @@ -68,5 +68,5 @@ { callData.native.function = callErrorConstructor; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/CallData.cpp =================================================================== --- trunk/JavaScriptCore/kjs/CallData.cpp (revision 394) +++ trunk/JavaScriptCore/kjs/CallData.cpp (revision 404) @@ -33,5 +33,5 @@ JSValue* call(ExecState* exec, JSValue* functionObject, CallType callType, const CallData& callData, JSValue* thisValue, const ArgList& args) { - if (callType == CallTypeNative) + if (callType == CallTypeHost) return callData.native.function(exec, static_cast(functionObject), thisValue, args); ASSERT(callType == CallTypeJS); Index: trunk/JavaScriptCore/kjs/config.h =================================================================== --- trunk/JavaScriptCore/kjs/config.h (revision 355) +++ trunk/JavaScriptCore/kjs/config.h (revision 404) @@ -38,5 +38,5 @@ #endif -#if PLATFORM(FREEBSD) +#if PLATFORM(FREEBSD) || PLATFORM(OPENBSD) #define HAVE_PTHREAD_NP_H 1 #endif Index: trunk/JavaScriptCore/kjs/JSGlobalObjectFunctions.cpp =================================================================== --- trunk/JavaScriptCore/kjs/JSGlobalObjectFunctions.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/JSGlobalObjectFunctions.cpp (revision 404) @@ -137,5 +137,5 @@ } -static bool isStrWhiteSpace(unsigned short c) +bool isStrWhiteSpace(UChar c) { switch (c) { Index: trunk/JavaScriptCore/kjs/DebuggerCallFrame.cpp =================================================================== --- trunk/JavaScriptCore/kjs/DebuggerCallFrame.cpp (revision 402) +++ trunk/JavaScriptCore/kjs/DebuggerCallFrame.cpp (revision 404) @@ -81,7 +81,6 @@ int errLine; UString errMsg; - - RefPtr evalNode = newExec.parser()->parse(&newExec, UString(), 1, UStringSourceProvider::create(script), &sourceId, &errLine, &errMsg); - + RefPtr sourceProvider = UStringSourceProvider::create(script); + RefPtr evalNode = newExec.parser()->parse(&newExec, UString(), 1, sourceProvider, &sourceId, &errLine, &errMsg); if (!evalNode) return Error::create(&newExec, SyntaxError, errMsg, errLine, sourceId, 0); Index: trunk/JavaScriptCore/kjs/NumberConstructor.cpp =================================================================== --- trunk/JavaScriptCore/kjs/NumberConstructor.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/NumberConstructor.cpp (revision 404) @@ -98,5 +98,5 @@ { callData.native.function = callNumberConstructor; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/RegExpConstructor.cpp =================================================================== --- trunk/JavaScriptCore/kjs/RegExpConstructor.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/RegExpConstructor.cpp (revision 404) @@ -309,5 +309,5 @@ { callData.native.function = callRegExpConstructor; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/Parser.h =================================================================== --- trunk/JavaScriptCore/kjs/Parser.h (revision 387) +++ trunk/JavaScriptCore/kjs/Parser.h (revision 404) @@ -81,5 +81,6 @@ { m_sourceURL = sourceURL; - parse(exec, sourceURL, startingLineNumber, source, sourceId, errLine, errMsg); + RefPtr sourceProvider = source; + parse(exec, sourceURL, startingLineNumber, sourceProvider.get(), sourceId, errLine, errMsg); if (!m_sourceElements) { m_sourceURL = UString(); @@ -90,4 +91,5 @@ m_varDeclarations ? &m_varDeclarations->data : 0, m_funcDeclarations ? &m_funcDeclarations->data : 0, + sourceProvider.get(), m_usesEval, m_needsClosure); Index: trunk/JavaScriptCore/kjs/RegExpObject.cpp =================================================================== --- trunk/JavaScriptCore/kjs/RegExpObject.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/RegExpObject.cpp (revision 404) @@ -147,5 +147,5 @@ { callData.native.function = callRegExpObject; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/SourceRange.h =================================================================== --- trunk/JavaScriptCore/kjs/SourceRange.h (revision 248) +++ trunk/JavaScriptCore/kjs/SourceRange.h (revision 404) @@ -54,5 +54,7 @@ return m_sourceProvider->getRange(m_startChar, m_endChar); } - + + SourceProvider* sourceProvider() const { return m_sourceProvider.get(); } + int startOffset() const { return m_startChar; } private: RefPtr m_sourceProvider; Index: trunk/JavaScriptCore/kjs/JSNotAnObject.h =================================================================== --- trunk/JavaScriptCore/kjs/JSNotAnObject.h (revision 381) +++ trunk/JavaScriptCore/kjs/JSNotAnObject.h (revision 404) @@ -34,4 +34,16 @@ namespace KJS { + class JSNotAnObjectErrorStub : public JSObject { + public: + JSNotAnObjectErrorStub(bool isNull) + : m_isNull(isNull) + { + } + bool isNull() const { return m_isNull; } + bool isNotAnObjectErrorStub() const { return true; } + private: + bool m_isNull; + }; + // This unholy class is used to allow us to avoid multiple exception checks // in certain SquirrelFish opcodes -- effectively it just silently consumes @@ -39,5 +51,5 @@ class JSNotAnObject : public JSObject { public: - JSNotAnObject(JSObject* exception) + JSNotAnObject(JSNotAnObjectErrorStub* exception) : m_exception(exception) { @@ -68,5 +80,5 @@ virtual void getPropertyNames(ExecState*, PropertyNameArray&); - JSObject* m_exception; + JSNotAnObjectErrorStub* m_exception; }; Index: trunk/JavaScriptCore/kjs/collector.cpp =================================================================== --- trunk/JavaScriptCore/kjs/collector.cpp (revision 396) +++ trunk/JavaScriptCore/kjs/collector.cpp (revision 404) @@ -64,4 +64,8 @@ #endif +#if PLATFORM(OPENBSD) +#include +#endif + #if HAVE(PTHREAD_NP_H) #include @@ -471,4 +475,9 @@ thr_stksegment(&s); return s.ss_sp; +#elif PLATFORM(OPENBSD) + pthread_t thread = pthread_self(); + stack_t stack; + pthread_stackseg_np(thread, &stack); + return stack.ss_sp; #elif PLATFORM(UNIX) static void* stackBase = 0; Index: trunk/JavaScriptCore/kjs/JSImmediate.cpp =================================================================== --- trunk/JavaScriptCore/kjs/JSImmediate.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/JSImmediate.cpp (revision 404) @@ -25,4 +25,5 @@ #include "BooleanPrototype.h" #include "Error.h" +#include "ExceptionHelpers.h" #include "JSGlobalObject.h" #include "JSNotAnObject.h" @@ -39,8 +40,8 @@ if (isBoolean(v)) return constructBooleanFromImmediateBoolean(exec, const_cast(v)); - if (v == jsNull()) - return new (exec) JSNotAnObject(throwError(exec, TypeError, "Null value")); - ASSERT(v == jsUndefined()); - return new (exec) JSNotAnObject(throwError(exec, TypeError, "Undefined value")); + + JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v == jsNull()); + exec->setException(exception); + return new (exec) JSNotAnObject(exception); } @@ -52,8 +53,8 @@ if (isBoolean(v)) return exec->lexicalGlobalObject()->booleanPrototype(); - if (v == jsNull()) - return new (exec) JSNotAnObject(throwError(exec, TypeError, "Null value")); - ASSERT(v == jsUndefined()); - return new (exec) JSNotAnObject(throwError(exec, TypeError, "Undefined value")); + + JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v == jsNull()); + exec->setException(exception); + return new (exec) JSNotAnObject(exception); } Index: trunk/JavaScriptCore/kjs/CallData.h =================================================================== --- trunk/JavaScriptCore/kjs/CallData.h (revision 320) +++ trunk/JavaScriptCore/kjs/CallData.h (revision 404) @@ -41,5 +41,5 @@ enum CallType { CallTypeNone, - CallTypeNative, + CallTypeHost, CallTypeJS }; Index: trunk/JavaScriptCore/kjs/FunctionPrototype.cpp =================================================================== --- trunk/JavaScriptCore/kjs/FunctionPrototype.cpp (revision 381) +++ trunk/JavaScriptCore/kjs/FunctionPrototype.cpp (revision 404) @@ -52,5 +52,5 @@ { callData.native.function = callFunctionPrototype; - return CallTypeNative; + return CallTypeHost; } Index: trunk/JavaScriptCore/kjs/nodes.h =================================================================== --- trunk/JavaScriptCore/kjs/nodes.h (revision 402) +++ trunk/JavaScriptCore/kjs/nodes.h (revision 404) @@ -176,5 +176,5 @@ UString toString() const KJS_FAST_CALL; - int lineNo() const KJS_FAST_CALL { return m_line; } + int lineNo() const { return m_line; } virtual bool isReturnNode() const KJS_FAST_CALL { return false; } @@ -187,7 +187,4 @@ protected: Node(JSGlobalData*, JSType) KJS_FAST_CALL; // used by ExpressionNode - - RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg); - RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg, const Identifier&); int m_line : 28; @@ -319,6 +316,99 @@ UString m_value; }; - - class RegExpNode : public ExpressionNode { + + class ThrowableExpressionData { + public: + ThrowableExpressionData() + : m_divot(static_cast(-1)) + , m_startOffset(static_cast(-1)) + , m_endOffset(static_cast(-1)) + { + } + + ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset) + : m_divot(divot) + , m_startOffset(startOffset) + , m_endOffset(endOffset) + { + } + + void setExceptionSourceRange(unsigned divot, unsigned startOffset, unsigned endOffset) + { + m_divot = divot; + m_startOffset = startOffset; + m_endOffset = endOffset; + } + + uint32_t divot() const { return m_divot; } + uint16_t startOffset() const { return m_startOffset; } + uint16_t endOffset() const { return m_endOffset; } + + protected: + RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg); + RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg, const Identifier&); + uint32_t m_divot; + uint16_t m_startOffset; + uint16_t m_endOffset; + }; + + class ThrowableSubExpressionData : public ThrowableExpressionData { + public: + ThrowableSubExpressionData() + : ThrowableExpressionData() + , m_subexpressionDivotOffset(0) + , m_subexpressionEndOffset(0) + { + } + + ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset) + : ThrowableExpressionData(divot, startOffset, endOffset) + , m_subexpressionDivotOffset(0) + , m_subexpressionEndOffset(0) + { + } + + void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) { + ASSERT(subexpressionDivot <= m_divot); + if ((m_divot - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot + return; + m_subexpressionDivotOffset = m_divot - subexpressionDivot; + m_subexpressionEndOffset = subexpressionOffset; + } + + protected: + uint16_t m_subexpressionDivotOffset; + uint16_t m_subexpressionEndOffset; + }; + + class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData { + public: + ThrowablePrefixedSubExpressionData() + : ThrowableExpressionData() + , m_subexpressionDivotOffset(0) + , m_subexpressionStartOffset(0) + { + } + + ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset) + : ThrowableExpressionData(divot, startOffset, endOffset) + , m_subexpressionDivotOffset(0) + , m_subexpressionStartOffset(0) + { + } + + void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) { + ASSERT(subexpressionDivot >= m_divot); + if ((subexpressionDivot - m_divot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot + return; + m_subexpressionDivotOffset = subexpressionDivot - m_divot; + m_subexpressionStartOffset = subexpressionOffset; + } + + protected: + uint16_t m_subexpressionDivotOffset; + uint16_t m_subexpressionStartOffset; + }; + + class RegExpNode : public ExpressionNode, public ThrowableExpressionData { public: RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags) KJS_FAST_CALL @@ -352,7 +442,8 @@ class ResolveNode : public ExpressionNode { public: - ResolveNode(JSGlobalData* globalData, const Identifier& ident) KJS_FAST_CALL + ResolveNode(JSGlobalData* globalData, const Identifier& ident, int startOffset) KJS_FAST_CALL : ExpressionNode(globalData) , m_ident(ident) + , m_startOffset(startOffset) { } @@ -370,6 +461,6 @@ protected: Identifier m_ident; - int m_index; // Used by LocalVarAccessNode and ScopedVarAccessNode. - size_t m_scopeDepth; // Used by ScopedVarAccessNode + int32_t m_startOffset; + }; @@ -514,6 +605,6 @@ RefPtr m_list; }; - - class BracketAccessorNode : public ExpressionNode { + + class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData { public: BracketAccessorNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments) KJS_FAST_CALL @@ -541,5 +632,5 @@ }; - class DotAccessorNode : public ExpressionNode { + class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData { public: DotAccessorNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL @@ -608,5 +699,5 @@ }; - class NewExprNode : public ExpressionNode { + class NewExprNode : public ExpressionNode, public ThrowableExpressionData { public: NewExprNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL @@ -633,8 +724,9 @@ }; - class EvalFunctionCallNode : public ExpressionNode { - public: - EvalFunctionCallNode(JSGlobalData* globalData, ArgumentsNode* args) KJS_FAST_CALL - : ExpressionNode(globalData) + class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData { + public: + EvalFunctionCallNode(JSGlobalData* globalData, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_args(args) { @@ -649,8 +741,9 @@ }; - class FunctionCallValueNode : public ExpressionNode { - public: - FunctionCallValueNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args) KJS_FAST_CALL - : ExpressionNode(globalData) + class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData { + public: + FunctionCallValueNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_expr(expr) , m_args(args) @@ -667,8 +760,9 @@ }; - class FunctionCallResolveNode : public ExpressionNode { - public: - FunctionCallResolveNode(JSGlobalData* globalData, const Identifier& ident, ArgumentsNode* args) KJS_FAST_CALL - : ExpressionNode(globalData) + class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData { + public: + FunctionCallResolveNode(JSGlobalData* globalData, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_ident(ident) , m_args(args) @@ -688,8 +782,9 @@ }; - class FunctionCallBracketNode : public ExpressionNode { - public: - FunctionCallBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args) KJS_FAST_CALL - : ExpressionNode(globalData) + class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData { + public: + FunctionCallBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableSubExpressionData(divot, startOffset, endOffset) , m_base(base) , m_subscript(subscript) @@ -708,8 +803,9 @@ }; - class FunctionCallDotNode : public ExpressionNode { - public: - FunctionCallDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args) KJS_FAST_CALL - : ExpressionNode(globalData) + class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData { + public: + FunctionCallDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableSubExpressionData(divot, startOffset, endOffset) , m_base(base) , m_ident(ident) @@ -728,8 +824,9 @@ }; - class PrePostResolveNode : public ExpressionNode { - public: - PrePostResolveNode(JSGlobalData* globalData, const Identifier& ident) KJS_FAST_CALL + class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData { + public: + PrePostResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL : ExpressionNode(globalData, NumberType) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_ident(ident) { @@ -738,11 +835,10 @@ protected: Identifier m_ident; - size_t m_index; // Used by LocalVarPostfixNode. }; class PostfixResolveNode : public PrePostResolveNode { public: - PostfixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper) KJS_FAST_CALL - : PrePostResolveNode(globalData, ident) + PostfixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset) , m_operator(oper) { @@ -757,8 +853,9 @@ }; - class PostfixBracketNode : public ExpressionNode { - public: - PostfixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper) KJS_FAST_CALL - : ExpressionNode(globalData) + class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData { + public: + PostfixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableSubExpressionData(divot, startOffset, endOffset) , m_base(base) , m_subscript(subscript) @@ -777,8 +874,9 @@ }; - class PostfixDotNode : public ExpressionNode { - public: - PostfixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper) KJS_FAST_CALL - : ExpressionNode(globalData) + class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData { + public: + PostfixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableSubExpressionData(divot, startOffset, endOffset) , m_base(base) , m_ident(ident) @@ -797,8 +895,9 @@ }; - class PostfixErrorNode : public ExpressionNode { - public: - PostfixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper) KJS_FAST_CALL - : ExpressionNode(globalData) + class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData { + public: + PostfixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableSubExpressionData(divot, startOffset, endOffset) , m_expr(expr) , m_operator(oper) @@ -815,8 +914,9 @@ }; - class DeleteResolveNode : public ExpressionNode { - public: - DeleteResolveNode(JSGlobalData* globalData, const Identifier& ident) KJS_FAST_CALL - : ExpressionNode(globalData) + class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData { + public: + DeleteResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_ident(ident) { @@ -832,8 +932,9 @@ }; - class DeleteBracketNode : public ExpressionNode { - public: - DeleteBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL - : ExpressionNode(globalData) + class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData { + public: + DeleteBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_base(base) , m_subscript(subscript) @@ -851,8 +952,9 @@ }; - class DeleteDotNode : public ExpressionNode { - public: - DeleteDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL - : ExpressionNode(globalData) + class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData { + public: + DeleteDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_base(base) , m_ident(ident) @@ -943,6 +1045,6 @@ class PrefixResolveNode : public PrePostResolveNode { public: - PrefixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper) KJS_FAST_CALL - : PrePostResolveNode(globalData, ident) + PrefixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset) , m_operator(oper) { @@ -958,8 +1060,9 @@ }; - class PrefixBracketNode : public ExpressionNode { - public: - PrefixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper) KJS_FAST_CALL - : ExpressionNode(globalData) + class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData { + public: + PrefixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset) , m_base(base) , m_subscript(subscript) @@ -978,8 +1081,9 @@ }; - class PrefixDotNode : public ExpressionNode { - public: - PrefixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper) KJS_FAST_CALL - : ExpressionNode(globalData) + class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData { + public: + PrefixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset) , m_base(base) , m_ident(ident) @@ -998,8 +1102,9 @@ }; - class PrefixErrorNode : public ExpressionNode { - public: - PrefixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper) KJS_FAST_CALL - : ExpressionNode(globalData) + class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData { + public: + PrefixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_expr(expr) , m_operator(oper) @@ -1283,8 +1388,21 @@ }; - class InstanceOfNode : public BinaryOpNode { + class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData { + public: + ThrowableBinaryOpNode(JSGlobalData* globalData, JSType type, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL + : BinaryOpNode(globalData, type, term1, term2, rightHasAssignments) + { + } + ThrowableBinaryOpNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL + : BinaryOpNode(globalData, term1, term2, rightHasAssignments) + { + } + virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; + }; + + class InstanceOfNode : public ThrowableBinaryOpNode { public: InstanceOfNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL - : BinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments) + : ThrowableBinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments) { } @@ -1295,8 +1413,8 @@ }; - class InNode : public BinaryOpNode { + class InNode : public ThrowableBinaryOpNode { public: InNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL - : BinaryOpNode(globalData, term1, term2, rightHasAssignments) + : ThrowableBinaryOpNode(globalData, term1, term2, rightHasAssignments) { } @@ -1437,8 +1555,9 @@ }; - class ReadModifyResolveNode : public ExpressionNode { - public: - ReadModifyResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL - : ExpressionNode(globalData) + class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData { + public: + ReadModifyResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_ident(ident) , m_right(right) @@ -1461,5 +1580,5 @@ }; - class AssignResolveNode : public ExpressionNode { + class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData { public: AssignResolveNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL @@ -1483,8 +1602,9 @@ }; - class ReadModifyBracketNode : public ExpressionNode { - public: - ReadModifyBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments) KJS_FAST_CALL - : ExpressionNode(globalData) + class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData { + public: + ReadModifyBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableSubExpressionData(divot, startOffset, endOffset) , m_base(base) , m_subscript(subscript) @@ -1510,8 +1630,9 @@ }; - class AssignBracketNode : public ExpressionNode { - public: - AssignBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments) KJS_FAST_CALL - : ExpressionNode(globalData) + class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData { + public: + AssignBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_base(base) , m_subscript(subscript) @@ -1535,8 +1656,9 @@ }; - class AssignDotNode : public ExpressionNode { - public: - AssignDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL - : ExpressionNode(globalData) + class AssignDotNode : public ExpressionNode, public ThrowableExpressionData { + public: + AssignDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_base(base) , m_ident(ident) @@ -1557,8 +1679,9 @@ }; - class ReadModifyDotNode : public ExpressionNode { - public: - ReadModifyDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL - : ExpressionNode(globalData) + class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData { + public: + ReadModifyDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableSubExpressionData(divot, startOffset, endOffset) , m_base(base) , m_ident(ident) @@ -1582,8 +1705,9 @@ }; - class AssignErrorNode : public ExpressionNode { - public: - AssignErrorNode(JSGlobalData* globalData, ExpressionNode* left, Operator oper, ExpressionNode* right) KJS_FAST_CALL - : ExpressionNode(globalData) + class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData { + public: + AssignErrorNode(JSGlobalData* globalData, ExpressionNode* left, Operator oper, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL + : ExpressionNode(globalData) + , ThrowableExpressionData(divot, startOffset, endOffset) , m_left(left) , m_operator(oper) @@ -1837,8 +1961,8 @@ }; - class ForInNode : public StatementNode { + class ForInNode : public StatementNode, public ThrowableExpressionData { public: ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL; - ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL; + ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset) KJS_FAST_CALL; virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; @@ -1854,5 +1978,5 @@ }; - class ContinueNode : public StatementNode { + class ContinueNode : public StatementNode, public ThrowableExpressionData { public: ContinueNode(JSGlobalData* globalData) KJS_FAST_CALL @@ -1874,5 +1998,5 @@ }; - class BreakNode : public StatementNode { + class BreakNode : public StatementNode, public ThrowableExpressionData { public: BreakNode(JSGlobalData* globalData) KJS_FAST_CALL @@ -1894,5 +2018,5 @@ }; - class ReturnNode : public StatementNode { + class ReturnNode : public StatementNode, public ThrowableExpressionData { public: ReturnNode(JSGlobalData* globalData, ExpressionNode* value) KJS_FAST_CALL @@ -1912,8 +2036,10 @@ class WithNode : public StatementNode { public: - WithNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement) KJS_FAST_CALL + WithNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement, uint32_t divot, uint32_t expressionLength) KJS_FAST_CALL : StatementNode(globalData) , m_expr(expr) , m_statement(statement) + , m_divot(divot) + , m_expressionLength(expressionLength) { } @@ -1925,7 +2051,9 @@ RefPtr m_expr; RefPtr m_statement; - }; - - class LabelNode : public StatementNode { + uint32_t m_divot; + uint32_t m_expressionLength; + }; + + class LabelNode : public StatementNode, public ThrowableExpressionData { public: LabelNode(JSGlobalData* globalData, const Identifier& label, StatementNode* statement) KJS_FAST_CALL @@ -1945,5 +2073,5 @@ }; - class ThrowNode : public StatementNode { + class ThrowNode : public StatementNode, public ThrowableExpressionData { public: ThrowNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL @@ -2023,5 +2151,5 @@ VarStack& varStack() { return m_varStack; } FunctionStack& functionStack() { return m_functionStack; } - + protected: VarStack m_varStack; @@ -2037,7 +2165,7 @@ class ProgramNode : public ScopeNode { public: - static ProgramNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL; - - ProgramCodeBlock& code(ScopeChainNode* scopeChain) KJS_FAST_CALL + static ProgramNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, SourceProvider*, bool usesEval, bool needsClosure) KJS_FAST_CALL; + + ProgramCodeBlock& byteCode(ScopeChainNode* scopeChain) KJS_FAST_CALL { if (!m_code) @@ -2047,5 +2175,5 @@ private: - ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL; + ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, SourceProvider*, bool usesEval, bool needsClosure) KJS_FAST_CALL; void generateCode(ScopeChainNode*) KJS_FAST_CALL; @@ -2055,4 +2183,6 @@ Vector m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.) + RefPtr m_sourceProvider; + OwnPtr m_code; }; @@ -2060,7 +2190,7 @@ class EvalNode : public ScopeNode { public: - static EvalNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL; - - EvalCodeBlock& code(ScopeChainNode* scopeChain) KJS_FAST_CALL + static EvalNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, SourceProvider*, bool usesEval, bool needsClosure) KJS_FAST_CALL; + + EvalCodeBlock& byteCode(ScopeChainNode* scopeChain) KJS_FAST_CALL { if (!m_code) @@ -2070,8 +2200,10 @@ private: - EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL; + EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, SourceProvider*, bool usesEval, bool needsClosure) KJS_FAST_CALL; void generateCode(ScopeChainNode*) KJS_FAST_CALL; virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; + + RefPtr m_sourceProvider; OwnPtr m_code; @@ -2080,4 +2212,5 @@ class FunctionBodyNode : public ScopeNode { public: + static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, SourceProvider*, bool usesEval, bool needsClosure) KJS_FAST_CALL; static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL; @@ -2089,5 +2222,5 @@ SymbolTable& symbolTable() { return m_symbolTable; } // FIXME: Remove this - CodeBlock& code(ScopeChainNode* scopeChain) KJS_FAST_CALL + CodeBlock& byteCode(ScopeChainNode* scopeChain) KJS_FAST_CALL { ASSERT(scopeChain); @@ -2097,5 +2230,5 @@ } - CodeBlock& generatedCode() KJS_FAST_CALL + CodeBlock& generatedByteCode() KJS_FAST_CALL { ASSERT(m_code); @@ -2107,5 +2240,4 @@ void setSource(const SourceRange& source) { m_source = source; } UString toSourceString() const KJS_FAST_CALL { return UString("{") + m_source.toString() + UString("}"); } - protected: FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL; Index: trunk/JavaScriptCore/kjs/lexer.h =================================================================== --- trunk/JavaScriptCore/kjs/lexer.h (revision 387) +++ trunk/JavaScriptCore/kjs/lexer.h (revision 404) @@ -134,5 +134,4 @@ State m_state; unsigned int m_position; - RefPtr m_source; const UChar* m_code; @@ -146,5 +145,10 @@ int m_next2; int m_next3; - + + int m_currentOffset; + int m_nextOffset1; + int m_nextOffset2; + int m_nextOffset3; + Vector m_strings; Vector m_identifiers;