From 126885e1fe509b69be947d79aacb3ed6efdf666a Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Tue, 25 Apr 2023 07:27:18 -0700 Subject: Implement `onResolve` plugins in `Bun.build()`, support multiple onLoad and onResolve plugins (#2739) * its 2023 * WIP `onResolve` plugins * more progress * it compiles * Lots of small fixes * Seems to work excluding entry points * Update BundlerPluginBuiltins.cpp --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> --- src/bun.js/bindings/ModuleLoader.cpp | 139 +++++------------------------------ 1 file changed, 20 insertions(+), 119 deletions(-) (limited to 'src/bun.js/bindings/ModuleLoader.cpp') diff --git a/src/bun.js/bindings/ModuleLoader.cpp b/src/bun.js/bindings/ModuleLoader.cpp index 00b975d88..40e41b083 100644 --- a/src/bun.js/bindings/ModuleLoader.cpp +++ b/src/bun.js/bindings/ModuleLoader.cpp @@ -40,56 +40,7 @@ namespace Bun { using namespace Zig; using namespace WebCore; -extern "C" BunLoaderType Bun__getDefaultLoader(JSC::JSGlobalObject*, const ZigString* specifier); -extern "C" BunLoaderType JSBundlerPlugin__getDefaultLoader(void* context); -extern "C" void JSBundlerPlugin__OnLoadAsync(void* ctx, EncodedJSValue errorValue, ZigString* sourceCode, BunLoaderType loader); -OnLoadResult handleOnLoadResult(Zig::GlobalObject* globalObject, JSC::JSValue objectValue, const ZigString* specifier, void* context); - -JSValue handleVirtualModuleResultForJSBundlerPlugin( - Zig::GlobalObject* globalObject, - JSValue virtualModuleResult, - const ZigString* specifier, - const ZigString* referrer, - void* bundlerPluginContext) -{ - auto onLoadResult = handleOnLoadResult(globalObject, virtualModuleResult, specifier, bundlerPluginContext); - JSC::VM& vm = globalObject->vm(); - - switch (onLoadResult.type) { - case OnLoadResultTypeCode: { - JSBundlerPlugin__OnLoadAsync(bundlerPluginContext, JSValue::encode({}), &onLoadResult.value.sourceText.string, onLoadResult.value.sourceText.loader); - return jsUndefined(); - } - case OnLoadResultTypeError: { - JSBundlerPlugin__OnLoadAsync(bundlerPluginContext, JSValue::encode(onLoadResult.value.error), nullptr, BunLoaderTypeNone); - return jsUndefined(); - } - - case OnLoadResultTypePromise: { - JSFunction* performPromiseThenFunction = globalObject->performPromiseThenFunction(); - auto callData = JSC::getCallData(performPromiseThenFunction); - ASSERT(callData.type != CallData::Type::None); - auto specifierString = Zig::toString(*specifier); - auto referrerString = referrer ? Zig::toString(*referrer) : String(); - PendingVirtualModuleResult* pendingModule = PendingVirtualModuleResult::create(globalObject, specifierString, referrerString, bundlerPluginContext); - pendingModule->internalField(2).set(vm, pendingModule, virtualModuleResult); - JSC::JSPromise* promise = pendingModule->promise(); - - MarkedArgumentBuffer arguments; - arguments.append(promise); - arguments.append(globalObject->thenable(jsFunctionOnLoadObjectResultResolveForJSBundlerPlugin)); - arguments.append(globalObject->thenable(jsFunctionOnLoadObjectResultRejectForJSBundlerPlugin)); - arguments.append(jsUndefined()); - arguments.append(pendingModule); - ASSERT(!arguments.hasOverflowed()); - JSC::call(globalObject, performPromiseThenFunction, callData, jsUndefined(), arguments); - return promise; - } - default: { - __builtin_unreachable(); - } - } -} +extern "C" BunLoaderType Bun__getDefaultLoader(JSC::JSGlobalObject*, ZigString* specifier); static JSC::JSInternalPromise* rejectedInternalPromise(JSC::JSGlobalObject* globalObject, JSC::JSValue value) { @@ -137,16 +88,11 @@ JSC::JSInternalPromise* PendingVirtualModuleResult::internalPromise() return jsCast(internalField(2).get()); } -JSC::JSPromise* PendingVirtualModuleResult::promise() -{ - 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, void* bundlerPluginContext) +PendingVirtualModuleResult* PendingVirtualModuleResult::create(VM& vm, Structure* structure) { - PendingVirtualModuleResult* mod = new (NotNull, allocateCell(vm)) PendingVirtualModuleResult(vm, structure, bundlerPluginContext); + PendingVirtualModuleResult* mod = new (NotNull, allocateCell(vm)) PendingVirtualModuleResult(vm, structure); return mod; } Structure* PendingVirtualModuleResult::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) @@ -154,9 +100,8 @@ Structure* PendingVirtualModuleResult::createStructure(VM& vm, JSGlobalObject* g return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info()); } -PendingVirtualModuleResult::PendingVirtualModuleResult(VM& vm, Structure* structure, void* bundlerPluginContext) +PendingVirtualModuleResult::PendingVirtualModuleResult(VM& vm, Structure* structure) : Base(vm, structure) - , m_bundlerPluginContext(bundlerPluginContext) { } @@ -165,9 +110,7 @@ void PendingVirtualModuleResult::finishCreation(VM& vm, const WTF::String& speci Base::finishCreation(vm); Base::internalField(0).set(vm, this, JSC::jsString(vm, specifier)); Base::internalField(1).set(vm, this, JSC::jsString(vm, referrer)); - if (!this->m_bundlerPluginContext) { - Base::internalField(2).set(vm, this, JSC::JSInternalPromise::create(vm, globalObject()->internalPromiseStructure())); - } + Base::internalField(2).set(vm, this, JSC::JSInternalPromise::create(vm, globalObject()->internalPromiseStructure())); } template @@ -180,22 +123,21 @@ void PendingVirtualModuleResult::visitChildrenImpl(JSCell* cell, Visitor& visito DEFINE_VISIT_CHILDREN(PendingVirtualModuleResult); -PendingVirtualModuleResult* PendingVirtualModuleResult::create(JSC::JSGlobalObject* globalObject, const WTF::String& specifier, const WTF::String& referrer, void* bundlerPluginContext) +PendingVirtualModuleResult* PendingVirtualModuleResult::create(JSC::JSGlobalObject* globalObject, const WTF::String& specifier, const WTF::String& referrer) { - auto* virtualModule = create(globalObject->vm(), reinterpret_cast(globalObject)->pendingVirtualModuleResultStructure(), bundlerPluginContext); + 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, const ZigString* specifier, void* bunPluginContext) +OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC::JSValue objectValue, ZigString* specifier) { OnLoadResult result = {}; result.type = OnLoadResultTypeError; - result.bundlerPluginContext = bunPluginContext; JSC::VM& vm = globalObject->vm(); result.value.error = JSC::jsUndefined(); auto scope = DECLARE_THROW_SCOPE(vm); - BunLoaderType loader = bunPluginContext ? JSBundlerPlugin__getDefaultLoader(bunPluginContext) : Bun__getDefaultLoader(globalObject, specifier); + BunLoaderType loader = Bun__getDefaultLoader(globalObject, specifier); if (JSC::Exception* exception = JSC::jsDynamicCast(objectValue)) { result.value.error = exception->value(); @@ -269,17 +211,16 @@ OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC:: return result; } -OnLoadResult handleOnLoadResult(Zig::GlobalObject* globalObject, JSC::JSValue objectValue, const ZigString* specifier, void* context) +static OnLoadResult handleOnLoadResult(Zig::GlobalObject* globalObject, JSC::JSValue objectValue, ZigString* specifier) { if (JSC::JSPromise* promise = JSC::jsDynamicCast(objectValue)) { OnLoadResult result = {}; result.type = OnLoadResultTypePromise; result.value.promise = objectValue; - result.bundlerPluginContext = context; return result; } - return handleOnLoadResultNotPromise(globalObject, objectValue, specifier, context); + return handleOnLoadResultNotPromise(globalObject, objectValue, specifier); } template @@ -287,10 +228,10 @@ static JSValue handleVirtualModuleResult( Zig::GlobalObject* globalObject, JSValue virtualModuleResult, ErrorableResolvedSource* res, - const ZigString* specifier, - const ZigString* referrer) + ZigString* specifier, + ZigString* referrer) { - auto onLoadResult = handleOnLoadResult(globalObject, virtualModuleResult, specifier, nullptr); + auto onLoadResult = handleOnLoadResult(globalObject, virtualModuleResult, specifier); JSC::VM& vm = globalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); @@ -412,8 +353,8 @@ template static JSValue fetchSourceCode( Zig::GlobalObject* globalObject, ErrorableResolvedSource* res, - const ZigString* specifier, - const ZigString* referrer) + ZigString* specifier, + ZigString* referrer) { void* bunVM = globalObject->bunVM(); auto& vm = globalObject->vm(); @@ -545,46 +486,6 @@ static JSValue fetchSourceCode( return rejectOrResolve(JSC::JSSourceCode::create(vm, JSC::SourceCode(WTFMove(provider)))); } -extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultResolveForJSBundlerPlugin(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()); - void* bunPluginContext = pendingModule->m_bundlerPluginContext; - JSC::JSPromise* promise = pendingModule->promise(); - - ZigString specifier = Zig::toZigString(specifierString, globalObject); - ZigString referrer = Zig::toZigString(referrerString, globalObject); - return JSC::JSValue::encode( - handleVirtualModuleResultForJSBundlerPlugin(reinterpret_cast(globalObject), objectResult, &specifier, &referrer, bunPluginContext)); -} - -extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultRejectForJSBundlerPlugin(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()); - - ZigString specifier = Zig::toZigString(specifierString, globalObject); - ZigString referrer = Zig::toZigString(referrerString, globalObject); - pendingModule->internalField(2).set(vm, pendingModule, JSC::jsUndefined()); - - JSBundlerPlugin__OnLoadAsync(pendingModule->m_bundlerPluginContext, JSValue::encode(reason), nullptr, BunLoaderTypeNone); - - return JSValue::encode(reason); -} - extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultResolve(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) { JSC::VM& vm = globalObject->vm(); @@ -643,8 +544,8 @@ extern "C" JSC::EncodedJSValue jsFunctionOnLoadObjectResultReject(JSC::JSGlobalO JSValue fetchSourceCodeSync( Zig::GlobalObject* globalObject, ErrorableResolvedSource* res, - const ZigString* specifier, - const ZigString* referrer) + ZigString* specifier, + ZigString* referrer) { return fetchSourceCode(globalObject, res, specifier, referrer); } @@ -652,8 +553,8 @@ JSValue fetchSourceCodeSync( JSValue fetchSourceCodeAsync( Zig::GlobalObject* globalObject, ErrorableResolvedSource* res, - const ZigString* specifier, - const ZigString* referrer) + ZigString* specifier, + ZigString* referrer) { return fetchSourceCode(globalObject, res, specifier, referrer); } -- cgit v1.2.3