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/qv4vme_moth.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/qv4vme_moth.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 17255c7e9e..08a085c90d 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -55,6 +55,7 @@ #include <private/qv4string_p.h> #include <private/qv4profiling_p.h> #include <private/qv4jscall_p.h> +#include <private/qv4generatorobject_p.h> #include <private/qqmljavascriptexpression_p.h> #include <iostream> @@ -508,6 +509,8 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const QV4::Value *thisObj CppStackFrame frame; frame.originalArguments = argv; frame.originalArgumentsCount = argc; + frame.yield = nullptr; + frame.exceptionHandler = nullptr; Function *function; { @@ -586,10 +589,9 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code) { QV4::Function *function = frame.v4Function; QV4::Value &accumulator = frame.jsFrame->accumulator; - QV4::ReturnedValue acc = Encode::undefined(); + QV4::ReturnedValue acc = accumulator.asReturnedValue(); Value *stack = reinterpret_cast<Value *>(frame.jsFrame); ExecutionEngine *engine = function->internalClass->engine; - const uchar *exceptionHandler = nullptr; MOTH_JUMP_TABLE; @@ -798,6 +800,24 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code) CHECK_EXCEPTION; MOTH_END_INSTR(LoadIdObject) + MOTH_BEGIN_INSTR(Yield) + frame.yield = code; + return acc; + MOTH_END_INSTR(Yield) + + MOTH_BEGIN_INSTR(Resume) + // check exception, in case the generator was called with throw() or return() + if (engine->hasException) { + // an empty value indicates that the generator was called with return() + if (engine->exceptionValue->asReturnedValue() != Primitive::emptyValue().asReturnedValue()) + goto catchException; + engine->hasException = false; + *engine->exceptionValue = Primitive::undefinedValue(); + } else { + code += offset; + } + MOTH_END_INSTR(Resume) + MOTH_BEGIN_INSTR(CallValue) STORE_IP(); Value func = STACK_VALUE(name); @@ -867,7 +887,7 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code) MOTH_END_INSTR(CallContextObjectProperty) MOTH_BEGIN_INSTR(SetExceptionHandler) - exceptionHandler = offset ? code + offset : nullptr; + frame.exceptionHandler = offset ? code + offset : nullptr; MOTH_END_INSTR(SetExceptionHandler) MOTH_BEGIN_INSTR(ThrowException) @@ -1406,10 +1426,10 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code) catchException: Q_ASSERT(engine->hasException); - if (!exceptionHandler) { + if (!frame.exceptionHandler) { acc = Encode::undefined(); return acc; } - code = exceptionHandler; + code = frame.exceptionHandler; } } |