mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
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>
This commit is contained in:
@@ -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<JSC::JSInternalPromise*>(internalField(2).get());
|
||||
}
|
||||
|
||||
JSC::JSPromise* PendingVirtualModuleResult::promise()
|
||||
{
|
||||
return jsCast<JSC::JSPromise*>(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<PendingVirtualModuleResult>(vm)) PendingVirtualModuleResult(vm, structure, bundlerPluginContext);
|
||||
PendingVirtualModuleResult* mod = new (NotNull, allocateCell<PendingVirtualModuleResult>(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<typename Visitor>
|
||||
@@ -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<Zig::GlobalObject*>(globalObject)->pendingVirtualModuleResultStructure(), bundlerPluginContext);
|
||||
auto* virtualModule = create(globalObject->vm(), reinterpret_cast<Zig::GlobalObject*>(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<JSC::Exception*>(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<JSC::JSPromise*>(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<bool allowPromise>
|
||||
@@ -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<bool allowPromise>
|
||||
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<PendingVirtualModuleResult*>(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<Zig::GlobalObject*>(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<PendingVirtualModuleResult*>(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<false>(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<true>(globalObject, res, specifier, referrer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user