8#include <private/qv4context_p.h>
9#include <private/qv4identifiertable_p.h>
10#include <private/qv4mm_p.h>
11#include <private/qv4stackframe_p.h>
12#include <private/qv4symbol_p.h>
13#include <private/qv4vme_moth_p.h>
15#include <QtCore/qscopeguard.h>
21void Heap::Module::init(ExecutionEngine *engine, ExecutableCompilationUnit *moduleUnit)
28 self.set(engine,
this);
30 Function *moduleFunction = unit->runtimeFunctions[unit->unitData()->indexOfRootFunction];
32 const uint locals = moduleFunction->compiledFunction->nLocals;
33 const size_t requiredMemory =
sizeof(QV4::CallContext::Data) -
sizeof(Value) +
sizeof(Value) * locals;
34 scope.set(engine, engine->memoryManager->allocManaged<QV4::CallContext>(requiredMemory, moduleFunction->internalClass));
36 scope->outer.set(engine, engine->rootContext()->d());
37 scope->locals.size = locals;
38 scope->locals.alloc = locals;
42 scope->setupLocalTemporalDeadZone(moduleFunction->compiledFunction);
44 Scope valueScope(engine);
53 Scoped<QV4::InternalClass> ic(valueScope, scope->internalClass);
55 for (uint i = 0; i < unit->unitData()->importEntryTableSize; ++i) {
56 const CompiledData::ImportEntry &import = unit->unitData()->importEntryTable()[i];
57 ic = ic->addMember(engine->identifierTable->asPropertyKey(unit->runtimeStrings[import.localName]), Attr_NotConfigurable);
59 scope->internalClass.set(engine, ic->d());
63 Scoped<QV4::Module> This(valueScope,
this);
64 ScopedString name(valueScope, engine->newString(QStringLiteral(
"Module")));
65 This->insertMember(engine->symbol_toStringTag(), name, Attr_ReadOnly);
66 This->setPrototypeUnchecked(
nullptr);
69void Module::evaluate()
73 d()->evaluated =
true;
75 ExecutableCompilationUnit *unit = d()->unit;
77 unit->evaluateModuleRequests();
79 ExecutionEngine *v4 = engine();
80 Function *moduleFunction = unit->runtimeFunctions[unit->unitData()->indexOfRootFunction];
81 JSTypesStackFrame frame;
82 frame.init(moduleFunction,
nullptr, 0);
83 frame.setupJSFrame(v4->jsStackTop, Value::undefinedValue(), d()->scope,
84 Value::undefinedValue(), Value::undefinedValue());
87 v4->jsStackTop += frame.requiredJSStackFrameSize();
88 auto frameCleanup = qScopeGuard([&frame, v4]() {
91 Moth::VME::exec(&frame, v4);
94const Value *Module::resolveExport(PropertyKey id)
const
96 if (d()->unit->isESModule()) {
99 Scope scope(engine());
100 ScopedString name(scope, id.asStringOrSymbol());
101 return d()->unit->resolveExport(name);
103 InternalClassEntry entry = d()->scope->internalClass->find(id);
105 return &d()->scope->locals[entry.index];
110ReturnedValue Module::virtualGet(
const Managed *m, PropertyKey id,
const Value *receiver,
bool *hasProperty)
113 return Object::virtualGet(m, id, receiver, hasProperty);
115 const Module *module =
static_cast<
const Module *>(m);
116 const Value *v = module->resolveExport(id);
118 *hasProperty = v !=
nullptr;
120 return Encode::undefined();
122 Scope scope(m->engine());
123 ScopedValue propName(scope, id.toStringOrSymbol(scope.engine));
124 return scope.engine->throwReferenceError(propName);
126 return v->asReturnedValue();
129PropertyAttributes Module::virtualGetOwnProperty(
const Managed *m, PropertyKey id, Property *p)
132 return Object::virtualGetOwnProperty(m, id, p);
134 const Module *module =
static_cast<
const Module *>(m);
135 const Value *v = module->resolveExport(id);
138 p->value = Encode::undefined();
142 p->value = v->isEmpty() ? Encode::undefined() : v->asReturnedValue();
144 Scope scope(m->engine());
145 ScopedValue propName(scope, id.toStringOrSymbol(scope.engine));
146 scope.engine->throwReferenceError(propName);
148 return Attr_Data | Attr_NotConfigurable;
151bool Module::virtualHasProperty(
const Managed *m, PropertyKey id)
154 return Object::virtualHasProperty(m, id);
156 const Module *module =
static_cast<
const Module *>(m);
157 const Value *v = module->resolveExport(id);
161bool Module::virtualPreventExtensions(Managed *)
166bool Module::virtualDefineOwnProperty(Managed *, PropertyKey,
const Property *, PropertyAttributes)
171bool Module::virtualPut(Managed *, PropertyKey,
const Value &, Value *)
176bool Module::virtualDeleteProperty(Managed *m, PropertyKey id)
179 return Object::virtualDeleteProperty(m, id);
180 const Module *module =
static_cast<
const Module *>(m);
181 const Value *v = module->resolveExport(id);
188struct ModuleNamespaceIterator : ObjectOwnPropertyKeyIterator
190 QStringList exportedNames;
192 ModuleNamespaceIterator(
const QStringList &names) : exportedNames(names) {}
193 ~ModuleNamespaceIterator() override =
default;
194 PropertyKey next(
const Object *o, Property *pd =
nullptr, PropertyAttributes *attrs =
nullptr)
override;
198PropertyKey ModuleNamespaceIterator::next(
const Object *o, Property *pd, PropertyAttributes *attrs)
200 const Module *module =
static_cast<
const Module *>(o);
201 if (exportIndex < exportedNames.size()) {
204 Scope scope(module->engine());
205 ScopedString exportName(scope, scope.engine->newString(exportedNames.at(exportIndex)));
208 const Value *v = module->resolveExport(exportName->toPropertyKey());
209 if (!v || v->isEmpty())
210 scope.engine->throwReferenceError(exportName);
214 return exportName->toPropertyKey();
216 return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
219OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(
const Object *o, Value *target)
221 const Module *module =
static_cast<
const Module *>(o);
225 if (module->d()->unit->isESModule()) {
226 names = module->d()->unit->exportedNames();
228 QV4::Scope scope(module->engine());
229 QV4::Scoped<InternalClass> scopeClass(scope, module->d()->scope->internalClass);
230 for (uint i = 0, end = scopeClass->d()->size; i < end; ++i) {
231 QV4::ScopedValue key(scope, scopeClass->d()->keyAt(i));
232 names << key->toQString();
236 return new ModuleNamespaceIterator(names);
239Heap::Object *Module::virtualGetPrototypeOf(
const Managed *)
244bool Module::virtualSetPrototypeOf(Managed *,
const Object *proto)
246 return proto ==
nullptr;
249bool Module::virtualIsExtensible(
const Managed *)
DEFINE_OBJECT_VTABLE(Module)