diff --git a/src/bun.js/bindings/NodeVMModule.cpp b/src/bun.js/bindings/NodeVMModule.cpp index 5da7de9384..662c192051 100644 --- a/src/bun.js/bindings/NodeVMModule.cpp +++ b/src/bun.js/bindings/NodeVMModule.cpp @@ -88,6 +88,28 @@ NodeVMModule* NodeVMModule::create(JSC::VM& vm, JSC::JSGlobalObject* globalObjec return nullptr; } +JSModuleNamespaceObject* NodeVMModule::namespaceObject(JSC::JSGlobalObject* globalObject) +{ + JSModuleNamespaceObject* object = m_namespaceObject.get(); + if (object) { + return object; + } + + if (auto* thisObject = jsDynamicCast(this)) { + VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + object = thisObject->moduleRecord(globalObject)->getModuleNamespace(globalObject); + RETURN_IF_EXCEPTION(scope, {}); + if (object) { + namespaceObject(vm, object); + } + } else { + RELEASE_ASSERT_NOT_REACHED_WITH_MESSAGE("NodeVMModule::namespaceObject called on an unsupported module type (%s)", info()->className.characters()); + } + + return object; +} + JSC_DECLARE_CUSTOM_GETTER(jsNodeVmModuleGetterIdentifier); JSC_DECLARE_HOST_FUNCTION(jsNodeVmModuleGetStatusCode); JSC_DECLARE_HOST_FUNCTION(jsNodeVmModuleGetStatus); @@ -179,7 +201,7 @@ JSC_DEFINE_HOST_FUNCTION(jsNodeVmModuleGetStatus, (JSC::JSGlobalObject * globalO JSC_DEFINE_HOST_FUNCTION(jsNodeVmModuleGetNamespace, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) { auto* thisObject = jsCast(callFrame->thisValue()); - return JSValue::encode(thisObject->namespace_()); + return JSValue::encode(thisObject->namespaceObject(globalObject)); } JSC_DEFINE_HOST_FUNCTION(jsNodeVmModuleGetError, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) @@ -292,7 +314,7 @@ void NodeVMModule::visitChildrenImpl(JSCell* cell, Visitor& visitor) ASSERT_GC_OBJECT_INHERITS(vmModule, info()); Base::visitChildren(vmModule, visitor); - visitor.append(vmModule->m_namespace); + visitor.append(vmModule->m_namespaceObject); visitor.append(vmModule->m_context); auto moduleNatives = vmModule->m_resolveCache.values(); diff --git a/src/bun.js/bindings/NodeVMModule.h b/src/bun.js/bindings/NodeVMModule.h index 79057345ea..c0226c9cb3 100644 --- a/src/bun.js/bindings/NodeVMModule.h +++ b/src/bun.js/bindings/NodeVMModule.h @@ -2,7 +2,8 @@ #include "NodeVM.h" -#include "JavaScriptCore/AbstractModuleRecord.h" +#include "AbstractModuleRecord.h" +#include "JSModuleNamespaceObject.h" namespace Bun { @@ -49,8 +50,8 @@ public: Status status() const { return m_status; } void status(Status value) { m_status = value; } - JSObject* namespace_() const { return m_namespace.get(); } - void namespace_(VM& vm, JSObject* value) { m_namespace.set(vm, this, value); } + JSModuleNamespaceObject* namespaceObject(JSC::JSGlobalObject* globalObject); + void namespaceObject(JSC::VM& vm, JSModuleNamespaceObject* value) { m_namespaceObject.set(vm, this, value); } const WTF::Vector& moduleRequests() const { return m_moduleRequests; } void addModuleRequest(NodeVMModuleRequest request) { m_moduleRequests.append(WTFMove(request)); } @@ -67,7 +68,7 @@ public: protected: WTF::String m_identifier; Status m_status = Status::Unlinked; - mutable WriteBarrier m_namespace; + mutable WriteBarrier m_namespaceObject; mutable WriteBarrier m_context; WTF::Vector m_moduleRequests; mutable WTF::HashMap> m_resolveCache; diff --git a/src/bun.js/bindings/NodeVMSourceTextModule.cpp b/src/bun.js/bindings/NodeVMSourceTextModule.cpp index a0ba4ee6cd..00c8763995 100644 --- a/src/bun.js/bindings/NodeVMSourceTextModule.cpp +++ b/src/bun.js/bindings/NodeVMSourceTextModule.cpp @@ -2,8 +2,8 @@ #include "ErrorCode.h" #include "JSDOMExceptionHandling.h" -#include "JSModuleLoader.h" #include "JSModuleRecord.h" +#include "JSPromise.h" #include "JSSourceCode.h" #include "ModuleAnalyzer.h" #include "Parser.h" @@ -228,7 +228,7 @@ JSValue NodeVMSourceTextModule::link(JSGlobalObject* globalObject, JSArray* spec WTF::String specifier = specifierValue.toWTFString(globalObject); JSObject* moduleNative = moduleNativeValue.getObject(); - auto* resolvedRecord = jsCast(moduleNative)->moduleRecord(globalObject); + AbstractModuleRecord* resolvedRecord = jsCast(moduleNative)->moduleRecord(globalObject); record->setImportedModule(globalObject, Identifier::fromString(vm, specifier), resolvedRecord); m_resolveCache.set(WTFMove(specifier), WriteBarrier { vm, this, moduleNative }); @@ -244,11 +244,9 @@ JSValue NodeVMSourceTextModule::link(JSGlobalObject* globalObject, JSArray* spec RETURN_IF_EXCEPTION(scope, {}); if (sync == Synchronousness::Async) { - ASSERT_NOT_REACHED_WITH_MESSAGE("TODO(@heimskr): async module linking"); + RELEASE_ASSERT_NOT_REACHED_WITH_MESSAGE("TODO(@heimskr): async module linking"); } - RETURN_IF_EXCEPTION(scope, {}); - status(Status::Linked); return JSC::jsUndefined(); } @@ -273,7 +271,19 @@ JSValue NodeVMSourceTextModule::evaluate(JSGlobalObject* globalObject, uint32_t } auto run = [&] { - // TODO(@heimskr): top-level await support + status(Status::Evaluating); + + for (const auto& request : record->requestedModules()) { + if (auto iter = m_resolveCache.find(WTF::String(*request.m_specifier)); iter != m_resolveCache.end()) { + if (auto* dependency = jsDynamicCast(iter->value.get())) { + if (dependency->status() == Status::Linked) { + JSValue dependencyResult = dependency->evaluate(globalObject, timeout, breakOnSigint); + RELEASE_ASSERT_WITH_MESSAGE(jsDynamicCast(dependencyResult) == nullptr, "TODO(@heimskr): implement async support for node:vm SourceTextModule dependencies"); + } + } + } + } + result = record->evaluate(globalObject, jsUndefined(), jsNumber(static_cast(JSGenerator::ResumeMode::NormalMode))); }; diff --git a/src/js/node/vm.ts b/src/js/node/vm.ts index f24e284ee1..e8cf3abebc 100644 --- a/src/js/node/vm.ts +++ b/src/js/node/vm.ts @@ -9,7 +9,6 @@ const { validateInt32, validateBuffer, validateFunction, - validateInternalField, } = require("internal/validators"); const util = require("node:util"); @@ -190,7 +189,6 @@ class Module { } [util.inspect.custom](depth, options) { - validateInternalField(this, kNative, "Module"); if (typeof depth === "number" && depth < 0) return this; const constructor = getConstructorOf(this) || Module; @@ -301,7 +299,6 @@ class SourceTextModule extends Module { const moduleNatives = await SafePromiseAllReturnArrayLike(modulePromises); this[kNative].link(specifiers, moduleNatives, 0); } catch (e) { - console.error("linking error:", e); this.#error = e; throw e; } finally {