aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bun.js/api/bun.zig14
-rw-r--r--src/bun.js/bindings/ImportMetaObject.cpp187
-rw-r--r--src/bun.js/bindings/ImportMetaObject.h9
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp13
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h5
-rw-r--r--src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h1
-rw-r--r--src/bun.js/bindings/webcore/DOMIsoSubspaces.h1
7 files changed, 174 insertions, 56 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig
index bf5b932fc..5b4035256 100644
--- a/src/bun.js/api/bun.zig
+++ b/src/bun.js/api/bun.zig
@@ -1046,10 +1046,24 @@ export fn Bun__resolveSync(
};
}
+export fn Bun__resolveSyncWithSource(
+ global: *JSGlobalObject,
+ specifier: JSValue,
+ source: *ZigString,
+ is_esm: bool,
+) JSC.JSValue {
+ var exception_ = [1]JSC.JSValueRef{null};
+ var exception = &exception_;
+ return doResolveWithArgs(global, specifier.getZigString(global), source.*, exception, is_esm, true) orelse {
+ return JSC.JSValue.fromRef(exception[0]);
+ };
+}
+
comptime {
if (!is_bindgen) {
_ = Bun__resolve;
_ = Bun__resolveSync;
+ _ = Bun__resolveSyncWithSource;
}
}
diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp
index be46e5332..a20ec7abb 100644
--- a/src/bun.js/bindings/ImportMetaObject.cpp
+++ b/src/bun.js/bindings/ImportMetaObject.cpp
@@ -44,13 +44,13 @@ namespace Zig {
using namespace JSC;
using namespace WebCore;
-static EncodedJSValue functionRequireResolve(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame, JSC::EncodedJSValue from)
+static EncodedJSValue functionRequireResolve(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame, const WTF::String& fromStr)
{
JSC::VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
switch (callFrame->argumentCount()) {
case 0: {
- auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
// not "requires" because "require" could be confusing
JSC::throwTypeError(globalObject, scope, "require.resolve needs 1 argument (a string)"_s);
scope.release();
@@ -59,8 +59,20 @@ static EncodedJSValue functionRequireResolve(JSC::JSGlobalObject* globalObject,
default: {
JSC::JSValue moduleName = callFrame->argument(0);
+ auto doIt = [&](const WTF::String& fromStr) -> JSC::EncodedJSValue {
+ ZigString from = Zig::toZigString(fromStr);
+ auto result = Bun__resolveSyncWithSource(globalObject, JSC::JSValue::encode(moduleName), &from, false);
+
+ if (!JSC::JSValue::decode(result).isString()) {
+ JSC::throwException(globalObject, scope, JSC::JSValue::decode(result));
+ return JSC::JSValue::encode(JSValue {});
+ }
+
+ scope.release();
+ return result;
+ };
+
if (moduleName.isUndefinedOrNull()) {
- auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
JSC::throwTypeError(globalObject, scope, "require.resolve expects a string"_s);
scope.release();
return JSC::JSValue::encode(JSC::JSValue {});
@@ -78,59 +90,17 @@ static EncodedJSValue functionRequireResolve(JSC::JSGlobalObject* globalObject,
}
}
}
- }
-
- auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from, false);
- auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
- if (!JSC::JSValue::decode(result).isString()) {
- JSC::throwException(globalObject, scope, JSC::JSValue::decode(result));
- return JSC::JSValue::encode(JSC::JSValue {});
+ if (fromValue.isString()) {
+ WTF::String str = fromValue.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
+ return doIt(str);
+ }
}
- scope.release();
- return result;
- }
+ return doIt(fromStr);
}
-}
-
-JSC_DEFINE_CUSTOM_SETTER(functionRequireResolveLazySetter,
- (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
- JSC::EncodedJSValue value, JSC::PropertyName))
-{
- Zig::GlobalObject* global = static_cast<Zig::GlobalObject*>(JSC::jsCast<JSC::JSObject*>(JSC::JSValue::decode(thisValue)));
- JSC::VM& vm = globalObject->vm();
- JSC::JSFunction* require = JSC::jsCast<JSC::JSFunction*>(JSC::JSValue::decode(thisValue));
- auto clientData = WebCore::clientData(vm);
- return require->putDirect(vm, PropertyName(clientData->builtinNames().resolvePrivateName()), JSValue::decode(value), 0);
-}
-
-JSC_DEFINE_CUSTOM_GETTER(functionRequireResolveLazyGetter,
- (JSC::JSGlobalObject * _globalObject, JSC::EncodedJSValue thisValue,
- JSC::PropertyName))
-{
- Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(_globalObject);
-
- JSC::VM& vm = globalObject->vm();
- auto clientData = WebCore::clientData(vm);
- auto& builtinNames = clientData->builtinNames();
-
- JSC::JSFunction* require = JSC::jsCast<JSC::JSFunction*>(JSC::JSValue::decode(thisValue));
-
- if (JSC::JSValue resolveFunctionValue = require->getIfPropertyExists(globalObject, PropertyName(builtinNames.resolvePrivateName()))) {
- return JSValue::encode(resolveFunctionValue);
}
-
- JSValue pathStringValue = require->get(globalObject, PropertyName(builtinNames.pathPrivateName()));
- WTF::String pathString = pathStringValue.toWTFString(globalObject);
-
- JSC::JSFunction* resolverFunction
- = JSC::JSNativeStdFunction::create(
- globalObject->vm(), globalObject, 2, "resolve"_s, [pathString_ = WTFMove(pathString)](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> const JSC::EncodedJSValue {
- return functionRequireResolve(globalObject, callFrame, JSValue::encode(jsString(globalObject->vm(), pathString_)));
- });
- require->putDirect(vm, builtinNames.resolvePrivateName(), resolverFunction, 0);
- return JSValue::encode(JSValue(resolverFunction));
}
Zig::ImportMetaObject* Zig::ImportMetaObject::create(JSC::JSGlobalObject* globalObject, JSValue key)
@@ -151,12 +121,121 @@ Zig::ImportMetaObject* Zig::ImportMetaObject::create(JSC::JSGlobalObject* global
return create(globalObject, keyString);
}
-JSObject* Zig::ImportMetaObject::createRequireFunction(VM& vm, JSGlobalObject* globalObject, WTF::String& pathString)
+JSC_DECLARE_HOST_FUNCTION(jsFunctionRequireResolve);
+
+class JSRequireResolveFunctionPrototype final : public JSC::InternalFunction {
+public:
+ using Base = JSC::InternalFunction;
+
+ static JSRequireResolveFunctionPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
+ {
+ auto* structure = createStructure(vm, globalObject, globalObject->functionPrototype());
+ JSRequireResolveFunctionPrototype* function = new (NotNull, JSC::allocateCell<JSRequireResolveFunctionPrototype>(vm)) JSRequireResolveFunctionPrototype(vm, structure);
+ function->finishCreation(vm);
+ return function;
+ }
+
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
+ }
+
+ DECLARE_INFO;
+
+ static JSC::EncodedJSValue pathsFunction(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
+ {
+ return JSValue::encode(JSC::constructEmptyArray(globalObject, nullptr));
+ }
+
+private:
+ JSRequireResolveFunctionPrototype(JSC::VM& vm, JSC::Structure* structure)
+ : JSC::InternalFunction(vm, structure, jsFunctionRequireResolve, jsFunctionRequireResolve)
+
+ {
+ }
+
+ void finishCreation(JSC::VM& vm)
+ {
+ this->putDirectNativeFunction(vm, globalObject(), Identifier::fromString(vm, "paths"_s), 0, pathsFunction, ImplementationVisibility::Public, NoIntrinsic, 0);
+ Base::finishCreation(vm, 2, "resolve"_s, PropertyAdditionMode::WithoutStructureTransition);
+ }
+};
+
+const JSC::ClassInfo JSRequireResolveFunctionPrototype::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSRequireResolveFunctionPrototype) };
+
+class JSRequireResolveFunction final : public JSC::InternalFunction {
+public:
+ using Base = JSC::InternalFunction;
+
+ static JSRequireResolveFunction* create(JSC::VM& vm, JSC::Structure* structure, const WTF::String& from)
+ {
+ JSRequireResolveFunction* function = new (NotNull, JSC::allocateCell<JSRequireResolveFunction>(vm)) JSRequireResolveFunction(vm, structure, from);
+ function->finishCreation(vm);
+ return function;
+ }
+
+ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
+ }
+
+ DECLARE_INFO;
+
+ WTF::String from;
+
+ template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+
+ return WebCore::subspaceForImpl<JSRequireResolveFunction, UseCustomHeapCellType::No>(
+ vm,
+ [](auto& spaces) { return spaces.m_clientSubspaceForRequireResolveFunction.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForRequireResolveFunction = WTFMove(space); },
+ [](auto& spaces) { return spaces.m_subspaceForRequireResolveFunction.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_subspaceForRequireResolveFunction = WTFMove(space); });
+ }
+
+private:
+ JSRequireResolveFunction(JSC::VM& vm, JSC::Structure* structure, const WTF::String& from_)
+ : JSC::InternalFunction(vm, structure, jsFunctionRequireResolve, jsFunctionRequireResolve)
+ , from(from_)
+ {
+ }
+
+ void finishCreation(JSC::VM& vm)
+ {
+ Base::finishCreation(vm);
+ }
+};
+
+const JSC::ClassInfo JSRequireResolveFunction::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSRequireResolveFunction) };
+
+JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireResolve, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
+{
+ JSRequireResolveFunction* thisObject = JSC::jsCast<JSRequireResolveFunction*>(callFrame->jsCallee());
+ return functionRequireResolve(globalObject, callFrame, thisObject->from);
+}
+
+JSValue Zig::ImportMetaObject::createResolveFunctionPrototype(JSC::VM& vm, Zig::GlobalObject* globalObject)
+{
+ return JSRequireResolveFunctionPrototype::create(vm, globalObject);
+}
+
+JSC::Structure* Zig::ImportMetaObject::createResolveFunctionStructure(JSC::VM& vm, Zig::GlobalObject* globalObject)
+{
+ JSValue prototype = globalObject->requireResolveFunctionPrototype();
+ return JSRequireResolveFunction::createStructure(vm, globalObject, prototype);
+}
+
+JSObject* Zig::ImportMetaObject::createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString)
{
+ Zig::GlobalObject* globalObject = static_cast<Zig::GlobalObject*>(lexicalGlobalObject);
JSFunction* requireFunction = JSFunction::create(vm, importMetaObjectRequireCodeGenerator(vm), globalObject);
+ auto* resolveFunction = JSRequireResolveFunction::create(vm, globalObject->requireResolveFunctionStructure(), pathString);
auto clientData = WebCore::clientData(vm);
- requireFunction->putDirectCustomAccessor(vm, clientData->builtinNames().resolvePublicName(), JSC::CustomGetterSetter::create(vm, functionRequireResolveLazyGetter, functionRequireResolveLazySetter), 0);
- requireFunction->putDirect(vm, clientData->builtinNames().pathPublicName(), jsString(vm, pathString), JSC::PropertyAttribute::DontEnum | 0);
+ requireFunction->putDirect(vm, clientData->builtinNames().pathPublicName(), jsString(vm, pathString), PropertyAttribute::DontEnum | 0);
+ requireFunction->putDirect(vm, clientData->builtinNames().resolvePublicName(), resolveFunction, PropertyAttribute::Function | PropertyAttribute::DontDelete | 0);
return requireFunction;
}
diff --git a/src/bun.js/bindings/ImportMetaObject.h b/src/bun.js/bindings/ImportMetaObject.h
index ff32c85d4..b9b7cce77 100644
--- a/src/bun.js/bindings/ImportMetaObject.h
+++ b/src/bun.js/bindings/ImportMetaObject.h
@@ -11,6 +11,7 @@
extern "C" JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolveSync);
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);
+extern "C" EncodedJSValue Bun__resolveSyncWithSource(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, ZigString* from, bool is_esm);
namespace Zig {
@@ -28,9 +29,15 @@ public:
return ptr;
}
+ static JSC::Structure* createResolveFunctionStructure(JSC::VM& vm, Zig::GlobalObject* globalObject);
+ static JSValue createResolveFunctionPrototype(JSC::VM& vm, Zig::GlobalObject* globalObject);
+ static JSObject* createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString);
+
static ImportMetaObject* create(JSC::JSGlobalObject* globalObject, JSC::JSValue key);
+
static inline Zig::ImportMetaObject* create(JSC::JSGlobalObject* globalObject, JSC::JSString* keyString)
{
+ // TODO: optimize this by reusing the same JSC::Structure object and using putDirectOffset
auto& vm = globalObject->vm();
auto view = keyString->value(globalObject);
JSC::Structure* structure = WebCore::getDOMStructure<Zig::ImportMetaObject>(vm, *reinterpret_cast<Zig::GlobalObject*>(globalObject));
@@ -94,8 +101,6 @@ public:
static JSObject* createPrototype(VM& vm, JSDOMGlobalObject& globalObject);
static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
- static JSObject* createRequireFunction(VM& vm, JSGlobalObject* globalObject, WTF::String& pathString);
-
private:
ImportMetaObject(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
: Base(vm, structure)
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index 10f76c15b..0d88ceac6 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -2582,6 +2582,16 @@ void GlobalObject::finishCreation(VM& vm)
init.set(structure);
});
+ m_requireResolveFunctionStructure.initLater(
+ [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::Structure>::Initializer& init) {
+ init.set(Zig::ImportMetaObject::createResolveFunctionStructure(init.vm, jsCast<Zig::GlobalObject*>(init.owner)));
+ });
+
+ m_resolveFunctionPrototype.initLater(
+ [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) {
+ init.set(Zig::ImportMetaObject::createResolveFunctionPrototype(init.vm, jsCast<Zig::GlobalObject*>(init.owner)).getObject());
+ });
+
m_JSFileSinkClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
auto* prototype = createJSSinkPrototype(init.vm, init.global, WebCore::SinkID::FileSink);
@@ -3463,6 +3473,9 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_emitReadableNextTickFunction.visit(visitor);
thisObject->m_JSBufferSubclassStructure.visit(visitor);
+ thisObject->m_requireResolveFunctionStructure.visit(visitor);
+ thisObject->m_resolveFunctionPrototype.visit(visitor);
+
for (auto& barrier : thisObject->m_thenables) {
visitor.append(barrier);
}
diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h
index 36c0356bc..3b8f4c342 100644
--- a/src/bun.js/bindings/ZigGlobalObject.h
+++ b/src/bun.js/bindings/ZigGlobalObject.h
@@ -243,6 +243,9 @@ public:
JSC::JSFunction* emitReadableNextTickFunction() { return m_emitReadableNextTickFunction.getInitializedOnMainThread(this); }
+ Structure* requireResolveFunctionStructure() { return m_requireResolveFunctionStructure.getInitializedOnMainThread(this); }
+ JSObject* requireResolveFunctionPrototype() { return m_resolveFunctionPrototype.getInitializedOnMainThread(this); }
+
JSC::JSObject* processObject()
{
return m_processObject.getInitializedOnMainThread(this);
@@ -444,6 +447,8 @@ private:
LazyProperty<JSGlobalObject, JSObject> m_subtleCryptoObject;
LazyProperty<JSGlobalObject, Structure> m_JSHTTPResponseController;
LazyProperty<JSGlobalObject, JSC::Structure> m_JSBufferSubclassStructure;
+ LazyProperty<JSGlobalObject, JSC::Structure> m_requireResolveFunctionStructure;
+ LazyProperty<JSGlobalObject, JSObject> m_resolveFunctionPrototype;
DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock);
void* m_bunVM;
diff --git a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
index aa0eb99a8..5b3605354 100644
--- a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
+++ b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
@@ -30,6 +30,7 @@ public:
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForPendingVirtualModuleResult;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCallSite;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNapiExternal;
+ std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRequireResolveFunction;
#include "ZigGeneratedClasses+DOMClientIsoSubspaces.h"
/* --- bun --- */
diff --git a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
index 3adfa0f44..461a63ac6 100644
--- a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
+++ b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
@@ -30,6 +30,7 @@ public:
std::unique_ptr<IsoSubspace> m_subspaceForPendingVirtualModuleResult;
std::unique_ptr<IsoSubspace> m_subspaceForCallSite;
std::unique_ptr<IsoSubspace> m_subspaceForNapiExternal;
+ std::unique_ptr<IsoSubspace> m_subspaceForRequireResolveFunction;
#include "ZigGeneratedClasses+DOMIsoSubspaces.h"
/*-- BUN --*/