Changeset 35245 in webkit for trunk/JavaScriptCore/kjs/nodes.cpp


Ignore:
Timestamp:
Jul 18, 2008, 6:44:24 PM (17 years ago)
Author:
[email protected]
Message:

Bug 18774: SQUIRRELFISH: print meaningful error messages <https://bugs.webkit.org/show_bug.cgi?id=18774>
<rdar://problem/5769353> SQUIRRELFISH: JavaScript error messages are missing informative text

Reviewed by Cameron Zwarich

Add support for decent error messages in JavaScript. This patch achieves this by providing
ensuring the common errors and exceptions have messages that provide the text of expression
that trigger the exception. In addition it attaches a number of properties to the exception
object detailing where in the source the expression came from.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r35230 r35245  
    163163}
    164164
    165 RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
    166 {
     165RegisterID* ThrowableExpressionData::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
     166{
     167    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    167168    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalExec(), msg));
    168169    generator.emitThrow(exception);
     
    170171}
    171172
    172 RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label)
     173RegisterID* ThrowableExpressionData::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label)
    173174{
    174175    UString message = msg;
    175176    substitute(message, label.ustring());
     177    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    176178    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalExec(), message));
    177179    generator.emitThrow(exception);
     
    185187    , m_lastLine(-1)
    186188{
    187     m_line = -1;
    188189}
    189190
     
    289290        return generator.moveToDestinationIfNeeded(dst, local);
    290291    }
    291 
     292   
     293    generator.emitExpressionInfo(m_startOffset + m_ident.size(), m_ident.size(), 0);
    292294    return generator.emitResolve(generator.finalDestination(dst), m_ident);
    293295}
     
    376378    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments, m_subscript->isPure(generator));
    377379    RegisterID* property = generator.emitNode(m_subscript.get());
    378 
     380    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    379381    return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
    380382}
     
    385387{
    386388    RegisterID* base = generator.emitNode(m_base.get());
     389    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    387390    return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
    388391}
     
    401404{
    402405    RegisterID* r0 = generator.emitNode(m_expr.get());
     406    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    403407    return generator.emitConstruct(generator.finalDestination(dst), r0, m_args.get());
    404408}
     
    409413    RegisterID* func = generator.newTemporary();
    410414    generator.emitResolveWithBase(base.get(), func, generator.propertyNames().eval);
    411     return generator.emitCallEval(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get());
     415    return generator.emitCallEval(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
    412416}
    413417
     
    415419{
    416420    RegisterID* func = generator.emitNode(m_expr.get());
    417     return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get());
     421    return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
    418422}
    419423
     
    421425{
    422426    if (RegisterID* local = generator.registerForLocal(m_ident))
    423         return generator.emitCall(generator.finalDestination(dst), local, 0, m_args.get());
     427        return generator.emitCall(generator.finalDestination(dst), local, 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
    424428
    425429    int index = 0;
     
    427431    if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
    428432        RegisterID* func = generator.emitGetScopedVar(generator.newTemporary(), depth, index);
    429         return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get());
     433        return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
    430434    }
    431435
    432436    RefPtr<RegisterID> base = generator.tempDestination(dst);
    433437    RegisterID* func = generator.newTemporary();
     438    int identifierStart = m_divot - m_startOffset;
     439    generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
    434440    generator.emitResolveFunction(base.get(), func, m_ident);
    435     return generator.emitCall(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get());
     441    return generator.emitCall(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
    436442}
    437443
     
    440446    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
    441447    RegisterID* property = generator.emitNode(m_subscript.get());
     448    generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    442449    RegisterID* function = generator.emitGetByVal(generator.newTemporary(), base.get(), property);
    443     return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get());
     450    return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
    444451}
    445452
     
    447454{
    448455    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
     456    generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    449457    RegisterID* function = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
    450     return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get());
     458    return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
    451459}
    452460
     
    492500    }
    493501
     502    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    494503    RefPtr<RegisterID> value = generator.newTemporary();
    495504    RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
     
    511520    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
    512521    RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
     522
     523    generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    513524    RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
    514525    RegisterID* oldValue;
     
    522533        oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
    523534    }
     535    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    524536    generator.emitPutByVal(base.get(), property.get(), value.get());
    525537    return oldValue;
     
    531543{
    532544    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
     545
     546    generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    533547    RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
    534548    RegisterID* oldValue;
     
    542556        oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get());
    543557    }
     558    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    544559    generator.emitPutById(base.get(), m_ident, value.get());
    545560    return oldValue;
     
    560575        return generator.emitLoad(generator.finalDestination(dst), false);
    561576
     577    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    562578    RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
    563579    return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
     
    570586    RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
    571587    RefPtr<RegisterID> r1 = generator.emitNode(m_subscript.get());
     588
     589    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    572590    return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
    573591}
     
    578596{
    579597    RegisterID* r0 = generator.emitNode(m_base.get());
     598
     599    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    580600    return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
    581601}
     
    657677    }
    658678
     679    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    659680    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
    660681    RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
     
    671692    RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
    672693    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
     694
     695    generator.emitExpressionInfo(m_divot + m_subexpressionDivotOffset, m_subexpressionStartOffset, m_endOffset - m_subexpressionDivotOffset);
    673696    RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
    674697    if (m_operator == OpPlusPlus)
     
    676699    else
    677700        generator.emitPreDec(value);
     701    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    678702    generator.emitPutByVal(base.get(), property.get(), value);
    679703    return generator.moveToDestinationIfNeeded(dst, propDst.get());
     
    686710    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
    687711    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
     712
     713    generator.emitExpressionInfo(m_divot + m_subexpressionDivotOffset, m_subexpressionStartOffset, m_endOffset - m_subexpressionDivotOffset);
    688714    RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
    689715    if (m_operator == OpPlusPlus)
     
    691717    else
    692718        generator.emitPreDec(value);
     719    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    693720    generator.emitPutById(base.get(), m_ident, value);
    694721    return generator.moveToDestinationIfNeeded(dst, propDst.get());
     
    724751    RegisterID* src2 = generator.emitNode(m_term2.get());
    725752    return generator.emitBinaryOp(opcode(), generator.finalDestination(dst, src1.get()), src2, src1.get());
     753}
     754
     755RegisterID* ThrowableBinaryOpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
     756{
     757    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_term1.get(), m_rightHasAssignments, m_term2->isPure(generator));
     758    RegisterID* src2 = generator.emitNode(m_term2.get());
     759    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
     760    return generator.emitBinaryOp(opcode(), generator.finalDestination(dst, src1.get()), src1.get(), src2);
    726761}
    727762
     
    847882
    848883    RefPtr<RegisterID> src1 = generator.tempDestination(dst);
     884    generator.emitExpressionInfo(m_divot - m_startOffset + m_ident.size(), m_ident.size(), 0);
    849885    RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
    850886    RegisterID* src2 = generator.emitNode(m_right.get());
     887    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    851888    RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator);
    852889    return generator.emitPutById(base.get(), m_ident, result);
     
    879916        dst = 0;
    880917    RegisterID* value = generator.emitNode(dst, m_right.get());
     918    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    881919    return generator.emitPutById(base.get(), m_ident, value);
    882920}
     
    889927    RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
    890928    RegisterID* result = generator.emitNode(value.get(), m_right.get());
     929    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    891930    generator.emitPutById(base.get(), m_ident, result);
    892931    return generator.moveToDestinationIfNeeded(dst, result);
     
    898937{
    899938    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
     939
     940    generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    900941    RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
    901942    RegisterID* change = generator.emitNode(m_right.get());
    902943    RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
     944
     945    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    903946    return generator.emitPutById(base.get(), m_ident, updatedValue);
    904947}
     
    919962    RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
    920963    RegisterID* result = generator.emitNode(value.get(), m_right.get());
     964
     965    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    921966    generator.emitPutByVal(base.get(), property.get(), result);
    922967    return generator.moveToDestinationIfNeeded(dst, result);
     
    928973    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
    929974
     975    generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    930976    RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
    931977    RegisterID* change = generator.emitNode(m_right.get());
    932978    RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
    933979
     980    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    934981    generator.emitPutByVal(base.get(), property.get(), updatedValue);
    935982
     
    11971244}
    11981245
    1199 ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement)
     1246ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
    12001247    : StatementNode(globalData)
    12011248    , m_ident(ident)
    1202     , m_lexpr(new ResolveNode(globalData, ident))
     1249    , m_lexpr(new ResolveNode(globalData, ident, divot - startOffset))
    12031250    , m_expr(expr)
    12041251    , m_statement(statement)
    12051252    , m_identIsVarDecl(true)
    12061253{
    1207     if (in)
    1208         m_init = new AssignResolveNode(globalData, ident, in, true);
     1254    if (in) {
     1255        AssignResolveNode* node = new AssignResolveNode(globalData, ident, in, true);
     1256        node->setExceptionSourceRange(divot, divot - startOffset, endOffset - divot);
     1257        m_init = node;
     1258    }
    12091259    // for( var foo = bar in baz )
    12101260}
     
    12301280            RefPtr<RegisterID> protect = propertyName;
    12311281            RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
     1282
     1283            generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
    12321284            generator.emitPutById(base, ident, propertyName);
    12331285        }
     
    12381290        RefPtr<RegisterID> protect = propertyName;
    12391291        RegisterID* base = generator.emitNode(assignNode->base());
     1292
     1293        generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
    12401294        generator.emitPutById(base, ident, propertyName);
    12411295    } else {
     
    12461300        RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
    12471301        RegisterID* subscript = generator.emitNode(assignNode->subscript());
     1302       
     1303        generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset());
    12481304        generator.emitPutByVal(base.get(), subscript, propertyName);
    12491305    }   
     
    13301386{
    13311387    RefPtr<RegisterID> scope = generator.emitNode(m_expr.get()); // scope must be protected until popped
     1388    generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
    13321389    generator.emitPushScope(scope.get());
    13331390    RegisterID* result = generator.emitNode(dst, m_statement.get());
     
    14101467    if (generator.jumpContextForBreak(m_label))
    14111468        return emitThrowError(generator, SyntaxError, "Duplicated label %s found.", m_label);
    1412    
     1469
    14131470    RefPtr<LabelID> l0 = generator.newLabel();
    14141471    m_labelStack.push(m_label);
     
    14281485RegisterID* ThrowNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    14291486{
    1430     generator.emitThrow(generator.emitNode(dst, m_expr.get()));
     1487    RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
     1488    generator.emitExpressionInfo(m_divot, m_startOffset, m_endOffset);
     1489    generator.emitThrow(expr.get());
    14311490    return dst;
    14321491}
     
    15071566// ------------------------------ ProgramNode -----------------------------
    15081567
    1509 ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
     1568ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure)
    15101569    : ScopeNode(globalData, children, varStack, funcStack, usesEval, needsClosure)
    1511 {
    1512 }
    1513 
    1514 ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
    1515 {
    1516     return new ProgramNode(globalData, children, varStack, funcStack, usesEval, needsClosure);
     1570    , m_sourceProvider(sourceProvider)
     1571{
     1572}
     1573
     1574ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure)
     1575{
     1576    return new ProgramNode(globalData, children, varStack, funcStack, sourceProvider, usesEval, needsClosure);
    15171577}
    15181578
    15191579// ------------------------------ EvalNode -----------------------------
    15201580
    1521 EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
     1581EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure)
    15221582    : ScopeNode(globalData, children, varStack, funcStack, usesEval, needsClosure)
     1583    , m_sourceProvider(sourceProvider)
    15231584{
    15241585}
     
    15431604
    15441605    SymbolTable symbolTable;
    1545 
    1546     m_code.set(new EvalCodeBlock(this, globalObject));
     1606    ASSERT(m_sourceProvider);
     1607    m_code.set(new EvalCodeBlock(this, globalObject, m_sourceProvider));
    15471608
    15481609    CodeGenerator generator(this, globalObject->debugger(), scopeChain, &symbolTable, m_code.get());
     
    15501611}
    15511612
    1552 EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
    1553 {
    1554     return new EvalNode(globalData, children, varStack, funcStack, usesEval, needsClosure);
     1613EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider* sourceProvider, bool usesEval, bool needsClosure)
     1614{
     1615    return new EvalNode(globalData, children, varStack, funcStack, sourceProvider, usesEval, needsClosure);
    15551616}
    15561617
     
    15731634}
    15741635
     1636FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, SourceProvider*, bool usesEval, bool needsClosure)
     1637{
     1638    return new FunctionBodyNode(globalData, children, varStack, funcStack, usesEval, needsClosure);
     1639}
     1640
    15751641void FunctionBodyNode::generateCode(ScopeChainNode* sc)
    15761642{
     
    15781644    JSGlobalObject* globalObject = scopeChain.globalObject();
    15791645
    1580     m_code.set(new CodeBlock(this, FunctionCode));
     1646    ASSERT(m_source.sourceProvider());
     1647    m_code.set(new CodeBlock(this, FunctionCode, m_source.sourceProvider(), m_source.startOffset()));
    15811648
    15821649    CodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_symbolTable, m_code.get());
     
    16141681    JSGlobalObject* globalObject = scopeChain.globalObject();
    16151682   
    1616     m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject));
     1683    ASSERT(m_sourceProvider);
     1684    m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, m_sourceProvider));
    16171685   
    16181686    CodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get(), m_varStack, m_functionStack);
Note: See TracChangeset for help on using the changeset viewer.