diff options
author | 2023-01-11 14:22:31 -0800 | |
---|---|---|
committer | 2023-01-11 14:22:31 -0800 | |
commit | 4a1470d26c9d303ad9de93185e1e877d144d5592 (patch) | |
tree | 4af13d70fb642b9f987c11b654cbeaa31bf8ae2d | |
parent | 5a3b6349821a2fd9756de600c0896a76daf7bc8d (diff) | |
download | bun-4a1470d26c9d303ad9de93185e1e877d144d5592.tar.gz bun-4a1470d26c9d303ad9de93185e1e877d144d5592.tar.zst bun-4a1470d26c9d303ad9de93185e1e877d144d5592.zip |
`require.resolve` in the runtime should use CommonJS export conditions
-rw-r--r-- | src/bun.js/api/bun.zig | 21 | ||||
-rw-r--r-- | src/bun.js/bindings/ImportMetaObject.cpp | 26 | ||||
-rw-r--r-- | src/bun.js/bindings/ImportMetaObject.h | 4 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.zig | 4 | ||||
-rw-r--r-- | src/bun.js/bindings/headers-cpp.h | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.h | 2 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 53 | ||||
-rw-r--r-- | src/bun.js/modules/NodeModuleModule.cpp | 44 |
8 files changed, 103 insertions, 53 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig index e9b760de5..32bd0a9ec 100644 --- a/src/bun.js/api/bun.zig +++ b/src/bun.js/api/bun.zig @@ -942,7 +942,17 @@ fn doResolve( return null; } - return doResolveWithArgs(ctx, specifier.getZigString(ctx.ptr()), from.getZigString(ctx.ptr()), exception, false); + var is_esm = true; + if (args.nextEat()) |next| { + if (next.isBoolean()) { + is_esm = next.toBoolean(); + } else { + JSC.throwInvalidArguments("esm must be a boolean", .{}, ctx, exception); + return null; + } + } + + return doResolveWithArgs(ctx, specifier.getZigString(ctx.ptr()), from.getZigString(ctx.ptr()), exception, is_esm, false); } fn doResolveWithArgs( @@ -950,6 +960,7 @@ fn doResolveWithArgs( specifier: ZigString, from: ZigString, exception: js.ExceptionRef, + is_esm: bool, comptime is_file_path: bool, ) ?JSC.JSValue { var errorable: ErrorableZigString = undefined; @@ -960,6 +971,7 @@ fn doResolveWithArgs( ctx.ptr(), specifier, from, + is_esm, ); } else { VirtualMachine.resolveForAPI( @@ -967,6 +979,7 @@ fn doResolveWithArgs( ctx.ptr(), specifier, from, + is_esm, ); } @@ -1010,10 +1023,11 @@ export fn Bun__resolve( global: *JSGlobalObject, specifier: JSValue, source: JSValue, + is_esm: bool, ) JSC.JSValue { var exception_ = [1]JSC.JSValueRef{null}; var exception = &exception_; - const value = doResolveWithArgs(global, specifier.getZigString(global), source.getZigString(global), exception, true) orelse { + const value = doResolveWithArgs(global, specifier.getZigString(global), source.getZigString(global), exception, is_esm, true) orelse { return JSC.JSPromise.rejectedPromiseValue(global, JSC.JSValue.fromRef(exception[0])); }; return JSC.JSPromise.resolvedPromiseValue(global, value); @@ -1023,10 +1037,11 @@ export fn Bun__resolveSync( global: *JSGlobalObject, specifier: JSValue, source: JSValue, + is_esm: bool, ) JSC.JSValue { var exception_ = [1]JSC.JSValueRef{null}; var exception = &exception_; - return doResolveWithArgs(global, specifier.getZigString(global), source.getZigString(global), exception, true) orelse { + return doResolveWithArgs(global, specifier.getZigString(global), source.getZigString(global), exception, is_esm, true) orelse { return JSC.JSValue.fromRef(exception[0]); }; } diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp index 5838bde04..1c79cb1bc 100644 --- a/src/bun.js/bindings/ImportMetaObject.cpp +++ b/src/bun.js/bindings/ImportMetaObject.cpp @@ -80,7 +80,7 @@ static EncodedJSValue functionRequireResolve(JSC::JSGlobalObject* globalObject, } } - auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from); + auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from, false); auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); if (!JSC::JSValue::decode(result).isString()) { @@ -156,17 +156,18 @@ JSObject* Zig::ImportMetaObject::createRequireFunction(VM& vm, JSGlobalObject* g JSFunction* requireFunction = JSFunction::create(vm, importMetaObjectRequireCodeGenerator(vm), globalObject); auto clientData = WebCore::clientData(vm); requireFunction->putDirectCustomAccessor(vm, clientData->builtinNames().resolvePublicName(), JSC::CustomGetterSetter::create(vm, functionRequireResolveLazyGetter, functionRequireResolveLazySetter), 0); - requireFunction->putDirect(vm, clientData->builtinNames().pathPrivateName(), jsOwnedString(vm, pathString), JSC::PropertyAttribute::DontEnum | 0); + requireFunction->putDirect(vm, clientData->builtinNames().pathPublicName(), jsOwnedString(vm, pathString), JSC::PropertyAttribute::DontEnum | 0); return requireFunction; } extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) { JSC::VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); switch (callFrame->argumentCount()) { case 0: { - auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); + // not "requires" because "require" could be confusing JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync needs 1 argument (a string)"_s); scope.release(); @@ -176,13 +177,13 @@ extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* g JSC::JSValue moduleName = callFrame->argument(0); if (moduleName.isUndefinedOrNull()) { - auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync expects a string"_s); scope.release(); return JSC::JSValue::encode(JSC::JSValue {}); } JSC__JSValue from; + bool isESM = true; if (callFrame->argumentCount() > 1) { JSC::JSValue fromValue = callFrame->argument(1); @@ -195,8 +196,20 @@ extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* g fromValue = array->getIndex(globalObject, 0); } } + + if (callFrame->argumentCount() > 2) { + JSC::JSValue isESMValue = callFrame->argument(2); + if (isESMValue.isBoolean()) { + isESM = isESMValue.toBoolean(globalObject); + RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {})); + } + } + } else if (fromValue.isBoolean()) { + isESM = fromValue.toBoolean(globalObject); + RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {})); } from = JSC::JSValue::encode(fromValue); + } else { JSC::JSObject* thisObject = JSC::jsDynamicCast<JSC::JSObject*>(callFrame->thisValue()); if (UNLIKELY(!thisObject)) { @@ -210,8 +223,7 @@ extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* g from = JSC::JSValue::encode(thisObject->get(globalObject, clientData->builtinNames().pathPublicName())); } - auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from); - auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); + auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from, isESM); if (!JSC::JSValue::decode(result).isString()) { JSC::throwException(globalObject, scope, JSC::JSValue::decode(result)); @@ -266,7 +278,7 @@ JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve, from = JSC::JSValue::encode(thisObject->get(globalObject, clientData->builtinNames().pathPublicName())); } - return Bun__resolve(globalObject, JSC::JSValue::encode(moduleName), from); + return Bun__resolve(globalObject, JSC::JSValue::encode(moduleName), from, true); } } } diff --git a/src/bun.js/bindings/ImportMetaObject.h b/src/bun.js/bindings/ImportMetaObject.h index 3ce50ebbb..ff32c85d4 100644 --- a/src/bun.js/bindings/ImportMetaObject.h +++ b/src/bun.js/bindings/ImportMetaObject.h @@ -9,8 +9,8 @@ #include "JSDOMWrapperCache.h" extern "C" JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolveSync); -extern "C" EncodedJSValue Bun__resolve(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, JSC::EncodedJSValue from); -extern "C" EncodedJSValue Bun__resolveSync(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, JSC::EncodedJSValue from); +extern "C" EncodedJSValue Bun__resolve(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, JSC::EncodedJSValue from, bool is_esm); +extern "C" EncodedJSValue Bun__resolveSync(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, JSC::EncodedJSValue from, bool is_esm); namespace Zig { diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index 41a52956d..b70dd5b54 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -1339,7 +1339,7 @@ pub fn NewGlobalObject(comptime Type: type) type { } pub fn resolve(res: *ErrorableZigString, global: *JSGlobalObject, specifier: *ZigString, source: *ZigString) callconv(.C) void { if (comptime @hasDecl(Type, "resolve")) { - @call(.always_inline, Type.resolve, .{ res, global, specifier.*, source.* }); + @call(.always_inline, Type.resolve, .{ res, global, specifier.*, source.*, true }); return; } res.* = ErrorableZigString.err(error.ResolveFailed, ZigString.init(resolveNotImpl).toErrorInstance(global).asVoid()); @@ -1506,7 +1506,7 @@ pub const JSPromise = extern struct { ) JSValue { if (value.isEmpty()) { return resolvedPromiseValue(globalObject, JSValue.jsUndefined()); - } else if (value.isUndefinedOrNull() or !value.isCell()) { + } else if (value.isEmptyOrUndefinedOrNull() or !value.isCell()) { return resolvedPromiseValue(globalObject, value); } diff --git a/src/bun.js/bindings/headers-cpp.h b/src/bun.js/bindings/headers-cpp.h index 065fd8caa..a05007fff 100644 --- a/src/bun.js/bindings/headers-cpp.h +++ b/src/bun.js/bindings/headers-cpp.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1673374722 +//-- AUTOGENERATED FILE -- 1673376494 // clang-format off #pragma once diff --git a/src/bun.js/bindings/headers.h b/src/bun.js/bindings/headers.h index 4e5dabe4e..71a8d1034 100644 --- a/src/bun.js/bindings/headers.h +++ b/src/bun.js/bindings/headers.h @@ -1,5 +1,5 @@ // clang-format off -//-- AUTOGENERATED FILE -- 1673374722 +//-- AUTOGENERATED FILE -- 1673376494 #pragma once #include <stddef.h> diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index fd2ded108..410f3a776 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -891,6 +891,7 @@ pub const VirtualMachine = struct { _: *JSGlobalObject, specifier: string, source: string, + is_esm: bool, comptime is_a_file_path: bool, comptime realpath: bool, ) !void { @@ -936,7 +937,7 @@ pub const VirtualMachine = struct { jsc_vm.bundler.fs.top_level_dir, // TODO: do we need to handle things like query string params? if (strings.hasPrefixComptime(specifier, "file://")) specifier["file://".len..] else specifier, - .stmt, + if (is_esm) .stmt else .require, .read_only, )) { .success => |r| r, @@ -1012,19 +1013,53 @@ pub const VirtualMachine = struct { } } - pub fn resolveForAPI(res: *ErrorableZigString, global: *JSGlobalObject, specifier: ZigString, source: ZigString) void { - resolveMaybeNeedsTrailingSlash(res, global, specifier, source, false, true); + pub fn resolveForAPI( + res: *ErrorableZigString, + global: *JSGlobalObject, + specifier: ZigString, + source: ZigString, + is_esm: bool, + ) void { + resolveMaybeNeedsTrailingSlash(res, global, specifier, source, is_esm, false, true); } - pub fn resolveFilePathForAPI(res: *ErrorableZigString, global: *JSGlobalObject, specifier: ZigString, source: ZigString) void { - resolveMaybeNeedsTrailingSlash(res, global, specifier, source, true, true); + pub fn resolveFilePathForAPI( + res: *ErrorableZigString, + global: *JSGlobalObject, + specifier: ZigString, + source: ZigString, + is_esm: bool, + ) void { + resolveMaybeNeedsTrailingSlash(res, global, specifier, source, is_esm, true, true); + } + + pub fn resolve( + res: *ErrorableZigString, + global: *JSGlobalObject, + specifier: ZigString, + source: ZigString, + is_esm: bool, + ) void { + resolveMaybeNeedsTrailingSlash(res, global, specifier, source, is_esm, true, false); } - pub fn resolve(res: *ErrorableZigString, global: *JSGlobalObject, specifier: ZigString, source: ZigString) void { - resolveMaybeNeedsTrailingSlash(res, global, specifier, source, true, false); + fn normalizeSource(source: []const u8) []const u8 { + if (strings.hasPrefixComptime(source, "file://")) { + return source["file://".len..]; + } + + return source; } - pub fn resolveMaybeNeedsTrailingSlash(res: *ErrorableZigString, global: *JSGlobalObject, specifier: ZigString, source: ZigString, comptime is_a_file_path: bool, comptime realpath: bool) void { + pub fn resolveMaybeNeedsTrailingSlash( + res: *ErrorableZigString, + global: *JSGlobalObject, + specifier: ZigString, + source: ZigString, + is_esm: bool, + comptime is_a_file_path: bool, + comptime realpath: bool, + ) void { var result = ResolveFunctionResult{ .path = "", .result = null }; var jsc_vm = VirtualMachine.get(); if (jsc_vm.plugin_runner) |plugin_runner| { @@ -1057,7 +1092,7 @@ pub const VirtualMachine = struct { jsc_vm.bundler.linker.log = old_log; jsc_vm.bundler.resolver.log = old_log; } - _resolve(&result, global, specifier.slice(), source.slice(), is_a_file_path, realpath) catch |err_| { + _resolve(&result, global, specifier.slice(), normalizeSource(source.slice()), is_esm, is_a_file_path, realpath) catch |err_| { var err = err_; const msg: logger.Msg = brk: { var msgs: []logger.Msg = log.msgs.items; diff --git a/src/bun.js/modules/NodeModuleModule.cpp b/src/bun.js/modules/NodeModuleModule.cpp index 02e4e3849..01e061499 100644 --- a/src/bun.js/modules/NodeModuleModule.cpp +++ b/src/bun.js/modules/NodeModuleModule.cpp @@ -19,36 +19,24 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleCreateRequire, return JSC::JSValue::encode(JSC::jsUndefined()); } - Zig::ImportMetaObject *importMetaObject = Zig::ImportMetaObject::create( - globalObject, callFrame->uncheckedArgument(0)); + auto str = callFrame->uncheckedArgument(0).toStringOrNull(globalObject); + RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined())); + WTF::String val = str->value(globalObject); + auto *meta = Zig::ImportMetaObject::create(globalObject, str); auto clientData = WebCore::clientData(vm); - - RETURN_IF_EXCEPTION(scope, {}); - - if (!importMetaObject) { - throwTypeError(globalObject, scope, "Invalid path"_s); - return JSC::JSValue::encode(JSC::jsUndefined()); - } - - auto requireFunctionValue = importMetaObject->get( - globalObject, clientData->builtinNames().requirePublicName()); - RETURN_IF_EXCEPTION(scope, {}); - - JSC::JSBoundFunction *boundRequireFunction = JSC::JSBoundFunction::create( - vm, globalObject, requireFunctionValue.getObject(), importMetaObject, - nullptr, 1, jsString(vm, String("require"_s))); - RETURN_IF_EXCEPTION(scope, {}); - auto resolveFunction = importMetaObject->get( - globalObject, clientData->builtinNames().resolveSyncPublicName()); - - JSC::JSBoundFunction *boundResolveFunction = JSC::JSBoundFunction::create( - vm, globalObject, resolveFunction.getObject(), importMetaObject, nullptr, - 1, jsString(vm, String("resolve"_s))); + auto requireFunction = + Zig::ImportMetaObject::createRequireFunction(vm, globalObject, val); + auto nameStr = jsCast<JSFunction *>(requireFunction)->name(vm); + JSC::JSBoundFunction *boundRequireFunction = + JSC::JSBoundFunction::create(vm, globalObject, requireFunction, meta, + nullptr, 0, jsString(vm, nameStr)); boundRequireFunction->putDirect( - vm, clientData->builtinNames().resolvePublicName(), boundResolveFunction, - JSC::PropertyAttribute::Function | 0); + vm, clientData->builtinNames().resolvePublicName(), + requireFunction->getDirect( + vm, clientData->builtinNames().resolvePublicName()), + 0); - RELEASE_AND_RETURN(scope, JSC::JSValue::encode(boundRequireFunction)); + RELEASE_AND_RETURN(scope, JSValue::encode(boundRequireFunction)); } JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModulePaths, (JSC::JSGlobalObject * globalObject, @@ -113,7 +101,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName, auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), - JSValue::encode(callFrame->argument(1))); + JSValue::encode(callFrame->argument(1)), false); auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); if (!JSC::JSValue::decode(result).isString()) { |