diff options
author | 2022-09-03 21:48:06 -0700 | |
---|---|---|
committer | 2022-09-03 21:48:06 -0700 | |
commit | 04cc1968dbe7947b63b93d800ecc1747dc11eb5f (patch) | |
tree | 136f3d7f45c5df03befdf0caa4b311fc0bcf6ea1 | |
parent | 4891be8d0d551fb4ee12510f63fed592f8bd8fc2 (diff) | |
download | bun-04cc1968dbe7947b63b93d800ecc1747dc11eb5f.tar.gz bun-04cc1968dbe7947b63b93d800ecc1747dc11eb5f.tar.zst bun-04cc1968dbe7947b63b93d800ecc1747dc11eb5f.zip |
Fix `createRequire()` in `node:module`
Fixes https://github.com/oven-sh/bun/issues/831
Fixes https://github.com/oven-sh/bun/issues/453
-rw-r--r-- | Makefile | 33 | ||||
-rw-r--r-- | src/bun.js/bindings/ImportMetaObject.cpp | 19 | ||||
-rw-r--r-- | src/bun.js/bindings/ImportMetaObject.h | 47 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 72 | ||||
-rw-r--r-- | src/bun.js/bindings/headers-handwritten.h | 1 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 58 | ||||
-rw-r--r-- | src/bun.js/module.exports.js | 72 | ||||
-rw-r--r-- | src/bun.js/modules/NodeModuleModule.cpp | 138 | ||||
-rw-r--r-- | src/bun.js/modules/NodeModuleModule.h | 12 | ||||
-rw-r--r-- | test/bun.js/import-meta.test.js | 11 |
10 files changed, 302 insertions, 161 deletions
@@ -235,11 +235,13 @@ HOMEBREW_PREFIX ?= $(BREW_PREFIX_PATH) SRC_DIR := src/bun.js/bindings +MODULES_DIR := src/bun.js/modules OBJ_DIR ?= src/bun.js/bindings-obj DEBUG_OBJ_DIR := src/bun.js/debug-bindings-obj SRC_PATH := $(realpath $(SRC_DIR)) SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp) +MODULES_FILES := $(wildcard $(MODULES_DIR)/*.cpp) SRC_WEBCORE_FILES := $(wildcard $(SRC_DIR)/webcore/*.cpp) SRC_SQLITE_FILES := $(wildcard $(SRC_DIR)/sqlite/*.cpp) SRC_NODE_OS_FILES := $(wildcard $(SRC_DIR)/node_os/*.cpp) @@ -252,7 +254,7 @@ SQLITE_OBJ_FILES := $(patsubst $(SRC_DIR)/sqlite/%.cpp,$(OBJ_DIR)/%.o,$(SRC_SQLI NODE_OS_OBJ_FILES := $(patsubst $(SRC_DIR)/node_os/%.cpp,$(OBJ_DIR)/%.o,$(SRC_NODE_OS_FILES)) BUILTINS_OBJ_FILES := $(patsubst src/bun.js/builtins/%.cpp,$(OBJ_DIR)/%.o,$(SRC_BUILTINS_FILES)) IO_FILES := $(patsubst src/io/%.cpp,$(OBJ_DIR)/%.o,$(SRC_IO_FILES)) - +MODULES_OBJ_FILES := $(patsubst $(MODULES_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(MODULES_FILES)) DEBUG_OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(DEBUG_OBJ_DIR)/%.o,$(SRC_FILES)) DEBUG_WEBCORE_OBJ_FILES := $(patsubst $(SRC_DIR)/webcore/%.cpp,$(DEBUG_OBJ_DIR)/%.o,$(SRC_WEBCORE_FILES)) @@ -260,9 +262,10 @@ DEBUG_SQLITE_OBJ_FILES := $(patsubst $(SRC_DIR)/sqlite/%.cpp,$(DEBUG_OBJ_DIR)/%. DEBUG_NODE_OS_OBJ_FILES := $(patsubst $(SRC_DIR)/node_os/%.cpp,$(DEBUG_OBJ_DIR)/%.o,$(SRC_NODE_OS_FILES)) DEBUG_BUILTINS_OBJ_FILES := $(patsubst src/bun.js/builtins/%.cpp,$(DEBUG_OBJ_DIR)/%.o,$(SRC_BUILTINS_FILES)) DEBUG_IO_FILES := $(patsubst src/io/%.cpp,$(DEBUG_OBJ_DIR)/%.o,$(SRC_IO_FILES)) +DEBUG_MODULES_OBJ_FILES := $(patsubst $(MODULES_DIR)/%.cpp,$(DEBUG_OBJ_DIR)/%.o,$(MODULES_FILES)) -BINDINGS_OBJ := $(OBJ_FILES) $(WEBCORE_OBJ_FILES) $(SQLITE_OBJ_FILES) $(NODE_OS_OBJ_FILES) $(BUILTINS_OBJ_FILES) $(IO_FILES) -DEBUG_BINDINGS_OBJ := $(DEBUG_OBJ_FILES) $(DEBUG_WEBCORE_OBJ_FILES) $(DEBUG_SQLITE_OBJ_FILES) $(DEBUG_NODE_OS_OBJ_FILES) $(DEBUG_BUILTINS_OBJ_FILES) $(DEBUG_IO_FILES) +BINDINGS_OBJ := $(OBJ_FILES) $(WEBCORE_OBJ_FILES) $(SQLITE_OBJ_FILES) $(NODE_OS_OBJ_FILES) $(BUILTINS_OBJ_FILES) $(IO_FILES) $(MODULES_OBJ_FILES) +DEBUG_BINDINGS_OBJ := $(DEBUG_OBJ_FILES) $(DEBUG_WEBCORE_OBJ_FILES) $(DEBUG_SQLITE_OBJ_FILES) $(DEBUG_NODE_OS_OBJ_FILES) $(DEBUG_BUILTINS_OBJ_FILES) $(DEBUG_IO_FILES) $(DEBUG_MODULES_OBJ_FILES) MAC_INCLUDE_DIRS := -I$(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders \ -I$(WEBKIT_RELEASE_DIR)/WTF/Headers \ @@ -1305,12 +1308,12 @@ clean: clean-bindings (cd $(BUN_DEPS_DIR)/zlib && make clean) || echo ""; .PHONY: release-bindings -release-bindings: $(OBJ_DIR) $(OBJ_FILES) $(WEBCORE_OBJ_FILES) $(SQLITE_OBJ_FILES) $(NODE_OS_OBJ_FILES) $(BUILTINS_OBJ_FILES) $(IO_FILES) +release-bindings: $(OBJ_DIR) $(OBJ_FILES) $(WEBCORE_OBJ_FILES) $(SQLITE_OBJ_FILES) $(NODE_OS_OBJ_FILES) $(BUILTINS_OBJ_FILES) $(IO_FILES) $(MODULES_OBJ_FILES) # Do not add $(DEBUG_DIR) to this list # It will break caching, causing you to have to wait for every .cpp file to rebuild. .PHONY: bindings -bindings: $(DEBUG_OBJ_FILES) $(DEBUG_WEBCORE_OBJ_FILES) $(DEBUG_SQLITE_OBJ_FILES) $(DEBUG_NODE_OS_OBJ_FILES) $(DEBUG_BUILTINS_OBJ_FILES) $(DEBUG_IO_FILES) +bindings: $(DEBUG_OBJ_FILES) $(DEBUG_WEBCORE_OBJ_FILES) $(DEBUG_SQLITE_OBJ_FILES) $(DEBUG_NODE_OS_OBJ_FILES) $(DEBUG_BUILTINS_OBJ_FILES) $(DEBUG_IO_FILES) $(DEBUG_MODULES_OBJ_FILES) .PHONY: jsc-bindings-mac jsc-bindings-mac: bindings @@ -1471,6 +1474,16 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(EMIT_LLVM) \ -c -o $@ $< +$(OBJ_DIR)/%.o: src/bun.js/modules/%.cpp + $(CXX) $(CLANG_FLAGS) $(UWS_INCLUDE) \ + $(MACOS_MIN_FLAG) \ + $(OPTIMIZATION_LEVEL) \ + -fno-exceptions \ + -fno-rtti \ + -ferror-limit=1000 \ + $(EMIT_LLVM) \ + -c -o $@ $< + $(OBJ_DIR)/%.o: $(SRC_DIR)/webcore/%.cpp $(CXX) $(CLANG_FLAGS) \ $(MACOS_MIN_FLAG) \ @@ -1592,6 +1605,16 @@ $(DEBUG_OBJ_DIR)/%.o: src/bun.js/builtins/%.cpp $(EMIT_LLVM_FOR_DEBUG) \ -g3 -c -o $@ $< +$(DEBUG_OBJ_DIR)/%.o: src/bun.js/modules/%.cpp + $(CXX) $(CLANG_FLAGS) \ + $(MACOS_MIN_FLAG) \ + $(DEBUG_OPTIMIZATION_LEVEL) \ + -fno-exceptions \ + -fno-rtti \ + -ferror-limit=1000 \ + $(EMIT_LLVM_FOR_DEBUG) \ + -g3 -c -o $@ $< + sizegen: mkdir -p $(BUN_TMP_DIR) $(CXX) src/bun.js/headergen/sizegen.cpp -Wl,-dead_strip -Wl,-dead_strip_dylibs -fuse-ld=lld -o $(BUN_TMP_DIR)/sizegen $(CLANG_FLAGS) -O1 diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp index 67ca4acc6..ba1617aa4 100644 --- a/src/bun.js/bindings/ImportMetaObject.cpp +++ b/src/bun.js/bindings/ImportMetaObject.cpp @@ -35,6 +35,7 @@ #include "JSBufferConstructorBuiltins.h" #include "JavaScriptCore/JSBase.h" +#include "JSDOMURL.h" #include "JavaScriptCore/JSNativeStdFunction.h" namespace Zig { @@ -133,6 +134,24 @@ JSC_DEFINE_CUSTOM_GETTER(functionRequireResolveLazyGetter, return JSValue::encode(JSValue(resolverFunction)); } +Zig::ImportMetaObject* Zig::ImportMetaObject::create(JSC::JSGlobalObject* globalObject, JSValue key) +{ + if (WebCore::DOMURL* domURL = WebCoreCast<WebCore::JSDOMURL, WebCore__DOMURL>(JSValue::encode(key))) { + return create(globalObject, JSC::jsString(globalObject->vm(), domURL->href().fileSystemPath())); + } + + auto* keyString = key.toStringOrNull(globalObject); + if (UNLIKELY(!keyString)) { + return nullptr; + } + + if (keyString->value(globalObject).startsWith("file://"_s)) { + return create(globalObject, JSC::jsString(globalObject->vm(), WTF::URL(keyString->value(globalObject)).fileSystemPath())); + } + + return create(globalObject, keyString); +} + JSObject* Zig::ImportMetaObject::createRequireFunction(VM& vm, JSGlobalObject* globalObject, WTF::String& pathString) { JSFunction* requireFunction = JSFunction::create(vm, importMetaObjectRequireCodeGenerator(vm), globalObject); diff --git a/src/bun.js/bindings/ImportMetaObject.h b/src/bun.js/bindings/ImportMetaObject.h index 7527dcb51..4511e4d6e 100644 --- a/src/bun.js/bindings/ImportMetaObject.h +++ b/src/bun.js/bindings/ImportMetaObject.h @@ -6,6 +6,8 @@ #include "BunClientData.h" #include "ZigGlobalObject.h" +#include "JSDOMWrapperCache.h" + namespace Zig { using namespace JSC; @@ -22,6 +24,51 @@ public: return ptr; } + static ImportMetaObject* create(JSC::JSGlobalObject* globalObject, JSC::JSValue key); + static inline Zig::ImportMetaObject* create(JSC::JSGlobalObject* globalObject, JSC::JSString* keyString) + { + auto& vm = globalObject->vm(); + auto view = keyString->value(globalObject); + JSC::Structure* structure = WebCore::getDOMStructure<Zig::ImportMetaObject>(vm, *reinterpret_cast<Zig::GlobalObject*>(globalObject)); + Zig::ImportMetaObject* metaProperties = Zig::ImportMetaObject::create(vm, globalObject, structure); + if (UNLIKELY(!metaProperties)) { + return nullptr; + } + + auto clientData = WebCore::clientData(vm); + auto& builtinNames = clientData->builtinNames(); + + auto index = view.reverseFind('/', view.length()); + if (index != WTF::notFound) { + metaProperties->putDirect(vm, builtinNames.dirPublicName(), + JSC::jsSubstring(globalObject, keyString, 0, index)); + metaProperties->putDirect( + vm, builtinNames.filePublicName(), + JSC::jsSubstring(globalObject, keyString, index + 1, view.length() - index - 1)); + } else { + metaProperties->putDirect(vm, builtinNames.filePublicName(), keyString); + } + metaProperties->putDirect( + vm, + builtinNames.pathPublicName(), + keyString, + 0); + + metaProperties->putDirect( + vm, + builtinNames.requirePublicName(), + Zig::ImportMetaObject::createRequireFunction(vm, globalObject, view), + PropertyAttribute::Builtin | PropertyAttribute::Function | 0); + + if (view.startsWith('/')) { + metaProperties->putDirect(vm, builtinNames.urlPublicName(), JSC::JSValue(JSC::jsString(vm, WTF::URL::fileURLWithFileSystemPath(view).string()))); + } else { + metaProperties->putDirect(vm, builtinNames.urlPublicName(), keyString); + } + + return metaProperties; + } + DECLARE_INFO; static constexpr bool needsDestruction = true; diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index d378a0f4c..31abac3c3 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -165,6 +165,7 @@ using JSBuffer = WebCore::JSBuffer; #include "../modules/ProcessModule.h" #include "../modules/StringDecoderModule.h" #include "../modules/ObjectModule.h" +#include "../modules/NodeModuleModule.h" // #include <iostream> static bool has_loaded_jsc = false; @@ -2630,6 +2631,7 @@ JSC::JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* g static JSC_DEFINE_HOST_FUNCTION(functionFulfillModuleSync, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) { + auto& vm = globalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSC::JSValue key = callFrame->argument(0); @@ -2702,6 +2704,16 @@ static JSC_DEFINE_HOST_FUNCTION(functionFulfillModuleSync, 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( @@ -2790,6 +2802,19 @@ JSC::JSInternalPromise* GlobalObject::moduleLoaderFetch(JSGlobalObject* globalOb 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, @@ -2863,50 +2888,11 @@ JSC::JSObject* GlobalObject::moduleLoaderCreateImportMetaProperties(JSGlobalObje { JSC::VM& vm = globalObject->vm(); - auto scope = DECLARE_THROW_SCOPE(vm); - - JSString* keyString = key.toStringOrNull(globalObject); - auto view = keyString->value(globalObject); - if (UNLIKELY(!keyString)) { - RELEASE_AND_RETURN(scope, JSC::constructEmptyObject(globalObject)); - } - - JSC::Structure* structure = WebCore::getDOMStructure<Zig::ImportMetaObject>(vm, *reinterpret_cast<Zig::GlobalObject*>(globalObject)); - Zig::ImportMetaObject* metaProperties = Zig::ImportMetaObject::create(vm, globalObject, structure); - RETURN_IF_EXCEPTION(scope, nullptr); - - auto clientData = WebCore::clientData(vm); - auto& builtinNames = clientData->builtinNames(); - - auto index = view.reverseFind('/', view.length()); - if (index != WTF::notFound) { - metaProperties->putDirect(vm, builtinNames.dirPublicName(), - JSC::jsSubstring(globalObject, keyString, 0, index)); - metaProperties->putDirect( - vm, builtinNames.filePublicName(), - JSC::jsSubstring(globalObject, keyString, index + 1, keyString->length() - index - 1)); - } else { - metaProperties->putDirect(vm, builtinNames.filePublicName(), keyString); - } - metaProperties->putDirect( - vm, - builtinNames.pathPublicName(), - keyString, - 0); - - metaProperties->putDirect( - vm, - builtinNames.requirePublicName(), - Zig::ImportMetaObject::createRequireFunction(vm, globalObject, view), - PropertyAttribute::Builtin | PropertyAttribute::Function | 0); - - if (view.startsWith('/')) { - metaProperties->putDirect(vm, builtinNames.urlPublicName(), JSC::JSValue(JSC::jsString(vm, WTF::URL::fileURLWithFileSystemPath(view).string()))); - } else { - metaProperties->putDirect(vm, builtinNames.urlPublicName(), keyString); - } + JSC::JSString* keyString = key.toStringOrNull(globalObject); + if (UNLIKELY(!keyString)) + return JSC::constructEmptyObject(globalObject); - RELEASE_AND_RETURN(scope, metaProperties); + return Zig::ImportMetaObject::create(globalObject, keyString); } JSC::JSValue GlobalObject::moduleLoaderEvaluate(JSGlobalObject* globalObject, diff --git a/src/bun.js/bindings/headers-handwritten.h b/src/bun.js/bindings/headers-handwritten.h index 69b4934e9..45d4752e0 100644 --- a/src/bun.js/bindings/headers-handwritten.h +++ b/src/bun.js/bindings/headers-handwritten.h @@ -190,6 +190,7 @@ enum SyntheticModuleType : uint64_t { Process = 1025, Events = 1026, StringDecoder = 1027, + Module = 1028, }; extern "C" ZigErrorCode Zig_ErrorCodeParserError; diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 6da062b23..54486e38a 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -685,6 +685,7 @@ pub const VirtualMachine = struct { return this != .transpile; } }; + fn _fetch( jsc_vm: *VirtualMachine, globalObject: *JSGlobalObject, @@ -818,16 +819,10 @@ pub const VirtualMachine = struct { .hash = 0, }; }, - .@"node:buffer" => { - return ResolvedSource{ - .allocator = null, - .source_code = ZigString.init(""), - .specifier = ZigString.init("node:buffer"), - .source_url = ZigString.init("node:buffer"), - .hash = 0, - .tag = ResolvedSource.Tag.@"node:buffer", - }; - }, + .@"node:buffer" => return jsSyntheticModule(.@"node:buffer"), + .@"node:string_decoder" => return jsSyntheticModule(.@"node:string_decoder"), + .@"node:module" => return jsSyntheticModule(.@"node:module"), + .@"node:events" => return jsSyntheticModule(.@"node:events"), .@"node:stream" => { return ResolvedSource{ .allocator = null, @@ -837,16 +832,7 @@ pub const VirtualMachine = struct { .hash = 0, }; }, - .@"node:events" => { - return ResolvedSource{ - .allocator = null, - .source_code = ZigString.init(""), - .specifier = ZigString.init("node:events"), - .source_url = ZigString.init("node:events"), - .hash = 0, - .tag = ResolvedSource.Tag.@"node:events", - }; - }, + .@"node:fs/promises" => { return ResolvedSource{ .allocator = null, @@ -884,16 +870,6 @@ pub const VirtualMachine = struct { .hash = 0, }; }, - .@"node:string_decoder" => { - return ResolvedSource{ - .allocator = null, - .source_code = ZigString.init(""), - .specifier = ZigString.init("node:string_decoder"), - .source_url = ZigString.init("node:string_decoder"), - .hash = 0, - .tag = ResolvedSource.Tag.@"node:string_decoder", - }; - }, .@"bun:ffi" => { return ResolvedSource{ .allocator = null, @@ -943,17 +919,6 @@ pub const VirtualMachine = struct { .hash = 0, }; }, - .@"node:module" => { - return ResolvedSource{ - .allocator = null, - .source_code = ZigString.init( - @as(string, jsModuleFromFile("./module.exports.js")), - ), - .specifier = ZigString.init("node:module"), - .source_url = ZigString.init("node:module"), - .hash = 0, - }; - }, .@"node:perf_hooks" => { return ResolvedSource{ .allocator = null, @@ -3123,3 +3088,14 @@ fn jsModuleFromFile(comptime input: string) string { var contents = file.readToEndAlloc(bun.default_allocator, std.math.maxInt(usize)) catch @panic("Cannot read file: " ++ absolute_path); return contents; } + +inline fn jsSyntheticModule(comptime name: ResolvedSource.Tag) ResolvedSource { + return ResolvedSource{ + .allocator = null, + .source_code = ZigString.init(""), + .specifier = ZigString.init(@tagName(name)), + .source_url = ZigString.init(@tagName(name)), + .hash = 0, + .tag = name, + }; +} diff --git a/src/bun.js/module.exports.js b/src/bun.js/module.exports.js deleted file mode 100644 index 856f75875..000000000 --- a/src/bun.js/module.exports.js +++ /dev/null @@ -1,72 +0,0 @@ -var fileURLToPath; - -var pathsFunction = function paths() { - return []; -}; - -export function createRequire(filename) { - var filenameString = filename; - const isURL = - typeof filename === "object" && filename && filename instanceof URL; - - if (isURL) { - fileURLToPath ||= globalThis[Symbol.for("Bun.lazy")]("fileURLToPath"); - filenameString = fileURLToPath(filename); - } - - var pathObject = { - path: filenameString, - resolveSync, - }; - var bunResolveSync = import.meta.resolveSync; - var realRequire = import.meta.require; - - function resolveSync(id) { - return arguments.length <= 1 - ? bunResolveSync.call(pathObject, id) - : bunResolveSync.call(pathObject, id, arguments[1]); - } - - var requireFunction = function require(id) { - return realRequire.call( - pathObject, - bunResolveSync.call(pathObject, id, filenameString) - ); - }; - - requireFunction.resolve = function resolve(id, pathsArg) { - if (arguments.length > 1 && pathsArg && typeof pathsArg === "object") { - var { paths } = pathsArg; - if (paths && Array.isArray(paths) && paths.length > 0) { - return bunResolveSync.call(pathObject, id, paths[0]); - } - } - - return bunResolveSync.call(pathObject, id); - }; - requireFunction.resolve.paths = pathsFunction; - requireFunction.main = undefined; - - return requireFunction; -} - -// this isn't exhaustive -export const builtinModules = ["node:path", "node:fs", "bun:ffi", "bun:sqlite"]; - -// noop -export function syncBuiltinESMExports() {} - -export function findSourceMap(path) { - throw new Error("findSourceMap is not implemented"); -} - -export function SourceMap() { - throw new Error("SourceMap is not implemented"); -} - -export default { - createRequire, - syncBuiltinESMExports, - findSourceMap, - SourceMap, -}; diff --git a/src/bun.js/modules/NodeModuleModule.cpp b/src/bun.js/modules/NodeModuleModule.cpp new file mode 100644 index 000000000..319d18478 --- /dev/null +++ b/src/bun.js/modules/NodeModuleModule.cpp @@ -0,0 +1,138 @@ +#include "root.h" + +#include "./NodeModuleModule.h" + +#include "ImportMetaObject.h" +#include "JavaScriptCore/JSBoundFunction.h" + +using namespace Zig; +using namespace JSC; + +JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleCreateRequire, + (JSC::JSGlobalObject * globalObject, + JSC::CallFrame *callFrame)) { + JSC::VM &vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + if (callFrame->argumentCount() < 1) { + throwTypeError(globalObject, scope, + "createRequire() requires at least one argument"_s); + return JSC::JSValue::encode(JSC::jsUndefined()); + } + + Zig::ImportMetaObject *importMetaObject = Zig::ImportMetaObject::create( + globalObject, callFrame->uncheckedArgument(0)); + 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))); + boundRequireFunction->putDirect( + vm, clientData->builtinNames().resolvePublicName(), boundResolveFunction, + JSC::PropertyAttribute::Function | 0); + + RELEASE_AND_RETURN(scope, JSC::JSValue::encode(boundRequireFunction)); +} +JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModulePaths, + (JSC::JSGlobalObject * globalObject, + JSC::CallFrame *callFrame)) { + return JSC::JSValue::encode(JSC::JSArray::create(globalObject->vm(), 0)); +} + +JSC_DEFINE_HOST_FUNCTION(jsFunctionFindSourceMap, + (JSGlobalObject * globalObject, + CallFrame *callFrame)) { + auto &vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + throwException(globalObject, scope, + createError(globalObject, "Not implemented"_s)); + return JSValue::encode(jsUndefined()); +} + +JSC_DEFINE_HOST_FUNCTION(jsFunctionSyncBuiltinExports, + (JSGlobalObject * globalObject, + CallFrame *callFrame)) { + return JSValue::encode(jsUndefined()); +} + +JSC_DEFINE_HOST_FUNCTION(jsFunctionSourceMap, (JSGlobalObject * globalObject, + CallFrame *callFrame)) { + auto &vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + throwException(globalObject, scope, + createError(globalObject, "Not implemented"_s)); + return JSValue::encode(jsUndefined()); +} + +namespace Zig { + +void generateNodeModuleModule(JSC::JSGlobalObject *globalObject, + JSC::Identifier moduleKey, + Vector<JSC::Identifier, 4> &exportNames, + JSC::MarkedArgumentBuffer &exportValues) { + JSC::VM &vm = globalObject->vm(); + + exportValues.append(JSFunction::create( + vm, globalObject, 1, String("createRequire"_s), + jsFunctionNodeModuleCreateRequire, ImplementationVisibility::Public)); + exportValues.append(JSFunction::create(vm, globalObject, 1, String("paths"_s), + jsFunctionNodeModulePaths, + ImplementationVisibility::Public)); + exportValues.append(JSFunction::create( + vm, globalObject, 1, String("findSourceMap"_s), jsFunctionFindSourceMap, + ImplementationVisibility::Public)); + exportValues.append(JSFunction::create( + vm, globalObject, 0, String("syncBuiltinExports"_s), + jsFunctionSyncBuiltinExports, ImplementationVisibility::Public)); + exportValues.append( + JSFunction::create(vm, globalObject, 1, String("SourceMap"_s), + jsFunctionSourceMap, ImplementationVisibility::Public, + NoIntrinsic, jsFunctionSourceMap, nullptr)); + + exportNames.append(JSC::Identifier::fromString(vm, "createRequire"_s)); + exportNames.append(JSC::Identifier::fromString(vm, "paths"_s)); + exportNames.append(JSC::Identifier::fromString(vm, "findSourceMap"_s)); + exportNames.append(JSC::Identifier::fromString(vm, "syncBuiltinExports"_s)); + exportNames.append(JSC::Identifier::fromString(vm, "SourceMap"_s)); + + exportNames.append(JSC::Identifier::fromString(vm, "builtinModules"_s)); + + JSC::JSArray *builtinModules = JSC::JSArray::create( + vm, + globalObject->arrayStructureForIndexingTypeDuringAllocation( + ArrayWithContiguous), + 7); + builtinModules->putDirectIndex(globalObject, 0, + JSC::jsString(vm, String("node:assert"_s))); + builtinModules->putDirectIndex(globalObject, 1, + JSC::jsString(vm, String("node:buffer"_s))); + builtinModules->putDirectIndex(globalObject, 2, + JSC::jsString(vm, String("node:events"_s))); + builtinModules->putDirectIndex(globalObject, 3, + JSC::jsString(vm, String("node:util"_s))); + builtinModules->putDirectIndex(globalObject, 4, + JSC::jsString(vm, String("node:path"_s))); + builtinModules->putDirectIndex(globalObject, 5, + JSC::jsString(vm, String("bun:ffi"_s))); + builtinModules->putDirectIndex(globalObject, 6, + JSC::jsString(vm, String("bun:sqlite"_s))); + exportValues.append(builtinModules); +} +} // namespace Zig diff --git a/src/bun.js/modules/NodeModuleModule.h b/src/bun.js/modules/NodeModuleModule.h new file mode 100644 index 000000000..0aefdef12 --- /dev/null +++ b/src/bun.js/modules/NodeModuleModule.h @@ -0,0 +1,12 @@ +#include "../bindings/ZigGlobalObject.h" +#include "JavaScriptCore/JSGlobalObject.h" + +namespace Zig { + +// node:module +void generateNodeModuleModule(JSC::JSGlobalObject *globalObject, + JSC::Identifier moduleKey, + Vector<JSC::Identifier, 4> &exportNames, + JSC::MarkedArgumentBuffer &exportValues); + +} // namespace Zig
\ No newline at end of file diff --git a/test/bun.js/import-meta.test.js b/test/bun.js/import-meta.test.js index 8b0cccea1..fc365fc38 100644 --- a/test/bun.js/import-meta.test.js +++ b/test/bun.js/import-meta.test.js @@ -33,6 +33,17 @@ it("Module.createRequire().resolve", () => { expect(result).toBe(expected); }); +it("Module.createRequire(file://url).resolve(file://url)", () => { + const expected = Bun.resolveSync("./require-json.json", import.meta.dir); + + const createdRequire = Module.createRequire(import.meta.url); + const result1 = createdRequire.resolve("./require-json.json"); + const result2 = createdRequire.resolve("file://./require-json.json"); + + expect(result1).toBe(expected); + expect(result2).toBe(expected); +}); + it("import.meta.require.resolve", () => { const expected = Bun.resolveSync("./require-json.json", import.meta.dir); var { resolve } = import.meta.require; |