diff options
Diffstat (limited to 'src/qml/jsruntime/qv4generatorobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4generatorobject.cpp | 88 |
1 files changed, 25 insertions, 63 deletions
diff --git a/src/qml/jsruntime/qv4generatorobject.cpp b/src/qml/jsruntime/qv4generatorobject.cpp index 4eee6f4338..e7a63ba185 100644 --- a/src/qml/jsruntime/qv4generatorobject.cpp +++ b/src/qml/jsruntime/qv4generatorobject.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include <qv4generatorobject_p.h> #include <qv4symbol_p.h> @@ -62,7 +26,7 @@ ReturnedValue GeneratorFunctionCtor::virtualCallAsConstructor(const FunctionObje if (engine->hasException) return Encode::undefined(); - Function *vmf = compilationUnit->linkToEngine(engine); + Function *vmf = compilationUnit->rootFunction(); ExecutionContext *global = engine->scriptContext(); ReturnedValue o = Encode(GeneratorFunction::create(global, vmf)); @@ -97,33 +61,31 @@ ReturnedValue GeneratorFunction::virtualCall(const FunctionObject *f, const Valu Function *function = gf->function(); ExecutionEngine *engine = gf->engine(); - // We need to set up a separate stack for the generator, as it's being re-entered - uint stackSize = argc // space for the original arguments - + CppStackFrame::requiredJSStackFrameSize(function); // space for the JS stack frame - - size_t requiredMemory = sizeof(GeneratorObject::Data) - sizeof(Value) + sizeof(Value) * stackSize; - Scope scope(gf); - Scoped<GeneratorObject> g(scope, scope.engine->memoryManager->allocManaged<GeneratorObject>(requiredMemory, scope.engine->classes[EngineBase::Class_GeneratorObject])); + Scoped<GeneratorObject> g(scope, engine->memoryManager->allocManaged<GeneratorObject>(engine->classes[EngineBase::Class_GeneratorObject])); g->setPrototypeOf(ScopedObject(scope, gf->get(scope.engine->id_prototype()))); + // We need to set up a separate JSFrame for the generator, as it's being re-entered Heap::GeneratorObject *gp = g->d(); - gp->stack.size = stackSize; - gp->stack.alloc = stackSize; + gp->values.set(engine, engine->newArrayObject(argc)); + gp->jsFrame.set(engine, engine->newArrayObject( + JSTypesStackFrame::requiredJSStackFrameSize(function))); // copy original arguments - memcpy(gp->stack.values, argv, argc*sizeof(Value)); - gp->cppFrame.init(engine, function, gp->stack.values, argc); - gp->cppFrame.setupJSFrame(&gp->stack.values[argc], *gf, gf->scope(), + for (int i = 0; i < argc; i++) + gp->values->arrayData->setArrayData(engine, i, argv[i]); + + gp->cppFrame.init(function, gp->values->arrayData->values.values, argc); + gp->cppFrame.setupJSFrame(gp->jsFrame->arrayData->values.values, *gf, gf->scope(), thisObject ? *thisObject : Value::undefinedValue(), Value::undefinedValue()); - gp->cppFrame.push(); + gp->cppFrame.push(engine); Moth::VME::interpret(&gp->cppFrame, engine, function->codeData); gp->state = GeneratorState::SuspendedStart; - gp->cppFrame.pop(); + gp->cppFrame.pop(engine); return g->asReturnedValue(); } @@ -191,7 +153,7 @@ ReturnedValue GeneratorPrototype::method_return(const FunctionObject *f, const V // a yield called with return() engine->throwError(Value::emptyValue()); - return g->resume(engine, argc ? argv[0]: Value::undefinedValue()); + return g->resume(engine, argc ? argv[0] : Value::undefinedValue()); } ReturnedValue GeneratorPrototype::method_throw(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc) @@ -203,7 +165,7 @@ ReturnedValue GeneratorPrototype::method_throw(const FunctionObject *f, const Va Heap::GeneratorObject *gp = g->d(); - engine->throwError(argc ? argv[0]: Value::undefinedValue()); + engine->throwError(argc ? argv[0] : Value::undefinedValue()); if (gp->state == GeneratorState::SuspendedStart || gp->state == GeneratorState::Completed) { gp->state = GeneratorState::Completed; @@ -217,25 +179,25 @@ ReturnedValue GeneratorObject::resume(ExecutionEngine *engine, const Value &arg) { Heap::GeneratorObject *gp = d(); gp->state = GeneratorState::Executing; - gp->cppFrame.parent = engine->currentStackFrame; + gp->cppFrame.setParentFrame(engine->currentStackFrame); engine->currentStackFrame = &gp->cppFrame; - Q_ASSERT(gp->cppFrame.yield != nullptr); - const char *code = gp->cppFrame.yield; - gp->cppFrame.yield = nullptr; + Q_ASSERT(gp->cppFrame.yield() != nullptr); + const char *code = gp->cppFrame.yield(); + gp->cppFrame.setYield(nullptr); gp->cppFrame.jsFrame->accumulator = arg; - gp->cppFrame.yieldIsIterator = false; + gp->cppFrame.setYieldIsIterator(false); Scope scope(engine); ScopedValue result(scope, Moth::VME::interpret(&gp->cppFrame, engine, code)); - engine->currentStackFrame = gp->cppFrame.parent; + engine->currentStackFrame = gp->cppFrame.parentFrame(); - bool done = (gp->cppFrame.yield == nullptr); + bool done = (gp->cppFrame.yield() == nullptr); gp->state = done ? GeneratorState::Completed : GeneratorState::SuspendedYield; if (engine->hasException) return Encode::undefined(); - if (gp->cppFrame.yieldIsIterator) + if (gp->cppFrame.yieldIsIterator()) return result->asReturnedValue(); return IteratorPrototype::createIterResultObject(engine, result, done); } |