diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-04-27 11:41:13 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-03 20:05:14 +0000 |
commit | 5747a7530206ac410b6bd7c1b8490d7d389ad3a5 (patch) | |
tree | afca9153823b1a9efdf878be80922bce693eaefd /src/qml/jsruntime/qv4functionobject.cpp | |
parent | 7e6485a046fde121f0e6fdf954162354939ff1d8 (diff) |
Add Generator support
Add support for ES6 generators. Those are currently
always executed in the interpreter (we never JIT them),
to simplify the initial implementation.
Most functionality, except for 'yield *' expressions
are supported. 'yield *' will have to wait until we
support for(... of ...)
Change-Id: I7c059d1e3b301cbcb79e3746b4bec346738fd426
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4functionobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index a684e1c5d3..6382a6e862 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -214,10 +214,8 @@ void Heap::FunctionCtor::init(QV4::ExecutionContext *scope) } // 15.3.2 -ReturnedValue FunctionCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc) +QQmlRefPointer<CompiledData::CompilationUnit> FunctionCtor::parse(ExecutionEngine *engine, const Value *argv, int argc, Type t) { - Scope scope(f->engine()); - QString arguments; QString body; if (argc > 0) { @@ -228,38 +226,51 @@ ReturnedValue FunctionCtor::callAsConstructor(const FunctionObject *f, const Val } body = argv[argc - 1].toQString(); } - if (scope.engine->hasException) - return Encode::undefined(); + if (engine->hasException) + return nullptr; - QString function = QLatin1String("function(") + arguments + QLatin1String("){") + body + QLatin1Char('}'); + QString function = (t == Type_Function ? QLatin1String("function(") : QLatin1String("function*(")) + arguments + QLatin1String("){") + body + QLatin1Char('}'); - QQmlJS::Engine ee, *engine = ⅇ - QQmlJS::Lexer lexer(engine); + QQmlJS::Engine ee; + QQmlJS::Lexer lexer(&ee); lexer.setCode(function, 1, false); - QQmlJS::Parser parser(engine); + QQmlJS::Parser parser(&ee); const bool parsed = parser.parseExpression(); - if (!parsed) - return scope.engine->throwSyntaxError(QLatin1String("Parse error")); + if (!parsed) { + engine->throwSyntaxError(QLatin1String("Parse error")); + return nullptr; + } QQmlJS::AST::FunctionExpression *fe = QQmlJS::AST::cast<QQmlJS::AST::FunctionExpression *>(parser.rootNode()); - if (!fe) - return scope.engine->throwSyntaxError(QLatin1String("Parse error")); + if (!fe) { + engine->throwSyntaxError(QLatin1String("Parse error")); + return nullptr; + } - Compiler::Module module(scope.engine->debugger() != nullptr); + Compiler::Module module(engine->debugger() != nullptr); Compiler::JSUnitGenerator jsGenerator(&module); - RuntimeCodegen cg(scope.engine, &jsGenerator, false); + RuntimeCodegen cg(engine, &jsGenerator, false); cg.generateFromFunctionExpression(QString(), function, fe, &module); - if (scope.hasException()) - return Encode::undefined(); + if (engine->hasException) + return nullptr; + + return cg.generateCompilationUnit(); +} - QQmlRefPointer<CompiledData::CompilationUnit> compilationUnit = cg.generateCompilationUnit(); - Function *vmf = compilationUnit->linkToEngine(scope.engine); +ReturnedValue FunctionCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc) +{ + ExecutionEngine *engine = f->engine(); + + QQmlRefPointer<CompiledData::CompilationUnit> compilationUnit = parse(engine, argv, argc, Type_Function); + if (engine->hasException) + return Encode::undefined(); - ExecutionContext *global = scope.engine->rootContext(); + Function *vmf = compilationUnit->linkToEngine(engine); + ExecutionContext *global = engine->rootContext(); return Encode(FunctionObject::createScriptFunction(global, vmf)); } |