diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2019-07-04 13:18:55 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-07-04 16:03:36 +0200 |
commit | 40ded579bd977dc8fc41aaa1cdfca36822d14fc6 (patch) | |
tree | 04069b8c15c05b2625dd45c869b45c37a6c62b3a /src/qml/compiler | |
parent | c1546f8b7005a7cc0ed25f9dc1c762a9c929a25b (diff) |
Simplify codegen error handling
There can only ever be one error, either a syntax error or a reference
error. We record the error type as we want to get rid of the virtual
throw<X>Error methods in favor of an explicit compilation result.
Change-Id: Ie228490aad8efb7885083f6485f931299567f54c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 289 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen_p.h | 19 |
3 files changed, 156 insertions, 154 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 7ed0a01cb0..5d3d055db3 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1836,7 +1836,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil } scan.leaveEnvironment(); - if (hasError) + if (hasError()) return QVector<int>(); _context = nullptr; diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 79eac5dbcc..453963c1dd 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -98,7 +98,6 @@ Codegen::Codegen(QV4::Compiler::JSUnitGenerator *jsUnitGenerator, bool strict) , jsUnitGenerator(jsUnitGenerator) , _strictMode(strict) , _fileNameIsUrl(false) - , hasError(false) { jsUnitGenerator->codeGeneratorName = QStringLiteral("moth"); pushExpr(); @@ -191,7 +190,7 @@ void Codegen::generateFromProgram(const QString &fileName, ScanFunctions scan(this, sourceCode, contextType); scan(node); - if (hasError) + if (hasError()) return; defineFunction(QStringLiteral("%entry"), node, nullptr, node->statements); @@ -215,7 +214,7 @@ void Codegen::generateFromModule(const QString &fileName, ScanFunctions scan(this, sourceCode, ContextType::ESModule); scan(node); - if (hasError) + if (hasError()) return; { @@ -265,7 +264,7 @@ Context *Codegen::enterBlock(Node *node) Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr) { - if (hasError) + if (hasError()) return exprResult(); if (expr.isConstant()) { @@ -416,7 +415,7 @@ void Codegen::statement(ExpressionNode *ast) qSwap(_volatileMemoryLocations, vLocs); Reference result = popResult(); - if (hasError) + if (hasError()) return; if (result.loadTriggersSideEffect()) result.loadInAccumulator(); // triggers side effects @@ -426,7 +425,7 @@ void Codegen::statement(ExpressionNode *ast) void Codegen::condition(ExpressionNode *ast, const BytecodeGenerator::Label *iftrue, const BytecodeGenerator::Label *iffalse, bool trueBlockFollowsCondition) { - if (hasError) + if (hasError()) return; if (!ast) @@ -436,7 +435,7 @@ void Codegen::condition(ExpressionNode *ast, const BytecodeGenerator::Label *ift accept(ast); Result r = popExpr(); - if (hasError) + if (hasError()) return; if (r.format() == ex) { @@ -590,7 +589,7 @@ Codegen::Reference Codegen::targetForPatternElement(AST::PatternElement *p) if (!p->bindingTarget || p->destructuringPattern()) return Codegen::Reference::fromStackSlot(this); Reference lhs = expression(p->bindingTarget); - if (hasError) + if (hasError()) return lhs; if (!lhs.isLValue()) { throwReferenceError(p->bindingTarget->firstSourceLocation(), QStringLiteral("Binding target is not a reference.")); @@ -608,14 +607,14 @@ void Codegen::initializeAndDestructureBindingElement(AST::PatternElement *e, con Reference varToStore = targetForPatternElement(e); if (isDefinition) varToStore.isReferenceToConst = false; - if (hasError) + if (hasError()) return; if (e->initializer) { if (!baseRef.isValid()) { // assignment Reference expr = expression(e->initializer); - if (hasError) + if (hasError()) return; expr.loadInAccumulator(); varToStore.storeConsumeAccumulator(); @@ -623,7 +622,7 @@ void Codegen::initializeAndDestructureBindingElement(AST::PatternElement *e, con baseRef.loadInAccumulator(); BytecodeGenerator::Jump jump = bytecodeGenerator->jumpNotUndefined(); Reference expr = expression(e->initializer); - if (hasError) { + if (hasError()) { jump.link(); return; } @@ -634,7 +633,7 @@ void Codegen::initializeAndDestructureBindingElement(AST::PatternElement *e, con baseRef.loadInAccumulator(); BytecodeGenerator::Jump jump = bytecodeGenerator->jumpNotUndefined(); Reference expr = expression(e->initializer); - if (hasError) { + if (hasError()) { jump.link(); return; } @@ -671,7 +670,7 @@ Codegen::Reference Codegen::referenceForPropertyName(const Codegen::Reference &o Reference property; if (cname) { Reference computedName = expression(cname->expression); - if (hasError) + if (hasError()) return Reference(); computedName = computedName.storeOnStack(); property = Reference::fromSubscript(object, computedName).asLValue(); @@ -694,10 +693,10 @@ void Codegen::destructurePropertyList(const Codegen::Reference &object, PatternP PatternProperty *p = it->property; RegisterScope scope(this); Reference property = referenceForPropertyName(object, p->name); - if (hasError) + if (hasError()) return; initializeAndDestructureBindingElement(p, property, isDefinition); - if (hasError) + if (hasError()) return; } } @@ -753,7 +752,7 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle next.done = iteratorDone.stackSlot(); bytecodeGenerator->addInstruction(next); initializeAndDestructureBindingElement(e, iteratorValue, isDefinition); - if (hasError) + if (hasError()) return; } } @@ -1017,7 +1016,7 @@ bool Codegen::visit(ClassExpression *ast) if (ast->heritage) { bytecodeGenerator->setLocation(ast->heritage->firstSourceLocation()); Reference r = expression(ast->heritage); - if (hasError) + if (hasError()) return false; r.storeOnStack(heritage.stackSlot()); } else { @@ -1036,7 +1035,7 @@ bool Codegen::visit(ClassExpression *ast) RegisterScope scope(this); bytecodeGenerator->setLocation(cname->firstSourceLocation()); Reference computedName = expression(cname->expression); - if (hasError) + if (hasError()) return false; computedName.storeOnStack(member->isStatic ? currentStaticName++ : currentNonStaticName++); } @@ -1069,7 +1068,7 @@ bool Codegen::visit(ClassDeclaration *ast) bool Codegen::visit(Expression *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -1082,7 +1081,7 @@ bool Codegen::visit(Expression *ast) bool Codegen::visit(ArrayPattern *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -1104,7 +1103,7 @@ bool Codegen::visit(ArrayPattern *ast) } else { RegisterScope scope(this); Reference r = expression(arg); - if (hasError) + if (hasError()) return; (void) r.storeOnStack(temp); } @@ -1122,7 +1121,7 @@ bool Codegen::visit(ArrayPattern *ast) continue; push(e->initializer); - if (hasError) + if (hasError()) return false; } @@ -1183,7 +1182,7 @@ bool Codegen::visit(ArrayPattern *ast) { RegisterScope innerScope(this); Reference expr = expression(it->element->initializer); - if (hasError) + if (hasError()) return false; expr.loadInAccumulator(); @@ -1224,7 +1223,7 @@ bool Codegen::visit(ArrayPattern *ast) } else { RegisterScope innerScope(this); Reference expr = expression(it->element->initializer); - if (hasError) + if (hasError()) return false; expr.loadInAccumulator(); @@ -1242,12 +1241,12 @@ bool Codegen::visit(ArrayPattern *ast) bool Codegen::visit(ArrayMemberExpression *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); Reference base = expression(ast->base); - if (hasError) + if (hasError()) return false; if (base.isSuper()) { Reference index = expression(ast->expression).storeOnStack(); @@ -1255,7 +1254,7 @@ bool Codegen::visit(ArrayMemberExpression *ast) return false; } base = base.storeOnStack(); - if (hasError) + if (hasError()) return false; if (AST::StringLiteral *str = AST::cast<AST::StringLiteral *>(ast->expression)) { QString s = str->value.toString(); @@ -1269,7 +1268,7 @@ bool Codegen::visit(ArrayMemberExpression *ast) return false; } Reference index = expression(ast->expression); - if (hasError) + if (hasError()) return false; setExprResult(Reference::fromSubscript(base, index)); return false; @@ -1296,7 +1295,7 @@ static QSOperator::Op baseOp(int op) bool Codegen::visit(BinaryExpression *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -1314,7 +1313,7 @@ bool Codegen::visit(BinaryExpression *ast) auto endif = bytecodeGenerator->newLabel(); Reference left = expression(ast->left); - if (hasError) + if (hasError()) return false; left.loadInAccumulator(); @@ -1324,7 +1323,7 @@ bool Codegen::visit(BinaryExpression *ast) blockTailCalls.unblock(); Reference right = expression(ast->right); - if (hasError) + if (hasError()) return false; right.loadInAccumulator(); @@ -1345,7 +1344,7 @@ bool Codegen::visit(BinaryExpression *ast) auto endif = bytecodeGenerator->newLabel(); Reference left = expression(ast->left); - if (hasError) + if (hasError()) return false; left.loadInAccumulator(); @@ -1355,7 +1354,7 @@ bool Codegen::visit(BinaryExpression *ast) blockTailCalls.unblock(); Reference right = expression(ast->right); - if (hasError) + if (hasError()) return false; right.loadInAccumulator(); @@ -1368,7 +1367,7 @@ bool Codegen::visit(BinaryExpression *ast) if (AST::Pattern *p = ast->left->patternCast()) { RegisterScope scope(this); Reference right = expression(ast->right); - if (hasError) + if (hasError()) return false; right = right.storeOnStack(); destructurePattern(p, right); @@ -1379,7 +1378,7 @@ bool Codegen::visit(BinaryExpression *ast) return false; } Reference left = expression(ast->left); - if (hasError) + if (hasError()) return false; if (!left.isLValue()) { @@ -1391,7 +1390,7 @@ bool Codegen::visit(BinaryExpression *ast) return false; blockTailCalls.unblock(); Reference r = expression(ast->right); - if (hasError) + if (hasError()) return false; r.loadInAccumulator(); if (exprAccept(nx)) @@ -1402,7 +1401,7 @@ bool Codegen::visit(BinaryExpression *ast) } Reference left = expression(ast->left); - if (hasError) + if (hasError()) return false; switch (ast->op) { @@ -1436,7 +1435,7 @@ bool Codegen::visit(BinaryExpression *ast) Reference tempLeft = left.storeOnStack(); Reference right = expression(ast->right); - if (hasError) + if (hasError()) return false; binopHelper(baseOp(ast->op), tempLeft, right).loadInAccumulator(); @@ -1450,7 +1449,7 @@ bool Codegen::visit(BinaryExpression *ast) case QSOperator::BitXor: if (left.isConstant()) { Reference right = expression(ast->right); - if (hasError) + if (hasError()) return false; setExprResult(binopHelper(static_cast<QSOperator::Op>(ast->op), right, left)); break; @@ -1483,7 +1482,7 @@ bool Codegen::visit(BinaryExpression *ast) left = left.storeOnStack(); // force any loads of the lhs, so the rhs won't clobber it right = expression(ast->right); } - if (hasError) + if (hasError()) return false; setExprResult(binopHelper(static_cast<QSOperator::Op>(ast->op), left, right)); @@ -1867,7 +1866,7 @@ Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Refe bool Codegen::visit(CallExpression *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -1875,7 +1874,7 @@ bool Codegen::visit(CallExpression *ast) Reference base = expression(ast->base); - if (hasError) + if (hasError()) return false; switch (base.type) { case Reference::Member: @@ -1898,7 +1897,7 @@ bool Codegen::visit(CallExpression *ast) int functionObject = bytecodeGenerator->newRegister(); auto calldata = pushArgs(ast->arguments); - if (hasError) + if (hasError()) return false; blockTailCalls.unblock(); @@ -2046,7 +2045,7 @@ Codegen::Arguments Codegen::pushArgs(ArgumentList *args) } RegisterScope scope(this); Reference e = expression(it->expression); - if (hasError) + if (hasError()) break; if (!argc && !it->next && !hasSpread) { // avoid copy for functions taking a single argument @@ -2075,7 +2074,7 @@ Codegen::Arguments Codegen::pushTemplateArgs(TemplateLiteral *args) for (TemplateLiteral *it = args; it && it->expression; it = it->next) { RegisterScope scope(this); Reference e = expression(it->expression); - if (hasError) + if (hasError()) break; (void) e.storeOnStack(calldata + argc); ++argc; @@ -2086,7 +2085,7 @@ Codegen::Arguments Codegen::pushTemplateArgs(TemplateLiteral *args) bool Codegen::visit(ConditionalExpression *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -2100,14 +2099,14 @@ bool Codegen::visit(ConditionalExpression *ast) iftrue.link(); Reference ok = expression(ast->ok); - if (hasError) + if (hasError()) return false; ok.loadInAccumulator(); BytecodeGenerator::Jump jump_endif = bytecodeGenerator->jump(); iffalse.link(); Reference ko = expression(ast->ko); - if (hasError) { + if (hasError()) { jump_endif.link(); // dummy link, to prevent assert in Jump destructor from triggering return false; } @@ -2121,13 +2120,13 @@ bool Codegen::visit(ConditionalExpression *ast) bool Codegen::visit(DeleteExpression *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); TailCallBlocker blockTailCalls(this); Reference expr = expression(ast->expression); - if (hasError) + if (hasError()) return false; switch (expr.type) { @@ -2192,7 +2191,7 @@ bool Codegen::visit(DeleteExpression *ast) bool Codegen::visit(FalseLiteral *) { - if (hasError) + if (hasError()) return false; setExprResult(Reference::fromConst(this, QV4::Encode(false))); @@ -2201,7 +2200,7 @@ bool Codegen::visit(FalseLiteral *) bool Codegen::visit(SuperLiteral *) { - if (hasError) + if (hasError()) return false; setExprResult(Reference::fromSuper(this)); @@ -2210,7 +2209,7 @@ bool Codegen::visit(SuperLiteral *) bool Codegen::visit(FieldMemberExpression *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -2233,7 +2232,7 @@ bool Codegen::visit(FieldMemberExpression *ast) } Reference base = expression(ast->base); - if (hasError) + if (hasError()) return false; if (base.isSuper()) { Instruction::LoadRuntimeString load; @@ -2249,7 +2248,7 @@ bool Codegen::visit(FieldMemberExpression *ast) bool Codegen::visit(TaggedTemplate *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -2258,7 +2257,7 @@ bool Codegen::visit(TaggedTemplate *ast) bool Codegen::handleTaggedTemplate(Reference base, TaggedTemplate *ast) { - if (hasError) + if (hasError()) return false; int functionObject = -1, thisObject = -1; @@ -2282,7 +2281,7 @@ bool Codegen::handleTaggedTemplate(Reference base, TaggedTemplate *ast) int templateObjectTemp = Reference::fromAccumulator(this).storeOnStack().stackSlot(); Q_UNUSED(templateObjectTemp); auto calldata = pushTemplateArgs(ast->templateLiteral); - if (hasError) + if (hasError()) return false; ++calldata.argc; Q_ASSERT(calldata.argv == templateObjectTemp + 1); @@ -2311,7 +2310,7 @@ void Codegen::createTemplateObject(TemplateLiteral *t) bool Codegen::visit(FunctionExpression *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -2319,7 +2318,7 @@ bool Codegen::visit(FunctionExpression *ast) RegisterScope scope(this); int function = defineFunction(ast->name.toString(), ast, ast->formals, ast->body); - if (hasError) + if (hasError()) return false; loadClosure(function); setExprResult(Reference::fromAccumulator(this)); @@ -2375,7 +2374,7 @@ void Codegen::loadClosure(int closureId) bool Codegen::visit(IdentifierExpression *ast) { - if (hasError) + if (hasError()) return false; setExprResult(referenceForName(ast->name.toString(), false, ast->firstSourceLocation())); @@ -2384,7 +2383,7 @@ bool Codegen::visit(IdentifierExpression *ast) bool Codegen::visit(NestedExpression *ast) { - if (hasError) + if (hasError()) return false; accept(ast->expression); @@ -2403,7 +2402,7 @@ void Codegen::handleConstruct(const Reference &base, ArgumentList *arguments) } auto calldata = pushArgs(arguments); - if (hasError) + if (hasError()) return; if (base.isSuper()) @@ -2433,14 +2432,14 @@ void Codegen::handleConstruct(const Reference &base, ArgumentList *arguments) bool Codegen::visit(NewExpression *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); TailCallBlocker blockTailCalls(this); Reference base = expression(ast->expression); - if (hasError) + if (hasError()) return false; if (base.isSuper()) { throwSyntaxError(ast->expression->firstSourceLocation(), QStringLiteral("Cannot use new with super.")); @@ -2453,14 +2452,14 @@ bool Codegen::visit(NewExpression *ast) bool Codegen::visit(NewMemberExpression *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); TailCallBlocker blockTailCalls(this); Reference base = expression(ast->base); - if (hasError) + if (hasError()) return false; if (base.isSuper()) { throwSyntaxError(ast->base->firstSourceLocation(), QStringLiteral("Cannot use new with super.")); @@ -2473,7 +2472,7 @@ bool Codegen::visit(NewMemberExpression *ast) bool Codegen::visit(NotExpression *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -2483,7 +2482,7 @@ bool Codegen::visit(NotExpression *ast) bool Codegen::visit(NullExpression *) { - if (hasError) + if (hasError()) return false; if (exprAccept(cx)) @@ -2496,7 +2495,7 @@ bool Codegen::visit(NullExpression *) bool Codegen::visit(NumericLiteral *ast) { - if (hasError) + if (hasError()) return false; setExprResult(Reference::fromConst(this, QV4::Encode::smallestNumber(ast->value))); @@ -2505,7 +2504,7 @@ bool Codegen::visit(NumericLiteral *ast) bool Codegen::visit(ObjectPattern *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -2541,7 +2540,7 @@ bool Codegen::visit(ObjectPattern *ast) { RegisterScope innerScope(this); Reference value = expression(p->initializer, name); - if (hasError) + if (hasError()) return false; value.loadInAccumulator(); } @@ -2568,7 +2567,7 @@ bool Codegen::visit(ObjectPattern *ast) if (cname) { RegisterScope innerScope(this); Reference name = expression(cname->expression); - if (hasError) + if (hasError()) return false; name.loadInAccumulator(); } else { @@ -2593,12 +2592,12 @@ bool Codegen::visit(ObjectPattern *ast) FunctionExpression *f = p->initializer->asFunctionDefinition(); Q_ASSERT(f); int function = defineFunction(f->name.toString(), f, f->formals, f->body); - if (hasError) + if (hasError()) return false; Reference::fromConst(this, Encode(function)).loadInAccumulator(); } else { Reference value = expression(p->initializer); - if (hasError) + if (hasError()) return false; value.loadInAccumulator(); } @@ -2617,11 +2616,11 @@ bool Codegen::visit(ObjectPattern *ast) bool Codegen::visit(PostDecrementExpression *ast) { - if (hasError) + if (hasError()) return false; Reference expr = expression(ast->base); - if (hasError) + if (hasError()) return false; if (!expr.isLValue()) { throwReferenceError(ast->base->lastSourceLocation(), QStringLiteral("Invalid left-hand side expression in postfix operation")); @@ -2637,11 +2636,11 @@ bool Codegen::visit(PostDecrementExpression *ast) bool Codegen::visit(PostIncrementExpression *ast) { - if (hasError) + if (hasError()) return false; Reference expr = expression(ast->base); - if (hasError) + if (hasError()) return false; if (!expr.isLValue()) { throwReferenceError(ast->base->lastSourceLocation(), QStringLiteral("Invalid left-hand side expression in postfix operation")); @@ -2655,11 +2654,11 @@ bool Codegen::visit(PostIncrementExpression *ast) } bool Codegen::visit(PreDecrementExpression *ast) -{ if (hasError) +{ if (hasError()) return false; Reference expr = expression(ast->expression); - if (hasError) + if (hasError()) return false; if (!expr.isLValue()) { throwReferenceError(ast->expression->lastSourceLocation(), QStringLiteral("Prefix ++ operator applied to value that is not a reference.")); @@ -2674,11 +2673,11 @@ bool Codegen::visit(PreDecrementExpression *ast) bool Codegen::visit(PreIncrementExpression *ast) { - if (hasError) + if (hasError()) return false; Reference expr = expression(ast->expression); - if (hasError) + if (hasError()) return false; if (!expr.isLValue()) { throwReferenceError(ast->expression->lastSourceLocation(), QStringLiteral("Prefix ++ operator applied to value that is not a reference.")); @@ -2693,7 +2692,7 @@ bool Codegen::visit(PreIncrementExpression *ast) bool Codegen::visit(RegExpLiteral *ast) { - if (hasError) + if (hasError()) return false; auto r = Reference::fromStackSlot(this); @@ -2709,7 +2708,7 @@ bool Codegen::visit(RegExpLiteral *ast) bool Codegen::visit(StringLiteral *ast) { - if (hasError) + if (hasError()) return false; auto r = Reference::fromAccumulator(this); @@ -2724,7 +2723,7 @@ bool Codegen::visit(StringLiteral *ast) bool Codegen::visit(TemplateLiteral *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -2741,7 +2740,7 @@ bool Codegen::visit(TemplateLiteral *ast) bytecodeGenerator->addInstruction(store); Reference expr = expression(ast->expression); - if (hasError) + if (hasError()) return false; if (ast->next) { @@ -2771,7 +2770,7 @@ bool Codegen::visit(TemplateLiteral *ast) bool Codegen::visit(ThisExpression *) { - if (hasError) + if (hasError()) return false; if (_context->isArrowFunction) { @@ -2786,7 +2785,7 @@ bool Codegen::visit(ThisExpression *) bool Codegen::visit(TildeExpression *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -2796,7 +2795,7 @@ bool Codegen::visit(TildeExpression *ast) bool Codegen::visit(TrueLiteral *) { - if (hasError) + if (hasError()) return false; setExprResult(Reference::fromConst(this, QV4::Encode(true))); @@ -2805,14 +2804,14 @@ bool Codegen::visit(TrueLiteral *) bool Codegen::visit(TypeOfExpression *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); TailCallBlocker blockTailCalls(this); Reference expr = expression(ast->expression); - if (hasError) + if (hasError()) return false; if (expr.type == Reference::Name) { @@ -2832,7 +2831,7 @@ bool Codegen::visit(TypeOfExpression *ast) bool Codegen::visit(UnaryMinusExpression *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -2842,7 +2841,7 @@ bool Codegen::visit(UnaryMinusExpression *ast) bool Codegen::visit(UnaryPlusExpression *ast) { - if (hasError) + if (hasError()) return false; TailCallBlocker blockTailCalls(this); @@ -2852,7 +2851,7 @@ bool Codegen::visit(UnaryPlusExpression *ast) bool Codegen::visit(VoidExpression *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -2865,7 +2864,7 @@ bool Codegen::visit(VoidExpression *ast) bool Codegen::visit(FunctionDeclaration * ast) { - if (hasError) + if (hasError()) return false; // no need to block tail calls: the function body isn't visited here. @@ -2887,7 +2886,7 @@ bool Codegen::visit(YieldExpression *ast) RegisterScope scope(this); TailCallBlocker blockTailCalls(this); Reference expr = ast->expression ? expression(ast->expression) : Reference::fromConst(this, Encode::undefined()); - if (hasError) + if (hasError()) return false; Reference acc = Reference::fromAccumulator(this); @@ -3065,7 +3064,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, } else { if (e->bindingTarget || e->initializer) { initializeAndDestructureBindingElement(e, arg); - if (hasError) + if (hasError()) break; } } @@ -3081,7 +3080,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, statementList(body); - if (!hasError) { + if (!hasError()) { bytecodeGenerator->setLocation(ast->lastSourceLocation()); _context->emitBlockFooter(this); @@ -3128,7 +3127,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, bool Codegen::visit(Block *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -3140,7 +3139,7 @@ bool Codegen::visit(Block *ast) bool Codegen::visit(BreakStatement *ast) { - if (hasError) + if (hasError()) return false; // no need to block tail calls here: children aren't visited @@ -3165,7 +3164,7 @@ bool Codegen::visit(BreakStatement *ast) bool Codegen::visit(ContinueStatement *ast) { - if (hasError) + if (hasError()) return false; // no need to block tail calls here: children aren't visited @@ -3198,7 +3197,7 @@ bool Codegen::visit(DebuggerStatement *) bool Codegen::visit(DoWhileStatement *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -3243,7 +3242,7 @@ bool Codegen::visit(EmptyStatement *) bool Codegen::visit(ExpressionStatement *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -3251,7 +3250,7 @@ bool Codegen::visit(ExpressionStatement *ast) if (requiresReturnValue) { Reference e = expression(ast->expression); - if (hasError) + if (hasError()) return false; (void) e.storeOnStack(_returnAddress); } else { @@ -3262,7 +3261,7 @@ bool Codegen::visit(ExpressionStatement *ast) bool Codegen::visit(ForEachStatement *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -3278,7 +3277,7 @@ bool Codegen::visit(ForEachStatement *ast) RegisterScope innerScope(this); ControlFlowBlock controlFlow(this, ast); Reference expr = expression(ast->expression); - if (hasError) + if (hasError()) return false; expr.loadInAccumulator(); @@ -3321,7 +3320,7 @@ bool Codegen::visit(ForEachStatement *ast) destructurePattern(p, lhsValue); } else { Reference lhs = expression(e); - if (hasError) + if (hasError()) goto error; if (!lhs.isLValue()) { throwReferenceError(e->firstSourceLocation(), QStringLiteral("Invalid left-hand side expression for 'in' expression")); @@ -3333,7 +3332,7 @@ bool Codegen::visit(ForEachStatement *ast) } } else if (PatternElement *p = AST::cast<PatternElement *>(ast->lhs)) { initializeAndDestructureBindingElement(p, lhsValue, /*isDefinition =*/ true); - if (hasError) + if (hasError()) goto error; } else { Q_UNREACHABLE(); @@ -3359,7 +3358,7 @@ bool Codegen::visit(ForEachStatement *ast) bool Codegen::visit(ForStatement *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -3403,7 +3402,7 @@ bool Codegen::visit(ForStatement *ast) bool Codegen::visit(IfStatement *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -3435,7 +3434,7 @@ bool Codegen::visit(IfStatement *ast) bool Codegen::visit(LabelledStatement *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -3483,7 +3482,7 @@ void Codegen::emitReturn(const Reference &expr) bool Codegen::visit(ReturnStatement *ast) { - if (hasError) + if (hasError()) return false; if (_functionContext->contextType != ContextType::Function && _functionContext->contextType != ContextType::Binding) { @@ -3493,7 +3492,7 @@ bool Codegen::visit(ReturnStatement *ast) Reference expr; if (ast->expression) { expr = expression(ast->expression); - if (hasError) + if (hasError()) return false; } else { expr = Reference::fromConst(this, Encode::undefined()); @@ -3506,7 +3505,7 @@ bool Codegen::visit(ReturnStatement *ast) bool Codegen::visit(SwitchStatement *ast) { - if (hasError) + if (hasError()) return false; if (requiresReturnValue) @@ -3519,7 +3518,7 @@ bool Codegen::visit(SwitchStatement *ast) BytecodeGenerator::Label switchEnd = bytecodeGenerator->newLabel(); Reference lhs = expression(ast->expression); - if (hasError) + if (hasError()) return false; lhs = lhs.storeOnStack(); @@ -3538,7 +3537,7 @@ bool Codegen::visit(SwitchStatement *ast) for (CaseClauses *it = ast->block->clauses; it; it = it->next) { CaseClause *clause = it->clause; Reference rhs = expression(clause->expression); - if (hasError) + if (hasError()) return false; rhs.loadInAccumulator(); bytecodeGenerator->jumpStrictEqual(lhs.stackSlot(), blockMap.value(clause)); @@ -3547,7 +3546,7 @@ bool Codegen::visit(SwitchStatement *ast) for (CaseClauses *it = ast->block->moreClauses; it; it = it->next) { CaseClause *clause = it->clause; Reference rhs = expression(clause->expression); - if (hasError) + if (hasError()) return false; rhs.loadInAccumulator(); bytecodeGenerator->jumpStrictEqual(lhs.stackSlot(), blockMap.value(clause)); @@ -3593,14 +3592,14 @@ bool Codegen::visit(SwitchStatement *ast) bool Codegen::visit(ThrowStatement *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); TailCallBlocker blockTailCalls(this); Reference expr = expression(ast->expression); - if (hasError) + if (hasError()) return false; expr.loadInAccumulator(); @@ -3637,7 +3636,7 @@ void Codegen::handleTryFinally(TryStatement *ast) bool Codegen::visit(TryStatement *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); @@ -3653,7 +3652,7 @@ bool Codegen::visit(TryStatement *ast) bool Codegen::visit(VariableStatement *ast) { - if (hasError) + if (hasError()) return false; variableDeclarationList(ast->declarations); @@ -3662,7 +3661,7 @@ bool Codegen::visit(VariableStatement *ast) bool Codegen::visit(WhileStatement *ast) { - if (hasError) + if (hasError()) return false; if (AST::cast<FalseLiteral *>(ast->expression)) @@ -3694,14 +3693,14 @@ bool Codegen::visit(WhileStatement *ast) bool Codegen::visit(WithStatement *ast) { - if (hasError) + if (hasError()) return false; RegisterScope scope(this); TailCallBlocker blockTailCalls(this); Reference src = expression(ast->expression); - if (hasError) + if (hasError()) return false; src = src.storeOnStack(); // trigger load before we setup the exception handler, so exceptions here go to the right place src.loadInAccumulator(); @@ -3771,35 +3770,30 @@ bool Codegen::throwSyntaxErrorOnEvalOrArgumentsInStrictMode(const Reference &r, return isArgOrEval; } -void Codegen::throwSyntaxError(const SourceLocation &loc, const QString &detail) +void Codegen::throwError(ErrorType errorType, const SourceLocation &loc, const QString &detail) { - if (hasError) + if (hasError()) return; - hasError = true; - QQmlJS::DiagnosticMessage error; - error.message = detail; - error.line = loc.startLine; - error.column = loc.startColumn; - _errors << error; + _errorType = errorType; + _error.message = detail; + _error.line = loc.startLine; + _error.column = loc.startColumn; } -void Codegen::throwReferenceError(const SourceLocation &loc, const QString &detail) +void Codegen::throwSyntaxError(const SourceLocation &loc, const QString &detail) { - if (hasError) - return; + throwError(SyntaxError, loc, detail); +} - hasError = true; - QQmlJS::DiagnosticMessage error; - error.message = detail; - error.line = loc.startLine; - error.column = loc.startColumn; - _errors << error; +void Codegen::throwReferenceError(const SourceLocation &loc, const QString &detail) +{ + throwError(ReferenceError, loc, detail); } -QList<QQmlJS::DiagnosticMessage> Codegen::errors() const +QQmlJS::DiagnosticMessage Codegen::error() const { - return _errors; + return _error; } QV4::CompiledData::CompilationUnit Codegen::generateCompilationUnit( @@ -3842,12 +3836,11 @@ CompiledData::CompilationUnit Codegen::compileModule( JSUnitGenerator jsGenerator(&compilerModule); Codegen cg(&jsGenerator, /*strictMode*/true); cg.generateFromModule(url, url, sourceCode, moduleNode, &compilerModule); - auto errors = cg.errors(); - if (diagnostics) - *diagnostics << errors; - - if (!errors.isEmpty()) + if (cg.hasError()) { + if (diagnostics) + *diagnostics << cg.error(); return CompiledData::CompilationUnit(); + } return cg.generateCompilationUnit(); } diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h index c76957620e..51b821aafe 100644 --- a/src/qml/compiler/qv4codegen_p.h +++ b/src/qml/compiler/qv4codegen_p.h @@ -534,7 +534,7 @@ protected: inline Reference expression(AST::ExpressionNode *ast, const QString &name = QString()) { - if (!ast || hasError) + if (!ast || hasError()) return Reference(); pushExpr(name); @@ -544,7 +544,7 @@ protected: inline void accept(AST::Node *node) { - if (!hasError && node) + if (!hasError() && node) node->accept(this); } @@ -671,7 +671,15 @@ protected: } public: - QList<DiagnosticMessage> errors() const; + enum ErrorType { + NoError, + SyntaxError, + ReferenceError + }; + + ErrorType errorType() const { return _errorType; } + bool hasError() const { return _errorType != NoError; } + DiagnosticMessage error() const; QUrl url() const; Reference binopHelper(QSOperator::Op oper, Reference &left, Reference &right); @@ -770,8 +778,8 @@ protected: ControlFlow *controlFlow = nullptr; bool _fileNameIsUrl; - bool hasError; - QList<QQmlJS::DiagnosticMessage> _errors; + ErrorType _errorType = NoError; + QQmlJS::DiagnosticMessage _error; class TailCallBlocker { @@ -800,6 +808,7 @@ protected: private: VolatileMemoryLocations scanVolatileMemoryLocations(AST::Node *ast); void handleConstruct(const Reference &base, AST::ArgumentList *args); + void throwError(ErrorType errorType, const AST::SourceLocation &loc, const QString &detail); }; } |