From 11aa17a57cc679d34e8e6f6f7aa665f565cb7305 Mon Sep 17 00:00:00 2001 From: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> Date: Mon, 5 Sep 2022 23:05:22 -0700 Subject: Support async `onLoad` callbacks in `Bun.plugin` --- src/bun.js/bindings/BunPlugin.cpp | 6 +- src/bun.js/bindings/ModuleLoader.cpp | 520 +++++++++++++++++++++ src/bun.js/bindings/ModuleLoader.h | 94 ++++ src/bun.js/bindings/ZigGlobalObject.cpp | 252 ++-------- src/bun.js/bindings/ZigGlobalObject.h | 21 +- src/bun.js/bindings/bindings.cpp | 30 +- src/bun.js/bindings/headers-handwritten.h | 39 ++ .../bindings/webcore/DOMClientIsoSubspaces.h | 1 + src/bun.js/bindings/webcore/DOMIsoSubspaces.h | 1 + 9 files changed, 738 insertions(+), 226 deletions(-) create mode 100644 src/bun.js/bindings/ModuleLoader.cpp create mode 100644 src/bun.js/bindings/ModuleLoader.h (limited to 'src/bun.js/bindings') diff --git a/src/bun.js/bindings/BunPlugin.cpp b/src/bun.js/bindings/BunPlugin.cpp index 0941d2722..ba1d40a0b 100644 --- a/src/bun.js/bindings/BunPlugin.cpp +++ b/src/bun.js/bindings/BunPlugin.cpp @@ -303,8 +303,7 @@ extern "C" EncodedJSValue jsFunctionBunPlugin(JSC::JSGlobalObject* globalObject, RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); if (auto* promise = JSC::jsDynamicCast(result)) { - JSC::throwTypeError(globalObject, throwScope, "setup() does not support promises yet"_s); - return JSValue::encode(jsUndefined()); + RELEASE_AND_RETURN(throwScope, JSValue::encode(promise)); } RELEASE_AND_RETURN(throwScope, JSValue::encode(jsUndefined())); @@ -384,8 +383,7 @@ EncodedJSValue BunPlugin::OnLoad::run(JSC::JSGlobalObject* globalObject, ZigStri if (auto* promise = JSC::jsDynamicCast(result)) { switch (promise->status(vm)) { case JSPromise::Status::Pending: { - JSC::throwTypeError(globalObject, throwScope, "onLoad() doesn't support pending promises yet"_s); - return JSValue::encode({}); + return JSValue::encode(promise); } case JSPromise::Status::Rejected: { promise->internalField(JSC::JSPromise::Field::Flags).set(vm, promise, jsNumber(static_cast(JSC::JSPromise::Status::Fulfilled))); diff --git a/src/bun.js/bindings/ModuleLoader.cpp b/src/bun.js/bindings/ModuleLoader.cpp new file mode 100644 index 000000000..dd5ea01ad --- /dev/null +++ b/src/bun.js/bindings/ModuleLoader.cpp @@ -0,0 +1,520 @@ +#include "root.h" +#include "headers-handwritten.h" + +#include "ModuleLoader.h" + +#include "ZigGlobalObject.h" +#include "JavaScriptCore/JSCInlines.h" +#include "JavaScriptCore/JSNativeStdFunction.h" +#include "JavaScriptCore/JSCJSValueInlines.h" +#include "JavaScriptCore/JSInternalPromise.h" +#include "JavaScriptCore/JSInternalFieldObjectImpl.h" + +#include "ZigSourceProvider.h" + +#include "JavaScriptCore/JSSourceCode.h" +#include "JavaScriptCore/JSString.h" +#include "JavaScriptCore/JSValueInternal.h" +#include "JavaScriptCore/JSVirtualMachineInternal.h" +#include "JavaScriptCore/ObjectConstructor.h" +#include "JavaScriptCore/OptionsList.h" +#include "JavaScriptCore/ParserError.h" +#include "JavaScriptCore/ScriptExecutable.h" +#include "JavaScriptCore/SourceOrigin.h" +#include "JavaScriptCore/StackFrame.h" +#include "JavaScriptCore/StackVisitor.h" + +#include "EventEmitter.h" +#include "JSEventEmitter.h" + +#include "../modules/BufferModule.h" +#include "../modules/EventsModule.h" +#include "../modules/ProcessModule.h" +#include "../modules/StringDecoderModule.h" +#include "../modules/ObjectModule.h" +#include "../modules/NodeModuleModule.h" + +namespace Bun { +using namespace Zig; +using namespace WebCore; + +static JSC::JSInternalPromise* rejectedInternalPromise(JSC::JSGlobalObject* globalObject, JSC::JSValue value) +{ + JSC::VM& vm = globalObject->vm(); + JSInternalPromise* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); + promise->internalField(JSC::JSPromise::Field::ReactionsOrResult).set(vm, promise, value); + promise->internalField(JSC::JSPromise::Field::Flags).set(vm, promise, jsNumber(promise->internalField(JSC::JSPromise::Field::Flags).get().asUInt32AsAnyInt() | JSC::JSPromise::isFirstResolvingFunctionCalledFlag | static_cast(JSC::JSPromise::Status::Rejected))); + return promise; +} + +static JSC::JSInternalPromise* resolvedInternalPromise(JSC::JSGlobalObject* globalObject, JSC::JSValue value) +{ + JSC::VM& vm = globalObject->vm(); + + JSInternalPromise* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); + promise->internalField(JSC::JSPromise::Field::ReactionsOrResult).set(vm, promise, value); + promise->internalField(JSC::JSPromise::Field::Flags).set(vm, promise, jsNumber(promise->internalField(JSC::JSPromise::Field::Flags).get().asUInt32AsAnyInt() | JSC::JSPromise::isFirstResolvingFunctionCalledFlag | static_cast(JSC::JSPromise::Status::Fulfilled))); + return promise; +} + +using namespace JSC; + +static OnLoadResult handleOnLoadObjectResult(Zig::GlobalObject* globalObject, JSC::JSObject* object) +{ + OnLoadResult result {}; + result.type = OnLoadResultTypeObject; + JSC::VM& vm = globalObject->vm(); + if (JSC::JSValue exportsValue = object->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "exports"_s))) { + if (exportsValue.isObject()) { + result.value.object = exportsValue; + return result; + } + } + + auto scope = DECLARE_THROW_SCOPE(vm); + scope.throwException(globalObject, createTypeError(globalObject, "\"object\" loader must return an \"exports\" object"_s)); + result.type = OnLoadResultTypeError; + result.value.error = scope.exception(); + scope.clearException(); + scope.release(); + return result; +} + +JSC::JSInternalPromise* PendingVirtualModuleResult::internalPromise() +{ + return jsCast(internalField(2).get()); +} + +const ClassInfo PendingVirtualModuleResult::s_info = { "PendingVirtualModule"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(PendingVirtualModuleResult) }; + +PendingVirtualModuleResult* PendingVirtualModuleResult::create(VM& vm, Structure* structure) +{ + PendingVirtualModuleResult* mod = new (NotNull, allocateCell(vm)) PendingVirtualModuleResult(vm, structure); + return mod; +} +Structure* PendingVirtualModuleResult::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) +{ + return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info()); +} + +PendingVirtualModuleResult::PendingVirtualModuleResult(VM& vm, Structure* structure) + : Base(vm, structure) +{ +} + +void PendingVirtualModuleResult::finishCreation(VM& vm, const WTF::String& specifier, const WTF::String& referrer) +{ + Base::finishCreation(vm); + Base::internalField(0).set(vm, this, JSC::jsString(vm, specifier)); + Base::internalField(1).set(vm, this, JSC::jsString(vm, referrer)); + Base::internalField(2).set(vm, this, JSC::JSInternalPromise::create(vm, globalObject()->internalPromiseStructure())); +} + +template +void PendingVirtualModuleResult::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); +} + +DEFINE_VISIT_CHILDREN(PendingVirtualModuleResult); + +PendingVirtualModuleResult* PendingVirtualModuleResult::create(JSC::JSGlobalObject* globalObject, const WTF::String& specifier, const WTF::String& referrer) +{ + auto* virtualModule = create(globalObject->vm(), reinterpret_cast(globalObject)->pendingVirtualModuleResultStructure()); + virtualModule->finishCreation(globalObject->vm(), specifier, referrer); + return virtualModule; +} + +OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC::JSValue objectValue) +{ + OnLoadResult result = {}; + result.type = OnLoadResultTypeError; + JSC::VM& vm = globalObject->vm(); + result.value.error = JSC::jsUndefined(); + auto scope = DECLARE_THROW_SCOPE(vm); + BunLoaderType loader = BunLoaderTypeNone; + + JSC::JSObject* object = objectValue.getObject(); + if (UNLIKELY(!object)) { + scope.throwException(globalObject, JSC::createError(globalObject, "Expected onLoad callback to return an object"_s)); + result.value.error = scope.exception(); + scope.clearException(); + scope.release(); + return result; + } + + if (JSC::JSValue loaderValue = object->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "loader"_s))) { + if (loaderValue.isString()) { + if (JSC::JSString* loaderJSString = loaderValue.toStringOrNull(globalObject)) { + WTF::String loaderString = loaderJSString->value(globalObject); + if (loaderString == "js"_s) { + loader = BunLoaderTypeJS; + } else if (loaderString == "object"_s) { + return handleOnLoadObjectResult(globalObject, object); + } else if (loaderString == "jsx"_s) { + loader = BunLoaderTypeJSX; + } else if (loaderString == "ts"_s) { + loader = BunLoaderTypeTS; + } else if (loaderString == "tsx"_s) { + loader = BunLoaderTypeTSX; + } else if (loaderString == "json"_s) { + loader = BunLoaderTypeJSON; + } else if (loaderString == "toml"_s) { + loader = BunLoaderTypeTOML; + } + } + } + } + + if (UNLIKELY(loader == BunLoaderTypeNone)) { + throwException(globalObject, scope, createError(globalObject, "Expected loader to be one of \"js\", \"jsx\", \"object\", \"ts\", \"tsx\", \"toml\", or \"json\""_s)); + result.value.error = scope.exception(); + scope.clearException(); + scope.release(); + return result; + } + + result.value.sourceText.loader = loader; + result.value.sourceText.value = JSValue {}; + result.value.sourceText.string = {}; + + if (JSC::JSValue contentsValue = object->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "contents"_s))) { + if (contentsValue.isString()) { + if (JSC::JSString* contentsJSString = contentsValue.toStringOrNull(globalObject)) { + result.value.sourceText.string = Zig::toZigString(contentsJSString, globalObject); + result.value.sourceText.value = contentsValue; + } + } else if (JSC::JSArrayBufferView* view = JSC::jsDynamicCast(contentsValue)) { + result.value.sourceText.string = ZigString { reinterpret_cast(view->vector()), view->byteLength() }; + result.value.sourceText.value = contentsValue; + } + } + + if (UNLIKELY(result.value.sourceText.value.isEmpty())) { + throwException(globalObject, scope, createError(globalObject, "Expected \"contents\" to be a string or an ArrayBufferView"_s)); + result.value.error = scope.exception(); + scope.clearException(); + scope.release(); + return result; + } + + result.type = OnLoadResultTypeCode; + return result; +} + +static OnLoadResult handleOnLoadResult(Zig::GlobalObject* globalObject, JSC::JSValue objectValue) +{ + if (JSC::JSPromise* promise = JSC::jsDynamicCast(objectValue)) { + OnLoadResult result = {}; + result.type = OnLoadResultTypePromise; + result.value.promise = objectValue; + return result; + } + + return handleOnLoadResultNotPromise(globalObject, objectValue); +} + +template +static JSValue handleVirtualModuleResult( + Zig::GlobalObject* globalObject, + JSValue virtualModuleResult, + ErrorableResolvedSource* res, + ZigString* specifier, + ZigString* referrer) +{ + auto onLoadResult = handleOnLoadResult(globalObject, virtualModuleResult); + JSC::VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto reject = [&](JSC::JSValue exception) -> JSValue { + if constexpr (allowPromise) { + return rejectedInternalPromise(globalObject, exception); + } else { + throwException(globalObject, scope, exception); + return exception; + } + }; + + auto resolve = [&](JSValue code) -> JSValue { + res->success = true; + if constexpr (allowPromise) { + return resolvedInternalPromise(globalObject, code); + } else { + return code; + } + }; + + auto rejectOrResolve = [&](JSValue code) -> JSValue { + if (auto* exception = scope.exception()) { + if constexpr (allowPromise) { + scope.clearException(); + return rejectedInternalPromise(globalObject, exception); + } else { + return exception; + } + } + + res->success = true; + + if constexpr (allowPromise) { + return resolvedInternalPromise(globalObject, code); + } else { + return code; + } + }; + + switch (onLoadResult.type) { + case OnLoadResultTypeCode: { + Bun__transpileVirtualModule(globalObject, specifier, referrer, &onLoadResult.value.sourceText.string, onLoadResult.value.sourceText.loader, res); + if (!res->success) { + return reject(JSValue::decode(reinterpret_cast(res->result.err.ptr))); + } + + auto provider = Zig::SourceProvider::create(res->result.value); + return resolve(JSC::JSSourceCode::create(vm, JSC::SourceCode(provider))); + } + case OnLoadResultTypeError: { + return reject(onLoadResult.value.error); + } + + case OnLoadResultTypeObject: { + JSC::JSObject* object = onLoadResult.value.object.getObject(); + JSC::ensureStillAliveHere(object); + auto function = generateObjectModuleSourceCode( + globalObject, + object); + auto source = JSC::SourceCode( + JSC::SyntheticSourceProvider::create(WTFMove(function), + JSC::SourceOrigin(), Zig::toString(*specifier))); + JSC::ensureStillAliveHere(object); + return rejectOrResolve(JSSourceCode::create(globalObject->vm(), WTFMove(source))); + } + + case OnLoadResultTypePromise: { + JSC::JSPromise* promise = jsCast(onLoadResult.value.promise); + JSFunction* performPromiseThenFunction = globalObject->performPromiseThenFunction(); + auto callData = JSC::getCallData(performPromiseThenFunction); + ASSERT(callData.type != CallData::Type::None); + auto specifierString = Zig::toString(*specifier); + auto referrerString = Zig::toString(*referrer); + PendingVirtualModuleResult* pendingModule = PendingVirtualModuleResult::create(globalObject, specifierString, referrerString); + JSC::JSInternalPromise* internalPromise = pendingModule->internalPromise(); + MarkedArgumentBuffer arguments; + arguments.append(promise); + arguments.append(globalObject->thenable(jsFunctionOnLoadObjectResultResolve)); + arguments.append(globalObject->thenable(jsFunctionOnLoadObjectResultReject)); + arguments.append(jsUndefined()); + arguments.append(pendingModule); + ASSERT(!arguments.hasOverflowed()); + JSC::call(globalObject, performPromiseThenFunction, callData, jsUndefined(), arguments); + return internalPromise; + } + default: { + __builtin_unreachable(); + } + } +} + +template +static JSValue fetchSourceCode( + Zig::GlobalObject* globalObject, + ErrorableResolvedSource* res, + ZigString* specifier, + ZigString* referrer) +{ + void* bunVM = globalObject->bunVM(); + auto& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto reject = [&](JSC::JSValue exception) -> JSValue { + if constexpr (allowPromise) { + return rejectedInternalPromise(globalObject, exception); + } else { + throwException(globalObject, scope, exception); + return JSC::jsUndefined(); + } + }; + + auto resolve = [&](JSValue code) -> JSValue { + if constexpr (allowPromise) { + return resolvedInternalPromise(globalObject, code); + } else { + return code; + } + }; + + auto rejectOrResolve = [&](JSValue code) -> JSValue { + if (auto* exception = scope.exception()) { + scope.clearException(); + return rejectedInternalPromise(globalObject, exception); + } + + if constexpr (allowPromise) { + return resolvedInternalPromise(globalObject, code); + } else { + return code; + } + }; + + if (Bun__fetchBuiltinModule(bunVM, globalObject, specifier, referrer, res)) { + if (!res->success) { + throwException(scope, res->result.err, globalObject); + auto* exception = scope.exception(); + scope.clearException(); + return reject(exception); + } + + auto moduleKey = Zig::toString(*specifier); + + switch (res->result.value.tag) { + case SyntheticModuleType::Module: { + auto source = JSC::SourceCode( + JSC::SyntheticSourceProvider::create(generateNodeModuleModule, + JSC::SourceOrigin(), WTFMove(moduleKey))); + + return rejectOrResolve(JSSourceCode::create(vm, WTFMove(source))); + } + + case SyntheticModuleType::Buffer: { + auto source = JSC::SourceCode( + JSC::SyntheticSourceProvider::create(generateBufferSourceCode, + JSC::SourceOrigin(), WTFMove(moduleKey))); + + auto sourceCode = JSSourceCode::create(vm, WTFMove(source)); + + return rejectOrResolve(JSSourceCode::create(vm, WTFMove(source))); + } + case SyntheticModuleType::Process: { + auto source = JSC::SourceCode( + JSC::SyntheticSourceProvider::create(generateProcessSourceCode, + JSC::SourceOrigin(), WTFMove(moduleKey))); + + return rejectOrResolve(JSSourceCode::create(vm, WTFMove(source))); + } + case SyntheticModuleType::Events: { + auto source = JSC::SourceCode( + JSC::SyntheticSourceProvider::create(generateEventsSourceCode, + JSC::SourceOrigin(), WTFMove(moduleKey))); + + return rejectOrResolve(JSSourceCode::create(vm, WTFMove(source))); + } + case SyntheticModuleType::StringDecoder: { + auto source = JSC::SourceCode( + JSC::SyntheticSourceProvider::create(generateStringDecoderSourceCode, + JSC::SourceOrigin(), WTFMove(moduleKey))); + + return rejectOrResolve(JSSourceCode::create(vm, WTFMove(source))); + } + default: { + auto provider = Zig::SourceProvider::create(res->result.value); + return rejectOrResolve(JSC::JSSourceCode::create(vm, JSC::SourceCode(provider))); + } + } + } + + if (JSC::JSValue virtualModuleResult = JSValue::decode(Bun__runVirtualModule(globalObject, specifier))) { + return handleVirtualModuleResult(globalObject, virtualModuleResult, res, specifier, referrer); + } + + Bun__transpileFile(bunVM, globalObject, specifier, referrer, res); + if (!res->success) { + throwException(scope, res->result.err, globalObject); + auto* exception = scope.exception(); + scope.clearException(); + return reject(exception); + } + + auto provider = Zig::SourceProvider::create(res->result.value); + return rejectOrResolve(JSC::JSSourceCode::create(vm, JSC::SourceCode(provider))); +} + +extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultResolve(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) +{ + JSC::VM& vm = globalObject->vm(); + ErrorableResolvedSource res = {}; + res.success = false; + JSC::JSValue objectResult = callFrame->argument(0); + PendingVirtualModuleResult* pendingModule = JSC::jsCast(callFrame->argument(1)); + JSC::JSValue specifierString = pendingModule->internalField(0).get(); + JSC::JSValue referrerString = pendingModule->internalField(1).get(); + pendingModule->internalField(0).set(vm, pendingModule, JSC::jsUndefined()); + pendingModule->internalField(1).set(vm, pendingModule, JSC::jsUndefined()); + JSC::JSInternalPromise* promise = pendingModule->internalPromise(); + + ZigString specifier = Zig::toZigString(specifierString, globalObject); + ZigString referrer = Zig::toZigString(referrerString, globalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + JSC::JSValue result = handleVirtualModuleResult(reinterpret_cast(globalObject), objectResult, &res, &specifier, &referrer); + if (res.success) { + if (scope.exception()) { + auto retValue = JSValue::encode(promise->rejectWithCaughtException(globalObject, scope)); + pendingModule->internalField(2).set(vm, pendingModule, JSC::jsUndefined()); + return retValue; + } + scope.release(); + promise->resolve(globalObject, result); + pendingModule->internalField(2).set(vm, pendingModule, JSC::jsUndefined()); + } else { + throwException(globalObject, scope, result); + auto retValue = JSValue::encode(promise->rejectWithCaughtException(globalObject, scope)); + pendingModule->internalField(2).set(vm, pendingModule, JSC::jsUndefined()); + return retValue; + } + return JSValue::encode(jsUndefined()); +} + +extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultReject(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) +{ + JSC::VM& vm = globalObject->vm(); + ErrorableResolvedSource res = {}; + JSC::JSValue reason = callFrame->argument(0); + PendingVirtualModuleResult* pendingModule = JSC::jsCast(callFrame->argument(1)); + JSC::JSValue specifierString = pendingModule->internalField(0).get(); + JSC::JSValue referrerString = pendingModule->internalField(1).get(); + pendingModule->internalField(0).set(vm, pendingModule, JSC::jsUndefined()); + pendingModule->internalField(1).set(vm, pendingModule, JSC::jsUndefined()); + JSC::JSInternalPromise* promise = pendingModule->internalPromise(); + + ZigString specifier = Zig::toZigString(specifierString, globalObject); + ZigString referrer = Zig::toZigString(referrerString, globalObject); + pendingModule->internalField(2).set(vm, pendingModule, JSC::jsUndefined()); + promise->reject(globalObject, reason); + + return JSValue::encode(reason); +} + +JSValue fetchSourceCodeSync( + Zig::GlobalObject* globalObject, + ErrorableResolvedSource* res, + ZigString* specifier, + ZigString* referrer) +{ + return fetchSourceCode(globalObject, res, specifier, referrer); +} + +JSValue fetchSourceCodeAsync( + Zig::GlobalObject* globalObject, + ErrorableResolvedSource* res, + ZigString* specifier, + ZigString* referrer) +{ + return fetchSourceCode(globalObject, res, specifier, referrer); +} +} +namespace JSC { + +template +template +void JSInternalFieldObjectImpl::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + auto* thisObject = jsCast(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + visitor.appendValues(thisObject->m_internalFields, numberOfInternalFields); +} + +DEFINE_VISIT_CHILDREN_WITH_MODIFIER(template, JSInternalFieldObjectImpl); + +} // namespace JSC diff --git a/src/bun.js/bindings/ModuleLoader.h b/src/bun.js/bindings/ModuleLoader.h new file mode 100644 index 000000000..98f8b7dbb --- /dev/null +++ b/src/bun.js/bindings/ModuleLoader.h @@ -0,0 +1,94 @@ +#include "root.h" +#include "headers-handwritten.h" + +#include "JavaScriptCore/JSCInlines.h" +#include "BunClientData.h" + +namespace Zig { +class GlobalObject; +} + +namespace JSC { +class JSInternalPromise; +} + +namespace Bun { +using namespace JSC; + +typedef uint8_t OnLoadResultType; +const OnLoadResultType OnLoadResultTypeError = 0; +const OnLoadResultType OnLoadResultTypeCode = 1; +const OnLoadResultType OnLoadResultTypeObject = 2; +const OnLoadResultType OnLoadResultTypePromise = 3; + +struct CodeString { + ZigString string; + JSC::JSValue value; + BunLoaderType loader; +}; + +union OnLoadResultValue { + CodeString sourceText; + JSC::JSValue object; + JSC::JSValue promise; + JSC::JSValue error; +}; + +struct OnLoadResult { + OnLoadResultValue value; + OnLoadResultType type; +}; + +class PendingVirtualModuleResult : public JSC::JSInternalFieldObjectImpl<3> { +public: + using Base = JSC::JSInternalFieldObjectImpl<3>; + + template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return WebCore::subspaceForImpl( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForPendingVirtualModuleResult.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForPendingVirtualModuleResult = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForPendingVirtualModuleResult.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForPendingVirtualModuleResult = WTFMove(space); }); + } + + JS_EXPORT_PRIVATE static PendingVirtualModuleResult* create(VM&, Structure*); + static PendingVirtualModuleResult* create(JSC::JSGlobalObject* globalObject, const WTF::String& specifier, const WTF::String& referrer); + static PendingVirtualModuleResult* createWithInitialValues(VM&, Structure*); + static Structure* createStructure(VM&, JSGlobalObject*, JSValue); + + JSC::JSInternalPromise* internalPromise(); + + static std::array initialValues() + { + return { { + jsUndefined(), + jsUndefined(), + jsUndefined(), + } }; + } + + DECLARE_EXPORT_INFO; + DECLARE_VISIT_CHILDREN; + + PendingVirtualModuleResult(JSC::VM&, JSC::Structure*); + void finishCreation(JSC::VM&, const WTF::String& specifier, const WTF::String& referrer); +}; + +OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC::JSValue objectValue); +JSValue fetchSourceCodeSync( + Zig::GlobalObject* globalObject, + ErrorableResolvedSource* res, + ZigString* specifier, + ZigString* referrer); + +JSValue fetchSourceCodeAsync( + Zig::GlobalObject* globalObject, + ErrorableResolvedSource* res, + ZigString* specifier, + ZigString* referrer); + +} // namespace Bun \ No newline at end of file diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 888bf8f6b..2753707e8 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -103,6 +103,7 @@ #include "JSSQLStatement.h" #include "ReadableStreamBuiltins.h" #include "BunJSCModule.h" +#include "ModuleLoader.h" #include "ZigGeneratedClasses.h" @@ -160,13 +161,6 @@ using JSBuffer = WebCore::JSBuffer; #include "DOMJITHelpers.h" #include -#include "../modules/BufferModule.h" -#include "../modules/EventsModule.h" -#include "../modules/ProcessModule.h" -#include "../modules/StringDecoderModule.h" -#include "../modules/ObjectModule.h" -#include "../modules/NodeModuleModule.h" - // #include static bool has_loaded_jsc = false; @@ -1022,6 +1016,7 @@ JSC: static NeverDestroyed bunJSCString(MAKE_STATIC_STRING_IMPL("bun:jsc")); static NeverDestroyed bunStreamString(MAKE_STATIC_STRING_IMPL("bun:stream")); static NeverDestroyed noopString(MAKE_STATIC_STRING_IMPL("noop")); + static NeverDestroyed createImportMeta(MAKE_STATIC_STRING_IMPL("createImportMeta")); JSC::JSValue moduleName = callFrame->argument(0); if (moduleName.isNumber()) { @@ -1081,6 +1076,11 @@ JSC: return JSValue::encode(obj); } + if (string == createImportMeta) { + Zig::ImportMetaObject* obj = Zig::ImportMetaObject::create(globalObject, callFrame->argument(1)); + return JSValue::encode(obj); + } + if (UNLIKELY(string == noopString)) { auto* obj = constructEmptyObject(globalObject); obj->putDirectCustomAccessor(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "getterSetter"_s)), JSC::CustomGetterSetter::create(vm, noop_getter, noop_setter), 0); @@ -1884,6 +1884,11 @@ void GlobalObject::finishCreation(VM& vm) init.set(JSModuleNamespaceObject::createStructure(init.vm, init.owner, init.owner->objectPrototype())); }); + this->m_pendingVirtualModuleResultStructure.initLater( + [](const Initializer& init) { + init.set(Bun::PendingVirtualModuleResult::createStructure(init.vm, init.owner, init.owner->objectPrototype())); + }); + this->initGeneratedLazyClasses(); m_NapiClassStructure.initLater( @@ -2655,87 +2660,27 @@ static JSC_DEFINE_HOST_FUNCTION(functionFulfillModuleSync, res.result.err.code = 0; res.result.err.ptr = nullptr; - Zig__GlobalObject__fetch(&res, globalObject, &specifier, &specifier); + JSValue result = Bun::fetchSourceCodeSync( + reinterpret_cast(globalObject), + &res, + &specifier, + &specifier); - if (!res.success) { - throwException(scope, res.result.err, globalObject); - return JSValue::encode(JSC::jsUndefined()); + if (result.isUndefined() || !result) { + return JSValue::encode(result); } - switch (res.result.value.tag) { - case SyntheticModuleType::Buffer: { - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create( - generateBufferSourceCode, - JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath("node:buffer"_s)), WTFMove(moduleKey))); - - globalObject->moduleLoader()->provideFetch(globalObject, key, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined())); - RELEASE_AND_RETURN(scope, JSValue::encode(JSC::jsUndefined())); - } - case SyntheticModuleType::ObjectModule: { - JSC::EncodedJSValue encodedValue = reinterpret_cast( - bitwise_cast(reinterpret_cast(res.result.value.source_code.ptr))); - JSC::JSObject* object = JSC::JSValue::decode(encodedValue).getObject(); - auto function = generateObjectModuleSourceCode( - globalObject, - object); - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create(WTFMove(function), - JSC::SourceOrigin(), WTFMove(moduleKey))); - - RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined())); - globalObject->moduleLoader()->provideFetch(globalObject, key, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined())); - RELEASE_AND_RETURN(scope, JSValue::encode(JSC::jsUndefined())); - } - case SyntheticModuleType::Process: { - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create( - generateProcessSourceCode, - JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath("node:process"_s)), WTFMove(moduleKey))); - - globalObject->moduleLoader()->provideFetch(globalObject, key, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined())); - RELEASE_AND_RETURN(scope, JSValue::encode(JSC::jsUndefined())); - } - case SyntheticModuleType::Events: { - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create( - generateEventsSourceCode, - JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath("node:events"_s)), WTFMove(moduleKey))); - - globalObject->moduleLoader()->provideFetch(globalObject, key, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined())); - RELEASE_AND_RETURN(scope, JSValue::encode(JSC::jsUndefined())); - } - case SyntheticModuleType::Module: { - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create( - generateNodeModuleModule, - JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath("node:module"_s)), WTFMove(moduleKey))); - - globalObject->moduleLoader()->provideFetch(globalObject, key, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined())); - RELEASE_AND_RETURN(scope, JSValue::encode(JSC::jsUndefined())); - } - case SyntheticModuleType::StringDecoder: { - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create( - generateStringDecoderSourceCode, - JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath("node:string_decoder"_s)), WTFMove(moduleKey))); - - globalObject->moduleLoader()->provideFetch(globalObject, key, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined())); - RELEASE_AND_RETURN(scope, JSValue::encode(JSC::jsUndefined())); - } - default: { - auto provider = Zig::SourceProvider::create(res.result.value); - globalObject->moduleLoader()->provideFetch(globalObject, key, JSC::SourceCode(provider)); - RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined())); - RELEASE_AND_RETURN(scope, JSValue::encode(JSC::jsUndefined())); - } - } + globalObject->moduleLoader()->provideFetch(globalObject, key, jsCast(result)->sourceCode()); + RELEASE_AND_RETURN(scope, JSValue::encode(JSC::jsUndefined())); +} + +static JSC::JSInternalPromise* rejectedInternalPromise(JSC::JSGlobalObject* globalObject, JSC::JSValue value) +{ + JSC::VM& vm = globalObject->vm(); + JSInternalPromise* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); + promise->internalField(JSC::JSPromise::Field::ReactionsOrResult).set(vm, promise, value); + promise->internalField(JSC::JSPromise::Field::Flags).set(vm, promise, jsNumber(promise->internalField(JSC::JSPromise::Field::Flags).get().asUInt32AsAnyInt() | JSC::JSPromise::isFirstResolvingFunctionCalledFlag | static_cast(JSC::JSPromise::Status::Rejected))); + return promise; } JSC::JSInternalPromise* GlobalObject::moduleLoaderFetch(JSGlobalObject* globalObject, @@ -2743,20 +2688,15 @@ JSC::JSInternalPromise* GlobalObject::moduleLoaderFetch(JSGlobalObject* globalOb JSValue value1, JSValue value2) { JSC::VM& vm = globalObject->vm(); - JSC::JSInternalPromise* promise = JSC::JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); auto scope = DECLARE_THROW_SCOPE(vm); - auto rejectWithError = [&](JSC::JSValue error) { - promise->reject(globalObject, error); - return promise; - }; - auto moduleKey = key.toWTFString(globalObject); - RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); + if (UNLIKELY(scope.exception())) + return rejectedInternalPromise(globalObject, scope.exception()->value()); if (moduleKey.endsWith(".node"_s)) { - return rejectWithError(createTypeError(globalObject, "To load Node-API modules, use require() or process.dlopen instead of import."_s)); + return rejectedInternalPromise(globalObject, createTypeError(globalObject, "To load Node-API modules, use require() or process.dlopen instead of import."_s)); } auto moduleKeyZig = toZigString(moduleKey); @@ -2766,123 +2706,19 @@ JSC::JSInternalPromise* GlobalObject::moduleLoaderFetch(JSGlobalObject* globalOb res.result.err.code = 0; res.result.err.ptr = nullptr; - Zig__GlobalObject__fetch(&res, globalObject, &moduleKeyZig, &source); - - if (!res.success) { - throwException(scope, res.result.err, globalObject); - RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); - } - - switch (res.result.value.tag) { - case 1: { - auto buffer = Vector(res.result.value.source_code.ptr, res.result.value.source_code.len); - auto source = JSC::SourceCode( - JSC::WebAssemblySourceProvider::create(WTFMove(buffer), - JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(Zig::toString(res.result.value.source_url))), - WTFMove(moduleKey))); - - auto sourceCode = JSSourceCode::create(vm, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); - - promise->resolve(globalObject, sourceCode); - scope.release(); - - globalObject->vm().drainMicrotasks(); - return promise; - } - case SyntheticModuleType::ObjectModule: { - JSC::EncodedJSValue encodedValue = reinterpret_cast( - bitwise_cast(reinterpret_cast(res.result.value.source_code.ptr))); - JSC::JSObject* object = JSC::JSValue::decode(encodedValue).getObject(); - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create(generateObjectModuleSourceCode( - globalObject, - object), - JSC::SourceOrigin(), WTFMove(moduleKey))); - - auto sourceCode = JSSourceCode::create(vm, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); + JSValue result = Bun::fetchSourceCodeAsync( + reinterpret_cast(globalObject), + &res, + &moduleKeyZig, + &source); - promise->resolve(globalObject, sourceCode); - scope.release(); - return promise; - } - case SyntheticModuleType::Module: { - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create(generateNodeModuleModule, - JSC::SourceOrigin(), WTFMove(moduleKey))); - - auto sourceCode = JSSourceCode::create(vm, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); - - promise->resolve(globalObject, sourceCode); - scope.release(); - return promise; - } - - case SyntheticModuleType::Buffer: { - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create(generateBufferSourceCode, - JSC::SourceOrigin(), WTFMove(moduleKey))); - - auto sourceCode = JSSourceCode::create(vm, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); - - promise->resolve(globalObject, sourceCode); - scope.release(); - return promise; - } - case SyntheticModuleType::Process: { - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create(generateProcessSourceCode, - JSC::SourceOrigin(), WTFMove(moduleKey))); - - auto sourceCode = JSSourceCode::create(vm, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); - - promise->resolve(globalObject, sourceCode); - scope.release(); - return promise; - } - case SyntheticModuleType::Events: { - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create(generateEventsSourceCode, - JSC::SourceOrigin(), WTFMove(moduleKey))); - - auto sourceCode = JSSourceCode::create(vm, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); - - promise->resolve(globalObject, sourceCode); - scope.release(); - return promise; - } - case SyntheticModuleType::StringDecoder: { - auto source = JSC::SourceCode( - JSC::SyntheticSourceProvider::create(generateStringDecoderSourceCode, - JSC::SourceOrigin(), WTFMove(moduleKey))); - - auto sourceCode = JSSourceCode::create(vm, WTFMove(source)); - RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); - - promise->resolve(globalObject, sourceCode); - scope.release(); - return promise; - } - default: { - auto provider = Zig::SourceProvider::create(res.result.value); - auto jsSourceCode = JSC::JSSourceCode::create(vm, JSC::SourceCode(provider)); - promise->resolve(globalObject, jsSourceCode); - } + if (auto* internalPromise = JSC::jsDynamicCast(result)) { + return internalPromise; + } else if (auto* promise = JSC::jsDynamicCast(result)) { + return jsCast(promise); + } else { + return rejectedInternalPromise(globalObject, result); } - - // if (provider.ptr()->isBytecodeCacheEnabled()) { - // provider.ptr()->readOrGenerateByteCodeCache(vm, jsSourceCode->sourceCode()); - // } - - scope.release(); - - globalObject->vm().drainMicrotasks(); - return promise; } JSC::JSObject* GlobalObject::moduleLoaderCreateImportMetaProperties(JSGlobalObject* globalObject, diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index 6c5c23b3a..160aef714 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -35,7 +35,9 @@ class EventLoopTask; #include "BunPlugin.h" extern "C" void Bun__reportError(JSC__JSGlobalObject*, JSC__JSValue); - +// defined in ModuleLoader.cpp +extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultResolve(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame); +extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultReject(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame); // #include "EventTarget.h" // namespace WebCore { @@ -239,7 +241,10 @@ public: Bun__HTTPRequestContextDebugTLS__onResolve, Bun__HTTPRequestContextDebugTLS__onResolveStream, + jsFunctionOnLoadObjectResultResolve, + jsFunctionOnLoadObjectResultReject, }; + static constexpr size_t promiseFunctionsSize = 18; static PromiseFunctions promiseHandlerID(EncodedJSValue (*handler)(JSC__JSGlobalObject* arg0, JSC__CallFrame* arg1)) { @@ -275,6 +280,14 @@ public: return PromiseFunctions::Bun__HTTPRequestContextDebugTLS__onResolve; } else if (handler == Bun__HTTPRequestContextDebugTLS__onResolveStream) { return PromiseFunctions::Bun__HTTPRequestContextDebugTLS__onResolveStream; + } else if (handler == Bun__HTTPRequestContextDebugTLS__onResolveStream) { + return PromiseFunctions::Bun__HTTPRequestContextDebugTLS__onResolveStream; + } else if (handler == Bun__HTTPRequestContextDebugTLS__onResolveStream) { + return PromiseFunctions::Bun__HTTPRequestContextDebugTLS__onResolveStream; + } else if (handler == jsFunctionOnLoadObjectResultResolve) { + return PromiseFunctions::jsFunctionOnLoadObjectResultResolve; + } else if (handler == jsFunctionOnLoadObjectResultReject) { + return PromiseFunctions::jsFunctionOnLoadObjectResultReject; } else { RELEASE_ASSERT_NOT_REACHED(); } @@ -300,7 +313,7 @@ public: mutable WriteBarrier m_readableStreamToJSON; mutable WriteBarrier m_readableStreamToArrayBuffer; mutable WriteBarrier m_assignToStream; - mutable WriteBarrier m_thenables[16]; + mutable WriteBarrier m_thenables[promiseFunctionsSize + 1]; void trackFFIFunction(JSC::JSFunction* function) { @@ -311,6 +324,8 @@ public: BunPlugin::OnResolve onResolvePlugins[BunPluginTargetMax + 1] {}; BunPluginTarget defaultBunPluginTarget = BunPluginTargetBun; + JSC::Structure* pendingVirtualModuleResultStructure() { return m_pendingVirtualModuleResultStructure.get(this); } + // When a napi module initializes on dlopen, we need to know what the value is JSValue pendingNapiModule = JSValue {}; @@ -344,6 +359,8 @@ private: LazyProperty m_requireMap; LazyProperty m_performanceObject; + LazyProperty m_pendingVirtualModuleResultStructure; + LazyProperty m_encodeIntoObjectPrototype; // LazyProperty m_eventTarget; diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 81e9c602b..bb0718ea9 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -873,27 +873,33 @@ bool JSC__JSModuleLoader__checkSyntax(JSC__JSGlobalObject* arg0, const JSC__Sour return result; } -JSC__JSValue JSC__JSModuleLoader__evaluate(JSC__JSGlobalObject* arg0, const unsigned char* arg1, +JSC__JSValue JSC__JSModuleLoader__evaluate(JSC__JSGlobalObject* globalObject, const unsigned char* arg1, size_t arg2, const unsigned char* arg3, size_t arg4, JSC__JSValue JSValue5, JSC__JSValue* arg6) { - WTF::String src = WTF::String(WTF::StringImpl::createWithoutCopying(arg1, arg2)); - WTF::URL origin = WTF::URL::fileURLWithFileSystemPath(WTF::StringView(arg3, arg4)); + WTF::String src = WTF::String::fromUTF8(arg1, arg2).isolatedCopy(); + WTF::URL origin = WTF::URL::fileURLWithFileSystemPath(WTF::String(WTF::StringImpl::createWithoutCopying(arg3, arg4))).isolatedCopy(); - JSC::VM& vm = arg0->vm(); - JSC::JSLockHolder locker(vm); + JSC::VM& vm = globalObject->vm(); JSC::SourceCode sourceCode = JSC::makeSource( - src, JSC::SourceOrigin { origin }, origin.lastPathComponent().toStringWithoutCopying(), + src, JSC::SourceOrigin { origin }, origin.fileSystemPath(), WTF::TextPosition(), JSC::SourceProviderSourceType::Module); - WTF::NakedPtr exception; - auto val = JSC::evaluate(arg0, sourceCode, JSC::JSValue(), exception); - if (exception.get()) { - *arg6 = JSC::JSValue::encode(JSC::JSValue(exception.get())); + globalObject->moduleLoader()->provideFetch(globalObject, jsString(vm, origin.fileSystemPath()), WTFMove(sourceCode)); + auto* promise = JSC::importModule(globalObject, JSC::Identifier::fromString(vm, origin.fileSystemPath()), JSValue(), JSValue()); + + if (promise->status(vm) == JSC::JSPromise::Status::Pending) { + vm.drainMicrotasks(); } - vm.drainMicrotasks(); - return JSC::JSValue::encode(val); + if (promise->status(vm) == JSC::JSPromise::Status::Fulfilled) { + return JSC::JSValue::encode(promise->result(vm)); + } else if (promise->status(vm) == JSC::JSPromise::Status::Rejected) { + *arg6 = JSC::JSValue::encode(promise->result(vm)); + return JSC::JSValue::encode(JSC::jsUndefined()); + } else { + return JSC::JSValue::encode(promise); + } } JSC__JSInternalPromise* JSC__JSModuleLoader__importModule(JSC__JSGlobalObject* arg0, const JSC__Identifier* arg1) diff --git a/src/bun.js/bindings/headers-handwritten.h b/src/bun.js/bindings/headers-handwritten.h index 45d4752e0..36678e22e 100644 --- a/src/bun.js/bindings/headers-handwritten.h +++ b/src/bun.js/bindings/headers-handwritten.h @@ -116,6 +116,19 @@ const JSErrorCode JSErrorCodeOutOfMemoryError = 8; const JSErrorCode JSErrorCodeStackOverflow = 253; const JSErrorCode JSErrorCodeUserErrorCode = 254; +typedef uint8_t BunLoaderType; +const BunLoaderType BunLoaderTypeNone = 0; +const BunLoaderType BunLoaderTypeJSX = 1; +const BunLoaderType BunLoaderTypeJS = 2; +const BunLoaderType BunLoaderTypeTS = 3; +const BunLoaderType BunLoaderTypeTSX = 4; +const BunLoaderType BunLoaderTypeCSS = 5; +const BunLoaderType BunLoaderTypeFILE = 6; +const BunLoaderType BunLoaderTypeJSON = 7; +const BunLoaderType BunLoaderTypeTOML = 8; +const BunLoaderType BunLoaderTypeWASM = 9; +const BunLoaderType BunLoaderTypeNAPI = 10; + #pragma mark - Stream typedef uint8_t Encoding; @@ -199,6 +212,32 @@ extern "C" void ZigString__free(const unsigned char* ptr, size_t len, void* allo extern "C" void Microtask__run(void* ptr, void* global); extern "C" void Microtask__run_default(void* ptr, void* global); +extern "C" bool Bun__transpileVirtualModule( + JSC::JSGlobalObject* global, + ZigString* specifier, + ZigString* referrer, + ZigString* sourceCode, + BunLoaderType loader, + ErrorableResolvedSource* result); + +extern "C" JSC::EncodedJSValue Bun__runVirtualModule( + JSC::JSGlobalObject* global, + ZigString* specifier); + +extern "C" bool Bun__transpileFile( + void* bunVM, + JSC::JSGlobalObject* global, + ZigString* specifier, + ZigString* referrer, + ErrorableResolvedSource* result); + +extern "C" bool Bun__fetchBuiltinModule( + void* bunVM, + JSC::JSGlobalObject* global, + ZigString* specifier, + ZigString* referrer, + ErrorableResolvedSource* result); + // Used in process.version extern "C" const char* Bun__version; diff --git a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h index 75b7995f0..456ef6aa4 100644 --- a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h +++ b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h @@ -28,6 +28,7 @@ public: std::unique_ptr m_clientSubspaceForJSSink; std::unique_ptr m_clientSubspaceForStringDecoder; std::unique_ptr m_clientSubspaceForStringDecoderConstructor; + std::unique_ptr m_clientSubspaceForPendingVirtualModuleResult; #include "ZigGeneratedClasses+DOMClientIsoSubspaces.h" /* --- bun --- */ diff --git a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h index 42fb1d88b..c5e01c902 100644 --- a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h +++ b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h @@ -28,6 +28,7 @@ public: std::unique_ptr m_subspaceForJSSink; std::unique_ptr m_subspaceForStringDecoder; std::unique_ptr m_subspaceForStringDecoderConstructor; + std::unique_ptr m_subspaceForPendingVirtualModuleResult; #include "ZigGeneratedClasses+DOMIsoSubspaces.h" /*-- BUN --*/ -- cgit v1.2.3