diff options
-rw-r--r-- | .vscode/launch.json | 1 | ||||
-rw-r--r-- | src/bun.js/bindings/BunPlugin.cpp | 6 | ||||
-rw-r--r-- | src/bun.js/bindings/CommonJSModuleRecord.cpp | 177 | ||||
-rw-r--r-- | src/bun.js/bindings/CommonJSModuleRecord.h | 49 | ||||
-rw-r--r-- | src/bun.js/bindings/ImportMetaObject.cpp | 147 | ||||
-rw-r--r-- | src/bun.js/bindings/ImportMetaObject.h | 7 | ||||
-rw-r--r-- | src/bun.js/bindings/ModuleLoader.cpp | 29 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 21 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.h | 8 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 2 | ||||
-rw-r--r-- | src/bun.js/modules/NodeModuleModule.cpp | 6 | ||||
-rw-r--r-- | src/js/builtins/ImportMetaObject.ts | 4 | ||||
-rw-r--r-- | src/js/out/WebCoreJSBuiltins.cpp | 8 | ||||
-rw-r--r-- | src/js/out/WebCoreJSBuiltins.h | 11 | ||||
-rw-r--r-- | src/js_printer.zig | 6 | ||||
-rw-r--r-- | test/js/bun/plugin/plugins.d.ts | 2 | ||||
-rw-r--r-- | test/js/bun/plugin/plugins.test.ts | 38 |
17 files changed, 233 insertions, 289 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json index 9ca2aa36a..4a4cad0ef 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -242,7 +242,6 @@ "console": "internalConsole", "env": {} }, - { "type": "lldb", "request": "launch", diff --git a/src/bun.js/bindings/BunPlugin.cpp b/src/bun.js/bindings/BunPlugin.cpp index 066cf82fd..129d7816b 100644 --- a/src/bun.js/bindings/BunPlugin.cpp +++ b/src/bun.js/bindings/BunPlugin.cpp @@ -405,14 +405,10 @@ EncodedJSValue BunPlugin::OnLoad::run(JSC::JSGlobalObject* globalObject, BunStri if (auto* promise = JSC::jsDynamicCast<JSPromise*>(result)) { switch (promise->status(vm)) { + case JSPromise::Status::Rejected: case JSPromise::Status::Pending: { return JSValue::encode(promise); } - case JSPromise::Status::Rejected: { - promise->internalField(JSC::JSPromise::Field::Flags).set(vm, promise, jsNumber(static_cast<unsigned>(JSC::JSPromise::Status::Fulfilled))); - result = promise->result(vm); - return JSValue::encode(result); - } case JSPromise::Status::Fulfilled: { result = promise->result(vm); break; diff --git a/src/bun.js/bindings/CommonJSModuleRecord.cpp b/src/bun.js/bindings/CommonJSModuleRecord.cpp index 8adba197c..bcae04500 100644 --- a/src/bun.js/bindings/CommonJSModuleRecord.cpp +++ b/src/bun.js/bindings/CommonJSModuleRecord.cpp @@ -164,98 +164,74 @@ JSC_DEFINE_HOST_FUNCTION(requireResolvePathsFunction, (JSGlobalObject * globalOb return JSValue::encode(JSC::constructEmptyArray(globalObject, nullptr, 0)); } -static const HashTableValue RequireResolveFunctionPrototypeValues[] = { - { "paths"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, requireResolvePathsFunction, 1 } }, -}; - -class RequireResolveFunctionPrototype final : public JSC::JSNonFinalObject { -public: - using Base = JSC::JSNonFinalObject; - static RequireResolveFunctionPrototype* create( - JSC::JSGlobalObject* globalObject) - { - auto& vm = globalObject->vm(); - - auto* structure = RequireResolveFunctionPrototype::createStructure(vm, globalObject, globalObject->functionPrototype()); - RequireResolveFunctionPrototype* prototype = new (NotNull, JSC::allocateCell<RequireResolveFunctionPrototype>(vm)) RequireResolveFunctionPrototype(vm, structure); - prototype->finishCreation(vm); - return prototype; - } - - DECLARE_INFO; +JSC_DEFINE_CUSTOM_GETTER(jsRequireCacheGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) +{ + Zig::GlobalObject* thisObject = jsCast<Zig::GlobalObject*>(globalObject); + return JSValue::encode(thisObject->lazyRequireCacheObject()); +} - RequireResolveFunctionPrototype( - JSC::VM& vm, - JSC::Structure* structure) - : Base(vm, structure) - { - } +JSC_DEFINE_CUSTOM_SETTER(jsRequireCacheSetter, + (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, + JSC::EncodedJSValue value, JSC::PropertyName propertyName)) +{ + JSObject* thisObject = jsDynamicCast<JSObject*>(JSValue::decode(thisValue)); + if (!thisObject) + return false; - template<typename CellType, JSC::SubspaceAccess> - static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) - { - return &vm.plainObjectSpace(); - } + thisObject->putDirect(globalObject->vm(), propertyName, JSValue::decode(value), 0); + return true; +} - void finishCreation(JSC::VM& vm); +static const HashTableValue RequireResolveFunctionPrototypeValues[] = { + { "paths"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, requireResolvePathsFunction, 1 } }, }; static const HashTableValue RequireFunctionPrototypeValues[] = { - { "cache"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, Zig::jsRequireCacheGetter, Zig::jsRequireCacheSetter } }, + { "cache"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsRequireCacheGetter, jsRequireCacheSetter } }, }; -class RequireFunctionPrototype final : public JSC::JSNonFinalObject { -public: - using Base = JSC::JSNonFinalObject; - static RequireFunctionPrototype* create( - JSC::JSGlobalObject* globalObject) - { - auto& vm = globalObject->vm(); +RequireResolveFunctionPrototype* RequireResolveFunctionPrototype::create(JSC::JSGlobalObject* globalObject) +{ + auto& vm = globalObject->vm(); - auto* structure = RequireFunctionPrototype::createStructure(vm, globalObject, globalObject->functionPrototype()); - RequireFunctionPrototype* prototype = new (NotNull, JSC::allocateCell<RequireFunctionPrototype>(vm)) RequireFunctionPrototype(vm, structure); - prototype->finishCreation(vm); + auto* structure = RequireResolveFunctionPrototype::createStructure(vm, globalObject, globalObject->functionPrototype()); + RequireResolveFunctionPrototype* prototype = new (NotNull, JSC::allocateCell<RequireResolveFunctionPrototype>(vm)) RequireResolveFunctionPrototype(vm, structure); + prototype->finishCreation(vm); + return prototype; +} - JSFunction* resolveFunction = JSFunction::create(vm, moduleRequireResolveCodeGenerator(vm), globalObject->globalScope(), JSFunction::createStructure(vm, globalObject, RequireResolveFunctionPrototype::create(globalObject))); - prototype->putDirect(vm, JSC::Identifier::fromString(vm, "resolve"_s), resolveFunction, PropertyAttribute::Function | 0); +RequireFunctionPrototype* RequireFunctionPrototype::create( + JSC::JSGlobalObject* globalObject) +{ + auto& vm = globalObject->vm(); - return prototype; - } + auto* structure = RequireFunctionPrototype::createStructure(vm, globalObject, globalObject->functionPrototype()); + RequireFunctionPrototype* prototype = new (NotNull, JSC::allocateCell<RequireFunctionPrototype>(vm)) RequireFunctionPrototype(vm, structure); + prototype->finishCreation(vm); - RequireFunctionPrototype( - JSC::VM& vm, - JSC::Structure* structure) - : Base(vm, structure) - { - } + prototype->putDirect(vm, JSC::Identifier::fromString(vm, "resolve"_s), static_cast<Zig::GlobalObject*>(globalObject)->requireResolveFunctionUnbound(), PropertyAttribute::Function | 0); - DECLARE_INFO; - - template<typename CellType, JSC::SubspaceAccess> - static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) - { - return &vm.plainObjectSpace(); - } + return prototype; +} - void finishCreation(JSC::VM& vm) - { - Base::finishCreation(vm); - ASSERT(inherits(vm, info())); +void RequireFunctionPrototype::finishCreation(JSC::VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(vm, info())); - reifyStaticProperties(vm, info(), RequireFunctionPrototypeValues, *this); - JSC::JSFunction* requireDotMainFunction = JSFunction::create( - vm, - moduleMainCodeGenerator(vm), - globalObject()->globalScope()); + reifyStaticProperties(vm, info(), RequireFunctionPrototypeValues, *this); + JSC::JSFunction* requireDotMainFunction = JSFunction::create( + vm, + moduleMainCodeGenerator(vm), + globalObject()->globalScope()); - this->putDirect( - vm, - JSC::Identifier::fromString(vm, "main"_s), - JSC::GetterSetter::create(vm, globalObject(), requireDotMainFunction, JSValue()), - PropertyAttribute::Builtin | PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | 0); - this->putDirect(vm, JSC::Identifier::fromString(vm, "extensions"_s), constructEmptyObject(globalObject()), 0); - } -}; + this->putDirect( + vm, + JSC::Identifier::fromString(vm, "main"_s), + JSC::GetterSetter::create(vm, globalObject(), requireDotMainFunction, JSValue()), + PropertyAttribute::Builtin | PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | 0); + this->putDirect(vm, JSC::Identifier::fromString(vm, "extensions"_s), constructEmptyObject(globalObject()), 0); +} JSC_DEFINE_CUSTOM_GETTER(getterFilename, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) { @@ -406,13 +382,7 @@ public: ASSERT(inherits(vm, info())); reifyStaticProperties(vm, JSCommonJSModule::info(), JSCommonJSModulePrototypeTableValues, *this); - JSFunction* requireFunction = JSFunction::create( - vm, - moduleRequireCodeGenerator(vm), - globalObject->globalScope(), - JSFunction::createStructure(vm, globalObject, RequireFunctionPrototype::create(globalObject))); - - this->putDirect(vm, clientData(vm)->builtinNames().requirePublicName(), requireFunction, PropertyAttribute::Builtin | PropertyAttribute::Function | 0); + this->putDirect(vm, clientData(vm)->builtinNames().requirePublicName(), (static_cast<Zig::GlobalObject*>(globalObject))->requireFunctionUnbound(), PropertyAttribute::Builtin | PropertyAttribute::Function | 0); this->putDirectNativeFunction( vm, @@ -485,7 +455,6 @@ JSCommonJSModule* JSCommonJSModule::create( JSString* requireMapKey = JSC::jsStringWithCache(vm, key); auto index = key.reverseFind('/', key.length()); JSString* dirname = jsEmptyString(vm); - JSString* filename = requireMapKey; if (index != WTF::notFound) { dirname = JSC::jsSubstring(globalObject, requireMapKey, 0, index); } @@ -493,7 +462,7 @@ JSCommonJSModule* JSCommonJSModule::create( auto* out = JSCommonJSModule::create( vm, globalObject->CommonJSModuleObjectStructure(), - requireMapKey, filename, dirname, nullptr); + requireMapKey, requireMapKey, dirname, nullptr); out->putDirect(vm, WebCore::clientData(vm)->builtinNames().exportsPublicName(), exportsObject, exportsObject.isCell() && exportsObject.isCallable() ? JSC::PropertyAttribute::Function | 0 : 0); out->hasEvaluated = hasEvaluated; @@ -969,4 +938,40 @@ std::optional<JSC::SourceCode> createCommonJSModule( sourceOrigin, sourceURL)); } -}
\ No newline at end of file + +JSObject* JSCommonJSModule::createBoundRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString) +{ + auto* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject); + + JSString* filename = JSC::jsStringWithCache(vm, pathString); + auto index = pathString.reverseFind('/', pathString.length()); + JSString* dirname = jsEmptyString(vm); + if (index != WTF::notFound) { + dirname = JSC::jsSubstring(globalObject, filename, 0, index); + } + + auto moduleObject = Bun::JSCommonJSModule::create( + vm, + globalObject->CommonJSModuleObjectStructure(), + filename, filename, dirname, nullptr); + + auto& builtinNames = WebCore::builtinNames(vm); + + JSFunction* requireFunction = JSC::JSBoundFunction::create(vm, + globalObject, + globalObject->requireFunctionUnbound(), + moduleObject, + ArgList(), 1, jsString(vm, String("require"_s))); + + JSFunction* resolveFunction = JSC::JSBoundFunction::create(vm, + globalObject, + globalObject->requireResolveFunctionUnbound(), + moduleObject, + ArgList(), 1, jsString(vm, String("require"_s))); + + requireFunction->putDirect(vm, builtinNames.resolvePublicName(), resolveFunction, PropertyAttribute::Function | 0); + + return requireFunction; +} + +} // namespace Bun diff --git a/src/bun.js/bindings/CommonJSModuleRecord.h b/src/bun.js/bindings/CommonJSModuleRecord.h index 15792f9da..20941f454 100644 --- a/src/bun.js/bindings/CommonJSModuleRecord.h +++ b/src/bun.js/bindings/CommonJSModuleRecord.h @@ -39,6 +39,7 @@ public: bool evaluate(Zig::GlobalObject* globalObject, const WTF::String& sourceURL, ResolvedSource resolvedSource); bool evaluate(Zig::GlobalObject* globalObject, const WTF::String& key, const SyntheticSourceProvider::SyntheticSourceGenerator& generator); + bool evaluate(Zig::GlobalObject* globalObject, const WTF::String& key, JSSourceCode* sourceCode); static JSCommonJSModule* create(JSC::VM& vm, JSC::Structure* structure, JSC::JSString* id, @@ -56,6 +57,8 @@ public: const WTF::String& key, ResolvedSource resolvedSource); + static JSObject* createBoundRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString); + void toSyntheticSource(JSC::JSGlobalObject* globalObject, JSC::Identifier moduleKey, Vector<JSC::Identifier, 4>& exportNames, @@ -95,4 +98,50 @@ std::optional<JSC::SourceCode> createCommonJSModule( Zig::GlobalObject* globalObject, ResolvedSource source); +class RequireResolveFunctionPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static RequireResolveFunctionPrototype* create(JSC::JSGlobalObject* globalObject); + + DECLARE_INFO; + + RequireResolveFunctionPrototype( + JSC::VM& vm, + JSC::Structure* structure) + : Base(vm, structure) + { + } + + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + return &vm.plainObjectSpace(); + } + + void finishCreation(JSC::VM& vm); +}; + +class RequireFunctionPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static RequireFunctionPrototype* create(JSC::JSGlobalObject* globalObject); + + RequireFunctionPrototype( + JSC::VM& vm, + JSC::Structure* structure) + : Base(vm, structure) + { + } + + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + return &vm.plainObjectSpace(); + } + + DECLARE_INFO; + + void finishCreation(JSC::VM& vm); +}; + } // namespace Bun diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp index 037305c81..328b9f940 100644 --- a/src/bun.js/bindings/ImportMetaObject.cpp +++ b/src/bun.js/bindings/ImportMetaObject.cpp @@ -41,6 +41,7 @@ #include <JavaScriptCore/LazyProperty.h> #include <JavaScriptCore/LazyPropertyInlines.h> #include <JavaScriptCore/VMTrapsInlines.h> +#include "CommonJSModuleRecord.h" namespace Zig { using namespace JSC; @@ -141,147 +142,6 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireResolve, (JSC::JSGlobalObject * global return functionRequireResolve(globalObject, callFrame, fromStr); } -JSC_DEFINE_CUSTOM_GETTER(jsRequireCacheGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) -{ - Zig::GlobalObject* thisObject = jsCast<Zig::GlobalObject*>(globalObject); - return JSValue::encode(thisObject->lazyRequireCacheObject()); -} - -JSC_DEFINE_CUSTOM_SETTER(jsRequireCacheSetter, - (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, - JSC::EncodedJSValue value, JSC::PropertyName propertyName)) -{ - JSObject* thisObject = jsDynamicCast<JSObject*>(JSValue::decode(thisValue)); - if (!thisObject) - return false; - - thisObject->putDirect(globalObject->vm(), propertyName, JSValue::decode(value), 0); - return true; -} - -JSC_DEFINE_HOST_FUNCTION(requireResolvePathsFunction, (JSGlobalObject * globalObject, CallFrame* callframe)) -{ - return JSValue::encode(JSC::constructEmptyArray(globalObject, nullptr, 0)); -} - -static const HashTableValue RequireResolveFunctionPrototypeValues[] = { - { "paths"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, requireResolvePathsFunction, 1 } }, -}; - -class RequireResolveFunctionPrototype final : public JSC::JSNonFinalObject { -public: - using Base = JSC::JSNonFinalObject; - static RequireResolveFunctionPrototype* create( - JSC::JSGlobalObject* globalObject) - { - auto& vm = globalObject->vm(); - - auto* structure = RequireResolveFunctionPrototype::createStructure(vm, globalObject, globalObject->functionPrototype()); - RequireResolveFunctionPrototype* prototype = new (NotNull, JSC::allocateCell<RequireResolveFunctionPrototype>(vm)) RequireResolveFunctionPrototype(vm, structure); - prototype->finishCreation(vm); - return prototype; - } - - DECLARE_INFO; - - RequireResolveFunctionPrototype( - JSC::VM& vm, - JSC::Structure* structure) - : Base(vm, structure) - { - } - - template<typename CellType, JSC::SubspaceAccess> - static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) - { - return &vm.plainObjectSpace(); - } -}; - -class ResolveFunction final : public JSC::InternalFunction { - -public: - using Base = JSC::InternalFunction; - static ResolveFunction* create(JSGlobalObject* globalObject) - { - JSObject* resolvePrototype = RequireResolveFunctionPrototype::create(globalObject); - Structure* structure = Structure::create( - globalObject->vm(), - globalObject, - resolvePrototype, - JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), - ResolveFunction::info()); - auto* resolveFunction = new (NotNull, JSC::allocateCell<ResolveFunction>(globalObject->vm())) ResolveFunction(globalObject->vm(), structure); - resolveFunction->finishCreation(globalObject->vm()); - return resolveFunction; - } - - DECLARE_INFO; - - template<typename CellType, JSC::SubspaceAccess> - static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) - { - return &vm.internalFunctionSpace(); - } - - ResolveFunction( - JSC::VM& vm, - JSC::Structure* structure) - : InternalFunction(vm, structure, jsFunctionRequireResolve, nullptr) - { - } -}; - -JSObject* Zig::ImportMetaObject::createRequireResolveFunctionUnbound(VM& vm, JSGlobalObject* globalObject) -{ - return ResolveFunction::create(globalObject); -} - -JSObject* Zig::ImportMetaObject::createRequireFunctionUnbound(VM& vm, JSGlobalObject* globalObject) -{ - auto& builtinNames = WebCore::builtinNames(vm); - - JSC::JSFunction* requireDotMainFunction = JSFunction::create( - vm, - moduleMainCodeGenerator(vm), - globalObject->globalScope()); - - auto* prototype = JSC::constructEmptyObject(globalObject, globalObject->functionPrototype()); - prototype->putDirect( - vm, - JSC::Identifier::fromString(vm, "main"_s), - JSC::GetterSetter::create(vm, globalObject, requireDotMainFunction, JSValue()), - PropertyAttribute::Builtin | PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | 0); - prototype->putDirect(vm, JSC::Identifier::fromString(vm, "extensions"_s), constructEmptyObject(globalObject), 0); - prototype->putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "cache"_s), JSC::CustomGetterSetter::create(vm, Zig::jsRequireCacheGetter, Zig::jsRequireCacheSetter), 0); - return JSFunction::create(vm, importMetaObjectRequireCodeGenerator(vm), globalObject, JSFunction::createStructure(vm, globalObject, prototype)); -} - -JSObject* Zig::ImportMetaObject::createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString) -{ - auto* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject); - auto& builtinNames = WebCore::builtinNames(vm); - - JSFunction* resolveFunctionUnbound = jsCast<JSFunction*>(globalObject->importMetaRequireResolveFunctionUnbound()); - JSFunction* requireFunctionUnbound = jsCast<JSFunction*>(globalObject->importMetaRequireFunctionUnbound()); - auto str = jsString(vm, pathString); - - JSFunction* requireFunction = JSC::JSBoundFunction::create(vm, - globalObject, requireFunctionUnbound, - str, ArgList(), 1, jsString(vm, String("require"_s))); - - JSFunction* resolveFunction = JSC::JSBoundFunction::create(vm, - globalObject, resolveFunctionUnbound, - str, ArgList(), 2, jsString(vm, String("resolve"_s))); - - requireFunction->putDirect(vm, builtinNames.resolvePublicName(), resolveFunction, PropertyAttribute::Function | 0); - - return requireFunction; -} - -const JSC::ClassInfo RequireResolveFunctionPrototype::s_info = { "resolve"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RequireResolveFunctionPrototype) }; -const JSC::ClassInfo ResolveFunction::s_info = { "resolve"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ResolveFunction) }; - extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) { JSC::VM& vm = globalObject->vm(); @@ -390,8 +250,6 @@ extern "C" EncodedJSValue functionImportMeta__resolveSyncPrivate(JSC::JSGlobalOb return result; } -JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolve); - JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) { @@ -443,7 +301,6 @@ enum class ImportMetaPropertyOffset : uint32_t { file, path, require, - }; static constexpr uint32_t numberOfImportMetaProperties = 5; @@ -593,7 +450,7 @@ void ImportMetaObject::finishCreation(VM& vm) path = url.path(); } - JSFunction* value = jsCast<JSFunction*>(ImportMetaObject::createRequireFunction(init.vm, meta->globalObject(), path.toString())); + JSFunction* value = jsCast<JSFunction*>(Bun::JSCommonJSModule::createBoundRequireFunction(init.vm, meta->globalObject(), path.toString())); init.set(value); }); this->urlProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSString>::Initializer& init) { diff --git a/src/bun.js/bindings/ImportMetaObject.h b/src/bun.js/bindings/ImportMetaObject.h index 6b5661039..02b911af0 100644 --- a/src/bun.js/bindings/ImportMetaObject.h +++ b/src/bun.js/bindings/ImportMetaObject.h @@ -19,17 +19,12 @@ namespace Zig { using namespace JSC; using namespace WebCore; -JSC_DECLARE_CUSTOM_GETTER(jsRequireCacheGetter); -JSC_DECLARE_CUSTOM_SETTER(jsRequireCacheSetter); - class ImportMetaObject final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; static ImportMetaObject* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, const WTF::String& url); - static JSC::JSObject* createRequireFunctionUnbound(JSC::VM& vm, JSGlobalObject* globalObject); - static JSC::JSObject* createRequireResolveFunctionUnbound(JSC::VM& vm, JSGlobalObject* globalObject); static JSObject* createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString); static ImportMetaObject* create(JSC::JSGlobalObject* globalObject, JSC::JSString* keyString); @@ -71,4 +66,4 @@ private: void finishCreation(JSC::VM&); }; -}
\ No newline at end of file +} diff --git a/src/bun.js/bindings/ModuleLoader.cpp b/src/bun.js/bindings/ModuleLoader.cpp index 62d73eb75..ac5ca0b91 100644 --- a/src/bun.js/bindings/ModuleLoader.cpp +++ b/src/bun.js/bindings/ModuleLoader.cpp @@ -420,9 +420,32 @@ JSValue fetchCommonJSModule( } } - // if (JSC::JSValue virtualModuleResult = JSValue::decode(Bun__runVirtualModule(globalObject, specifier))) { - // return handleVirtualModuleResult<allowPromise>(globalObject, virtualModuleResult, res, specifier, referrer); - // } + if (JSC::JSValue virtualModuleResult = JSValue::decode(Bun__runVirtualModule(globalObject, specifier))) { + JSPromise* promise = jsCast<JSPromise*>(handleVirtualModuleResult<true>(globalObject, virtualModuleResult, res, specifier, referrer)); + switch (promise->status(vm)) { + case JSPromise::Status::Rejected: { + uint32_t promiseFlags = promise->internalField(JSPromise::Field::Flags).get().asUInt32AsAnyInt(); + promise->internalField(JSPromise::Field::Flags).set(vm, promise, jsNumber(promiseFlags | JSPromise::isHandledFlag)); + JSC::throwException(globalObject, scope, promise->result(vm)); + RELEASE_AND_RETURN(scope, JSValue {}); + } + case JSPromise::Status::Pending: { + JSC::throwTypeError(globalObject, scope, makeString("require() async module \""_s, Bun::toWTFString(*specifier), "\" is unsupported. use \"await import()\" instead."_s)); + RELEASE_AND_RETURN(scope, JSValue {}); + } + case JSPromise::Status::Fulfilled: { + if (!res->success) { + throwException(scope, res->result.err, globalObject); + RELEASE_AND_RETURN(scope, {}); + } + auto* jsSourceCode = jsCast<JSSourceCode*>(promise->result(vm)); + globalObject->moduleLoader()->provideFetch(globalObject, specifierValue, jsSourceCode->sourceCode()); + RETURN_IF_EXCEPTION(scope, {}); + RELEASE_AND_RETURN(scope, jsNumber(-1)); + } + } + } + auto* loader = globalObject->moduleLoader(); JSMap* registry = jsCast<JSMap*>(loader->getDirect(vm, Identifier::fromString(vm, "registry"_s))); diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 759217ed1..946e368dd 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -3448,15 +3448,23 @@ void GlobalObject::finishCreation(VM& vm) init.set(structure); }); - m_importMetaRequireFunctionUnbound.initLater( + m_requireFunctionUnbound.initLater( [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) { init.set( - Zig::ImportMetaObject::createRequireFunctionUnbound(init.vm, init.owner)); + JSFunction::create( + init.vm, + moduleRequireCodeGenerator(init.vm), + init.owner->globalScope(), + JSFunction::createStructure(init.vm, init.owner, RequireFunctionPrototype::create(init.owner)))); }); - m_importMetaRequireResolveFunctionUnbound.initLater( + m_requireResolveFunctionUnbound.initLater( [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) { init.set( - Zig::ImportMetaObject::createRequireResolveFunctionUnbound(init.vm, init.owner)); + JSFunction::create( + init.vm, + moduleRequireResolveCodeGenerator(init.vm), + init.owner->globalScope(), + JSFunction::createStructure(init.vm, init.owner, RequireResolveFunctionPrototype::create(init.owner)))); }); m_importMetaObjectStructure.initLater( @@ -4107,7 +4115,6 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm) putDirectBuiltinFunction(vm, this, builtinNames.createNativeReadableStreamPrivateName(), readableStreamCreateNativeReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); putDirectBuiltinFunction(vm, this, builtinNames.requireESMPrivateName(), importMetaObjectRequireESMCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); - putDirectBuiltinFunction(vm, this, builtinNames.requirePrivateName(), importMetaObjectRequireCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); putDirectBuiltinFunction(vm, this, builtinNames.loadCJS2ESMPrivateName(), importMetaObjectLoadCJS2ESMCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); putDirectBuiltinFunction(vm, this, builtinNames.internalRequirePrivateName(), importMetaObjectInternalRequireCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); putDirectNativeFunction(vm, this, builtinNames.createUninitializedArrayBufferPrivateName(), 1, functionCreateUninitializedArrayBuffer, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function); @@ -4622,8 +4629,8 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor) thisObject->m_emitReadableNextTickFunction.visit(visitor); thisObject->m_JSBufferSubclassStructure.visit(visitor); - thisObject->m_importMetaRequireFunctionUnbound.visit(visitor); - thisObject->m_importMetaRequireResolveFunctionUnbound.visit(visitor); + thisObject->m_requireFunctionUnbound.visit(visitor); + thisObject->m_requireResolveFunctionUnbound.visit(visitor); thisObject->m_importMetaObjectStructure.visit(visitor); thisObject->m_asyncBoundFunctionStructure.visit(visitor); diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index 0e126f7f7..e4364d248 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -262,8 +262,8 @@ public: JSC::JSFunction* emitReadableNextTickFunction() { return m_emitReadableNextTickFunction.getInitializedOnMainThread(this); } - JSObject* importMetaRequireFunctionUnbound() { return m_importMetaRequireFunctionUnbound.getInitializedOnMainThread(this); } - JSObject* importMetaRequireResolveFunctionUnbound() { return m_importMetaRequireResolveFunctionUnbound.getInitializedOnMainThread(this); } + JSObject* requireFunctionUnbound() { return m_requireFunctionUnbound.getInitializedOnMainThread(this); } + JSObject* requireResolveFunctionUnbound() { return m_requireResolveFunctionUnbound.getInitializedOnMainThread(this); } JSObject* lazyRequireCacheObject() { return m_lazyRequireCacheObject.getInitializedOnMainThread(this); } @@ -523,8 +523,8 @@ private: LazyProperty<JSGlobalObject, Structure> m_commonJSModuleObjectStructure; LazyProperty<JSGlobalObject, Structure> m_commonJSFunctionArgumentsStructure; - LazyProperty<JSGlobalObject, JSC::JSObject> m_importMetaRequireFunctionUnbound; - LazyProperty<JSGlobalObject, JSC::JSObject> m_importMetaRequireResolveFunctionUnbound; + LazyProperty<JSGlobalObject, JSC::JSObject> m_requireFunctionUnbound; + LazyProperty<JSGlobalObject, JSC::JSObject> m_requireResolveFunctionUnbound; LazyProperty<JSGlobalObject, JSC::Structure> m_importMetaObjectStructure; LazyProperty<JSGlobalObject, JSC::Structure> m_asyncBoundFunctionStructure; diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 00c663077..b48ade978 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -1693,7 +1693,7 @@ pub const VirtualMachine = struct { &ZigString.init( std.fmt.allocPrint(globalThis.allocator(), "{d} errors building \"{}\"", .{ errors.len, - referrer, + specifier, }) catch unreachable, ), ).asVoid(), diff --git a/src/bun.js/modules/NodeModuleModule.cpp b/src/bun.js/modules/NodeModuleModule.cpp index 57fc1834d..476ee95dc 100644 --- a/src/bun.js/modules/NodeModuleModule.cpp +++ b/src/bun.js/modules/NodeModuleModule.cpp @@ -2,6 +2,7 @@ #include "./NodeModuleModule.h" +#include "CommonJSModuleRecord.h" #include "ImportMetaObject.h" #include "JavaScriptCore/JSBoundFunction.h" #include "JavaScriptCore/ObjectConstructor.h" @@ -126,14 +127,13 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleCreateRequire, if (callFrame->argumentCount() < 1) { throwTypeError(globalObject, scope, "createRequire() requires at least one argument"_s); - return JSC::JSValue::encode(JSC::jsUndefined()); + RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::jsUndefined())); } auto val = callFrame->uncheckedArgument(0).toWTFString(globalObject); RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined())); - auto clientData = WebCore::clientData(vm); RELEASE_AND_RETURN( - scope, JSValue::encode(Zig::ImportMetaObject::createRequireFunction( + scope, JSValue::encode(Bun::JSCommonJSModule::createBoundRequireFunction( vm, globalObject, val))); } extern "C" EncodedJSValue Resolver__nodeModulePathsForJS(JSGlobalObject *, diff --git a/src/js/builtins/ImportMetaObject.ts b/src/js/builtins/ImportMetaObject.ts index 1f26695fc..46c00534a 100644 --- a/src/js/builtins/ImportMetaObject.ts +++ b/src/js/builtins/ImportMetaObject.ts @@ -214,10 +214,6 @@ export function createRequireCache() { }); } -export function require(this: string, name) { - return $internalRequire($resolveSync(name, $toString(this), false)); -} - $getter; export function main(this: ImportMetaObject) { return this.path === Bun.main; diff --git a/src/js/out/WebCoreJSBuiltins.cpp b/src/js/out/WebCoreJSBuiltins.cpp index 76a242bf7..9ae90e82a 100644 --- a/src/js/out/WebCoreJSBuiltins.cpp +++ b/src/js/out/WebCoreJSBuiltins.cpp @@ -2284,14 +2284,6 @@ const int s_importMetaObjectCreateRequireCacheCodeLength = 854; static const JSC::Intrinsic s_importMetaObjectCreateRequireCacheCodeIntrinsic = JSC::NoIntrinsic; const char* const s_importMetaObjectCreateRequireCacheCode = "(function (){\"use strict\";var c=new Map,L={};return new Proxy(L,{get(f,_){const h=@requireMap.@get(_);if(h)return h;const t=@Loader.registry.@get(_);if(t\?.evaluated){const u=@Loader.getModuleNamespaceObject(t.module),g=u[@commonJSSymbol]===0||u.default\?.[@commonJSSymbol]\?u.default:u,b=@createCommonJSModule(_,g,!0);return @requireMap.@set(_,b),b}return L[_]},set(f,_,h){return @requireMap.@set(_,h),!0},has(f,_){return @requireMap.@has(_)||@Loader.registry.@has(_)},deleteProperty(f,_){return c.@delete(_),@requireMap.@delete(_),@Loader.registry.@delete(_),!0},ownKeys(f){var _=[...@requireMap.@keys()];const h=[...@Loader.registry.@keys()];for(let t of h)if(!_.includes(t))@arrayPush(_,t);return _},getPrototypeOf(f){return null},getOwnPropertyDescriptor(f,_){if(@requireMap.@has(_)||@Loader.registry.@has(_))return{configurable:!0,enumerable:!0}}})})\n"; -// require -const JSC::ConstructAbility s_importMetaObjectRequireCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; -const JSC::ConstructorKind s_importMetaObjectRequireCodeConstructorKind = JSC::ConstructorKind::None; -const JSC::ImplementationVisibility s_importMetaObjectRequireCodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_importMetaObjectRequireCodeLength = 89; -static const JSC::Intrinsic s_importMetaObjectRequireCodeIntrinsic = JSC::NoIntrinsic; -const char* const s_importMetaObjectRequireCode = "(function (l){\"use strict\";return @internalRequire(@resolveSync(l,@toString(this),!1))})\n"; - // main const JSC::ConstructAbility s_importMetaObjectMainCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_importMetaObjectMainCodeConstructorKind = JSC::ConstructorKind::None; diff --git a/src/js/out/WebCoreJSBuiltins.h b/src/js/out/WebCoreJSBuiltins.h index 135e01f17..44e7023af 100644 --- a/src/js/out/WebCoreJSBuiltins.h +++ b/src/js/out/WebCoreJSBuiltins.h @@ -4172,14 +4172,6 @@ extern const JSC::ConstructAbility s_importMetaObjectCreateRequireCacheCodeConst extern const JSC::ConstructorKind s_importMetaObjectCreateRequireCacheCodeConstructorKind; extern const JSC::ImplementationVisibility s_importMetaObjectCreateRequireCacheCodeImplementationVisibility; -// require -#define WEBCORE_BUILTIN_IMPORTMETAOBJECT_REQUIRE 1 -extern const char* const s_importMetaObjectRequireCode; -extern const int s_importMetaObjectRequireCodeLength; -extern const JSC::ConstructAbility s_importMetaObjectRequireCodeConstructAbility; -extern const JSC::ConstructorKind s_importMetaObjectRequireCodeConstructorKind; -extern const JSC::ImplementationVisibility s_importMetaObjectRequireCodeImplementationVisibility; - // main #define WEBCORE_BUILTIN_IMPORTMETAOBJECT_MAIN 1 extern const char* const s_importMetaObjectMainCode; @@ -4193,7 +4185,6 @@ extern const JSC::ImplementationVisibility s_importMetaObjectMainCodeImplementat macro(requireESM, importMetaObjectRequireESM, 1) \ macro(internalRequire, importMetaObjectInternalRequire, 1) \ macro(createRequireCache, importMetaObjectCreateRequireCache, 0) \ - macro(require, importMetaObjectRequire, 1) \ macro(main, importMetaObjectMain, 0) \ #define WEBCORE_FOREACH_IMPORTMETAOBJECT_BUILTIN_CODE(macro) \ @@ -4201,7 +4192,6 @@ extern const JSC::ImplementationVisibility s_importMetaObjectMainCodeImplementat macro(importMetaObjectRequireESMCode, requireESM, ASCIILiteral(), s_importMetaObjectRequireESMCodeLength) \ macro(importMetaObjectInternalRequireCode, internalRequire, ASCIILiteral(), s_importMetaObjectInternalRequireCodeLength) \ macro(importMetaObjectCreateRequireCacheCode, createRequireCache, ASCIILiteral(), s_importMetaObjectCreateRequireCacheCodeLength) \ - macro(importMetaObjectRequireCode, require, ASCIILiteral(), s_importMetaObjectRequireCodeLength) \ macro(importMetaObjectMainCode, main, "get main"_s, s_importMetaObjectMainCodeLength) \ #define WEBCORE_FOREACH_IMPORTMETAOBJECT_BUILTIN_FUNCTION_NAME(macro) \ @@ -4209,7 +4199,6 @@ extern const JSC::ImplementationVisibility s_importMetaObjectMainCodeImplementat macro(requireESM) \ macro(internalRequire) \ macro(createRequireCache) \ - macro(require) \ macro(main) \ #define DECLARE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \ diff --git a/src/js_printer.zig b/src/js_printer.zig index 1f920327c..61c13c25f 100644 --- a/src/js_printer.zig +++ b/src/js_printer.zig @@ -1682,9 +1682,9 @@ fn NewPrinter( } pub fn printRequireError(p: *Printer, text: string) void { - p.print("(() => { throw (new Error(`Cannot require module "); + p.print("(()=>{ throw new Error(`Cannot require module "); p.printQuotedUTF8(text, false); - p.print("`)); } )()"); + p.print("`);})()"); } pub inline fn importRecord( @@ -4826,7 +4826,7 @@ fn NewPrinter( } inline fn printDisabledImport(p: *Printer) void { - p.print("(() => ({}))"); + p.print("(()=>({}))"); } pub fn printLoadFromBundleWithoutCall(p: *Printer, import_record_index: u32) void { diff --git a/test/js/bun/plugin/plugins.d.ts b/test/js/bun/plugin/plugins.d.ts index aebfd952b..ba88ef7be 100644 --- a/test/js/bun/plugin/plugins.d.ts +++ b/test/js/bun/plugin/plugins.d.ts @@ -9,3 +9,5 @@ declare module "async-obj:*"; declare module "obj:*"; declare module "delay:*"; declare module "./*.svelte"; +declare module "rejected-promise:*"; +declare module "rejected-promise2:*"; diff --git a/test/js/bun/plugin/plugins.test.ts b/test/js/bun/plugin/plugins.test.ts index f754ffbb3..c2827f600 100644 --- a/test/js/bun/plugin/plugins.test.ts +++ b/test/js/bun/plugin/plugins.test.ts @@ -160,6 +160,29 @@ plugin({ }, }); +plugin({ + name: "instant rejected load promise", + setup(builder) { + builder.onResolve({ filter: /.*/, namespace: "rejected-promise" }, ({ path }) => ({ + namespace: "rejected-promise", + path, + })); + + builder.onLoad({ filter: /.*/, namespace: "rejected-promise" }, async ({ path }) => { + throw new Error("Rejected Promise"); + }); + + builder.onResolve({ filter: /.*/, namespace: "rejected-promise2" }, ({ path }) => ({ + namespace: "rejected-promise2", + path, + })); + + builder.onLoad({ filter: /.*/, namespace: "rejected-promise2" }, ({ path }) => { + return Promise.reject(new Error("Rejected Promise")); + }); + }, +}); + // This is to test that it works when imported from a separate file import "../../third_party/svelte"; @@ -326,12 +349,23 @@ describe("errors", () => { } }); - it.skip("async transpiler errors work", async () => { + it("async transpiler errors work", async () => { expect(async () => { globalThis.asyncOnLoad = `const x: string = -NaNAn../!!;`; await import("async:fail"); throw -1; - }).toThrow('Cannot find package "'); + }).toThrow('4 errors building "async:fail"'); + }); + + it("onLoad returns the rejected promise", async () => { + expect(async () => { + await import("rejected-promise:hi"); + throw -1; + }).toThrow("Rejected Promise"); + expect(async () => { + await import("rejected-promise2:hi"); + throw -1; + }).toThrow("Rejected Promise"); }); it("can work with http urls", async () => { |