aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/ImportMetaObject.cpp
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-06-25 19:48:56 -0700
committerGravatar GitHub <noreply@github.com> 2023-06-25 19:48:56 -0700
commit76626ac54b83a5a9a24abee1bc35f13a2196504d (patch)
tree0ad676a65b1629905a9b2cf7871f58409922f5d6 /src/bun.js/bindings/ImportMetaObject.cpp
parent116bcf424564a5f38ddf5f99f34453c175526fdc (diff)
downloadbun-76626ac54b83a5a9a24abee1bc35f13a2196504d.tar.gz
bun-76626ac54b83a5a9a24abee1bc35f13a2196504d.tar.zst
bun-76626ac54b83a5a9a24abee1bc35f13a2196504d.zip
Fix test failures in import.meta (#3403)
* Fix test failures in import.meta * regenerate * Use bound functions for `import.meta.require` and `import.meta.require.resolve` and `Module.createRequire` --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js/bindings/ImportMetaObject.cpp')
-rw-r--r--src/bun.js/bindings/ImportMetaObject.cpp193
1 files changed, 125 insertions, 68 deletions
diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp
index d201dafca..037305c81 100644
--- a/src/bun.js/bindings/ImportMetaObject.cpp
+++ b/src/bun.js/bindings/ImportMetaObject.cpp
@@ -59,6 +59,7 @@ static EncodedJSValue functionRequireResolve(JSC::JSGlobalObject* globalObject,
return JSC::JSValue::encode(JSC::JSValue {});
}
default: {
+ JSValue thisValue = callFrame->thisValue();
JSC::JSValue moduleName = callFrame->argument(0);
auto doIt = [&](const WTF::String& fromStr) -> JSC::EncodedJSValue {
@@ -130,7 +131,14 @@ Zig::ImportMetaObject* Zig::ImportMetaObject::create(JSC::JSGlobalObject* global
JSC_DECLARE_HOST_FUNCTION(jsFunctionRequireResolve);
JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireResolve, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
- return functionRequireResolve(globalObject, callFrame, callFrame->thisValue().toWTFString(globalObject));
+ JSValue thisValue = callFrame->thisValue();
+ WTF::String fromStr;
+
+ if (thisValue.isString()) {
+ fromStr = thisValue.toWTFString(globalObject);
+ }
+
+ return functionRequireResolve(globalObject, callFrame, fromStr);
}
JSC_DEFINE_CUSTOM_GETTER(jsRequireCacheGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
@@ -224,32 +232,49 @@ public:
}
};
-Structure* Zig::ImportMetaObject::createRequireFunctionStructure(VM& vm, JSGlobalObject* globalObject)
+JSObject* Zig::ImportMetaObject::createRequireResolveFunctionUnbound(VM& vm, JSGlobalObject* globalObject)
{
-
- return nullptr;
+ return ResolveFunction::create(globalObject);
}
-JSObject* Zig::ImportMetaObject::createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString)
+JSObject* Zig::ImportMetaObject::createRequireFunctionUnbound(VM& vm, JSGlobalObject* globalObject)
{
- auto* globalObject = lexicalGlobalObject;
- JSFunction* requireFunction = JSFunction::create(vm, importMetaObjectRequireCodeGenerator(vm), lexicalGlobalObject);
+ auto& builtinNames = WebCore::builtinNames(vm);
JSC::JSFunction* requireDotMainFunction = JSFunction::create(
vm,
moduleMainCodeGenerator(vm),
globalObject->globalScope());
- requireFunction->putDirect(
+ 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)));
- requireFunction->putDirect(vm, JSC::Identifier::fromString(vm, "extensions"_s), JSC::constructEmptyObject(globalObject), 0);
- requireFunction->putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "cache"_s), JSC::CustomGetterSetter::create(vm, Zig::jsRequireCacheGetter, Zig::jsRequireCacheSetter), 0);
- requireFunction->putDirect(vm, JSC::Identifier::fromString(vm, "resolve"_s), ResolveFunction::create(globalObject), JSC::PropertyAttribute::Function | 0);
- requireFunction->putDirect(vm, JSC::Identifier::fromString(vm, "path"_s), jsString(vm, pathString));
+ 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;
}
@@ -262,84 +287,107 @@ extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* g
JSC::VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
- switch (callFrame->argumentCount()) {
- case 0: {
+ JSValue thisValue = callFrame->thisValue();
+ JSC::JSValue moduleName = callFrame->argument(0);
+ JSC::JSValue fromValue = callFrame->argument(1);
- // not "requires" because "require" could be confusing
- JSC::throwTypeError(globalObject, scope, "needs 1 argument (a string)"_s);
+ if (moduleName.isUndefinedOrNull()) {
+ JSC::throwTypeError(globalObject, scope, "expects a string"_s);
scope.release();
return JSC::JSValue::encode(JSC::JSValue {});
}
- default: {
- JSC::JSValue moduleName = callFrame->argument(0);
- if (moduleName.isUndefinedOrNull()) {
- JSC::throwTypeError(globalObject, scope, "expects a string"_s);
- scope.release();
- return JSC::JSValue::encode(JSC::JSValue {});
- }
+ JSC__JSValue from;
+ bool isESM = true;
- JSC__JSValue from;
- bool isESM = true;
+ if (callFrame->argumentCount() > 1) {
- if (callFrame->argumentCount() > 1) {
- JSC::JSValue fromValue = callFrame->argument(1);
-
- 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 {}));
- }
+ 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 {}));
}
+ }
- if (!fromValue.isUndefinedOrNull() && fromValue.isObject()) {
+ if (!fromValue.isUndefinedOrNull() && fromValue.isObject()) {
- if (auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "paths"_s))) {
- if (pathsObject.isCell() && pathsObject.asCell()->type() == JSC::JSType::ArrayType) {
- auto pathsArray = JSC::jsCast<JSC::JSArray*>(pathsObject);
- if (pathsArray->length() > 0) {
- fromValue = pathsArray->getIndex(globalObject, 0);
- RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
- }
+ if (auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "paths"_s))) {
+ if (pathsObject.isCell() && pathsObject.asCell()->type() == JSC::JSType::ArrayType) {
+ auto pathsArray = JSC::jsCast<JSC::JSArray*>(pathsObject);
+ if (pathsArray->length() > 0) {
+ fromValue = pathsArray->getIndex(globalObject, 0);
+ 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 {}));
- }
-
- if (fromValue.isString()) {
- from = JSC::JSValue::encode(fromValue);
}
- } else {
- JSC::JSObject* thisObject = JSC::jsDynamicCast<JSC::JSObject*>(callFrame->thisValue());
- if (UNLIKELY(!thisObject)) {
- auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
- JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync must be bound to an import.meta object"_s);
- return JSC::JSValue::encode(JSC::JSValue {});
- }
-
- auto clientData = WebCore::clientData(vm);
- JSValue pathProperty = thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().pathPublicName());
-
- if (pathProperty && pathProperty.isString())
- from = JSC::JSValue::encode(pathProperty);
+ } else if (fromValue.isBoolean()) {
+ isESM = fromValue.toBoolean(globalObject);
+ RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
+ fromValue = JSC::jsUndefined();
}
- auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from, isESM);
+ if (fromValue.isString()) {
+ from = JSC::JSValue::encode(fromValue);
+ } else if (thisValue.isString()) {
+ from = JSC::JSValue::encode(thisValue);
+ }
- if (!JSC::JSValue::decode(result).isString()) {
- JSC::throwException(globalObject, scope, JSC::JSValue::decode(result));
+ } else if (thisValue.isString()) {
+ from = JSC::JSValue::encode(thisValue);
+ } else {
+ JSC::JSObject* thisObject = JSC::jsDynamicCast<JSC::JSObject*>(thisValue);
+ if (UNLIKELY(!thisObject)) {
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync must be bound to an import.meta object"_s);
return JSC::JSValue::encode(JSC::JSValue {});
}
+ auto clientData = WebCore::clientData(vm);
+ JSValue pathProperty = thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().pathPublicName());
+
+ if (pathProperty && pathProperty.isString())
+ from = JSC::JSValue::encode(pathProperty);
+ }
+
+ 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));
+ return JSC::JSValue::encode(JSC::JSValue {});
+ }
+
+ scope.release();
+ return result;
+}
+
+extern "C" EncodedJSValue functionImportMeta__resolveSyncPrivate(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
+{
+ JSC::VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+
+ JSC::JSValue moduleName = callFrame->argument(0);
+ JSValue from = callFrame->argument(1);
+ bool isESM = callFrame->argument(2).asBoolean();
+
+ if (moduleName.isUndefinedOrNull()) {
+ JSC::throwTypeError(globalObject, scope, "expected module name as a string"_s);
scope.release();
- return result;
+ return JSC::JSValue::encode(JSC::JSValue {});
}
+
+ RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
+
+ auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), JSValue::encode(from), isESM);
+
+ if (!JSC::JSValue::decode(result).isString()) {
+ JSC::throwException(globalObject, scope, JSC::JSValue::decode(result));
+ return JSC::JSValue::encode(JSC::JSValue {});
}
+
+ scope.release();
+ return result;
}
JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolve);
@@ -536,7 +584,16 @@ void ImportMetaObject::finishCreation(VM& vm)
this->requireProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSFunction>::Initializer& init) {
ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
- JSFunction* value = jsCast<JSFunction*>(ImportMetaObject::createRequireFunction(init.vm, meta->globalObject(), meta->url));
+
+ WTF::URL url = meta->url.startsWith('/') ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
+ WTF::StringView path;
+ if (url.protocolIs("file"_s)) {
+ path = url.fileSystemPath();
+ } else {
+ path = url.path();
+ }
+
+ JSFunction* value = jsCast<JSFunction*>(ImportMetaObject::createRequireFunction(init.vm, meta->globalObject(), path.toString()));
init.set(value);
});
this->urlProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSString>::Initializer& init) {