mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 02:18:47 +00:00
Compare commits
1 Commits
ciro/fix-a
...
jdalton/cu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c821a4d14a |
@@ -68,11 +68,13 @@
|
||||
#include <JavaScriptCore/HeapAnalyzer.h>
|
||||
|
||||
extern "C" bool Bun__isBunMain(JSC::JSGlobalObject* global, const BunString*);
|
||||
extern "C" JSC__JSValue Bun__Path__basename(JSC__JSGlobalObject* arg0, bool arg1, JSC__JSValue* arg2, uint16_t arg3);
|
||||
extern "C" JSC__JSValue Bun__Path__dirname(JSC__JSGlobalObject* arg0, bool arg1, JSC__JSValue* arg2, uint16_t arg3);
|
||||
|
||||
namespace Bun {
|
||||
using namespace JSC;
|
||||
|
||||
JSC_DECLARE_HOST_FUNCTION(jsFunctionRequireCommonJS);
|
||||
JSC_DECLARE_HOST_FUNCTION(jsFunctionRequirePrivate);
|
||||
|
||||
static bool canPerformFastEnumeration(Structure* s)
|
||||
{
|
||||
@@ -103,19 +105,23 @@ static bool evaluateCommonJSModuleOnce(JSC::VM& vm, Zig::GlobalObject* globalObj
|
||||
return false;
|
||||
}
|
||||
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
auto builtinNames = clientData->builtinNames();
|
||||
auto globalString = globalObject->commonStrings().resolveString(globalObject);
|
||||
|
||||
JSFunction* resolveFunction = JSC::JSBoundFunction::create(vm,
|
||||
globalObject,
|
||||
globalObject->requireResolveFunctionUnbound(),
|
||||
moduleObject->id(),
|
||||
ArgList(), 1, globalObject->commonStrings().resolveString(globalObject));
|
||||
ArgList(), 1, globalString);
|
||||
JSFunction* requireFunction = JSC::JSBoundFunction::create(vm,
|
||||
globalObject,
|
||||
globalObject->requireFunctionUnbound(),
|
||||
moduleObject,
|
||||
ArgList(), 1, globalObject->commonStrings().requireString(globalObject));
|
||||
ArgList(), 1, globalString);
|
||||
requireFunction->putDirect(vm, vm.propertyNames->resolve, resolveFunction, 0);
|
||||
moduleObject->putDirect(vm, WebCore::clientData(vm)->builtinNames().requirePublicName(), requireFunction, 0);
|
||||
|
||||
moduleObject->putDirect(vm, builtinNames.requirePublicName(), requireFunction, 0);
|
||||
moduleObject->hasEvaluated = true;
|
||||
|
||||
// This will return 0 if there was a syntax error or an allocation failure
|
||||
@@ -148,11 +154,11 @@ static bool evaluateCommonJSModuleOnce(JSC::VM& vm, Zig::GlobalObject* globalObj
|
||||
return exception.get() == nullptr;
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionLoadModule, (JSGlobalObject * lexicalGlobalObject, CallFrame* callframe))
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionEvaluateCommonJSModule, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
|
||||
{
|
||||
auto* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
JSCommonJSModule* moduleObject = jsDynamicCast<JSCommonJSModule*>(callframe->argument(0));
|
||||
JSCommonJSModule* moduleObject = jsDynamicCast<JSCommonJSModule*>(callFrame->argument(0));
|
||||
if (!moduleObject) {
|
||||
RELEASE_AND_RETURN(throwScope, JSValue::encode(jsBoolean(true)));
|
||||
}
|
||||
@@ -184,18 +190,18 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionLoadModule, (JSGlobalObject * lexicalGlobalOb
|
||||
RELEASE_AND_RETURN(throwScope, JSValue::encode(jsBoolean(true)));
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(requireResolvePathsFunction, (JSGlobalObject * globalObject, CallFrame* callframe))
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireResolvePaths, (JSGlobalObject * globalObject, CallFrame* callFrame))
|
||||
{
|
||||
return JSValue::encode(JSC::constructEmptyArray(globalObject, nullptr, 0));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsRequireCacheGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
JSC_DEFINE_CUSTOM_GETTER(requireCacheGetter, (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_DEFINE_CUSTOM_SETTER(requireCacheSetter,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
@@ -208,11 +214,11 @@ JSC_DEFINE_CUSTOM_SETTER(jsRequireCacheSetter,
|
||||
}
|
||||
|
||||
static const HashTableValue RequireResolveFunctionPrototypeValues[] = {
|
||||
{ "paths"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, requireResolvePathsFunction, 1 } },
|
||||
{ "paths"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsFunctionRequireResolvePaths, 1 } },
|
||||
};
|
||||
|
||||
static const HashTableValue RequireFunctionPrototypeValues[] = {
|
||||
{ "cache"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsRequireCacheGetter, jsRequireCacheSetter } },
|
||||
{ "cache"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, requireCacheGetter, requireCacheSetter } },
|
||||
};
|
||||
|
||||
Structure* RequireFunctionPrototype::createStructure(
|
||||
@@ -236,7 +242,6 @@ Structure* RequireResolveFunctionPrototype::createStructure(
|
||||
RequireResolveFunctionPrototype* RequireResolveFunctionPrototype::create(JSC::JSGlobalObject* globalObject)
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
|
||||
auto* structure = RequireResolveFunctionPrototype::createStructure(vm, globalObject);
|
||||
RequireResolveFunctionPrototype* prototype = new (NotNull, JSC::allocateCell<RequireResolveFunctionPrototype>(vm)) RequireResolveFunctionPrototype(vm, structure);
|
||||
prototype->finishCreation(vm);
|
||||
@@ -247,13 +252,10 @@ RequireFunctionPrototype* RequireFunctionPrototype::create(
|
||||
JSC::JSGlobalObject* globalObject)
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
|
||||
auto* structure = RequireFunctionPrototype::createStructure(vm, globalObject);
|
||||
RequireFunctionPrototype* prototype = new (NotNull, JSC::allocateCell<RequireFunctionPrototype>(vm)) RequireFunctionPrototype(vm, structure);
|
||||
prototype->finishCreation(vm);
|
||||
|
||||
prototype->putDirect(vm, builtinNames(vm).resolvePublicName(), jsCast<Zig::GlobalObject*>(globalObject)->requireResolveFunctionUnbound(), 0);
|
||||
|
||||
return prototype;
|
||||
}
|
||||
|
||||
@@ -263,26 +265,34 @@ void RequireFunctionPrototype::finishCreation(JSC::VM& vm)
|
||||
ASSERT(inherits(info()));
|
||||
|
||||
reifyStaticProperties(vm, info(), RequireFunctionPrototypeValues, *this);
|
||||
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(this->globalObject());
|
||||
auto builtinNames = clientData->builtinNames();
|
||||
|
||||
JSC::JSFunction* requireDotMainFunction = JSFunction::create(
|
||||
vm,
|
||||
moduleMainCodeGenerator(vm),
|
||||
globalObject()->globalScope());
|
||||
globalObject->globalScope());
|
||||
|
||||
this->putDirectAccessor(
|
||||
globalObject(),
|
||||
globalObject,
|
||||
JSC::Identifier::fromString(vm, "main"_s),
|
||||
JSC::GetterSetter::create(vm, globalObject(), requireDotMainFunction, requireDotMainFunction),
|
||||
JSC::GetterSetter::create(vm, globalObject, requireDotMainFunction, requireDotMainFunction),
|
||||
PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | 0);
|
||||
|
||||
auto extensions = constructEmptyObject(globalObject());
|
||||
this->putDirect(vm, builtinNames.resolvePublicName(), globalObject->requireResolveFunctionUnbound(), 0);
|
||||
|
||||
auto extensions = constructEmptyObject(vm, globalObject->nullPrototypeObjectStructure());
|
||||
extensions->putDirect(vm, JSC::Identifier::fromString(vm, ".js"_s), jsBoolean(true), 0);
|
||||
extensions->putDirect(vm, JSC::Identifier::fromString(vm, ".json"_s), jsBoolean(true), 0);
|
||||
extensions->putDirect(vm, JSC::Identifier::fromString(vm, ".node"_s), jsBoolean(true), 0);
|
||||
|
||||
extensions->putDirect(vm, builtinNames.originalStructureIDPrivateName(), jsNumber(0), 0);
|
||||
extensions->putDirect(vm, builtinNames.originalStructureIDPrivateName(), jsNumber(extensions->structureID().bits()), 0);
|
||||
this->putDirect(vm, JSC::Identifier::fromString(vm, "extensions"_s), extensions, 0);
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(getterFilename, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
JSC_DEFINE_CUSTOM_GETTER(filenameGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
@@ -290,7 +300,20 @@ JSC_DEFINE_CUSTOM_GETTER(getterFilename, (JSC::JSGlobalObject * globalObject, JS
|
||||
}
|
||||
return JSValue::encode(thisObject->m_filename.get());
|
||||
}
|
||||
JSC_DEFINE_CUSTOM_GETTER(getterId, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
|
||||
JSC_DEFINE_CUSTOM_SETTER(filenameSetter,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (!thisObject)
|
||||
return false;
|
||||
|
||||
thisObject->m_filename.set(globalObject->vm(), thisObject, JSValue::decode(value).toString(globalObject));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(idGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
@@ -299,16 +322,42 @@ JSC_DEFINE_CUSTOM_GETTER(getterId, (JSC::JSGlobalObject * globalObject, JSC::Enc
|
||||
return JSValue::encode(thisObject->m_id.get());
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(getterPath, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
JSC_DEFINE_CUSTOM_SETTER(idSetter,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (!thisObject)
|
||||
return false;
|
||||
|
||||
thisObject->m_id.set(globalObject->vm(), thisObject, JSValue::decode(value).toString(globalObject));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(loadedGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
return JSValue::encode(thisObject->m_id.get());
|
||||
|
||||
return JSValue::encode(jsBoolean(thisObject->hasEvaluated));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(getterParent, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
JSC_DEFINE_CUSTOM_SETTER(loadedSetter,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (!thisObject)
|
||||
return false;
|
||||
|
||||
thisObject->hasEvaluated = JSValue::decode(value).toBoolean(globalObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(parentGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
@@ -334,7 +383,29 @@ JSC_DEFINE_CUSTOM_GETTER(getterParent, (JSC::JSGlobalObject * globalObject, JSC:
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_SETTER(setterPath,
|
||||
JSC_DEFINE_CUSTOM_SETTER(parentSetter,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (!thisObject)
|
||||
return false;
|
||||
|
||||
thisObject->m_parent.set(globalObject->vm(), thisObject, JSValue::decode(value));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(pathGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
return JSValue::encode(thisObject->m_id.get());
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_SETTER(pathSetter,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
@@ -348,7 +419,7 @@ JSC_DEFINE_CUSTOM_SETTER(setterPath,
|
||||
|
||||
extern "C" JSC::EncodedJSValue Resolver__propForRequireMainPaths(JSGlobalObject*);
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(getterPaths, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
JSC_DEFINE_CUSTOM_GETTER(pathsGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
@@ -363,17 +434,7 @@ JSC_DEFINE_CUSTOM_GETTER(getterPaths, (JSC::JSGlobalObject * globalObject, JSC::
|
||||
return JSValue::encode(thisObject->m_paths.get());
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(getterLoaded, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
return JSValue::encode(jsBoolean(thisObject->hasEvaluated));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_SETTER(setterPaths,
|
||||
JSC_DEFINE_CUSTOM_SETTER(pathsSetter,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
@@ -385,62 +446,14 @@ JSC_DEFINE_CUSTOM_SETTER(setterPaths,
|
||||
return true;
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_SETTER(setterFilename,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (!thisObject)
|
||||
return false;
|
||||
|
||||
thisObject->m_filename.set(globalObject->vm(), thisObject, JSValue::decode(value).toString(globalObject));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_SETTER(setterId,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (!thisObject)
|
||||
return false;
|
||||
|
||||
thisObject->m_id.set(globalObject->vm(), thisObject, JSValue::decode(value).toString(globalObject));
|
||||
return true;
|
||||
}
|
||||
JSC_DEFINE_CUSTOM_SETTER(setterParent,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (!thisObject)
|
||||
return false;
|
||||
|
||||
thisObject->m_parent.set(globalObject->vm(), thisObject, JSValue::decode(value));
|
||||
|
||||
return true;
|
||||
}
|
||||
JSC_DEFINE_CUSTOM_SETTER(setterLoaded,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (!thisObject)
|
||||
return false;
|
||||
|
||||
thisObject->hasEvaluated = JSValue::decode(value).toBoolean(globalObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSValue createChildren(VM& vm, JSObject* object)
|
||||
{
|
||||
return constructEmptyArray(object->globalObject(), nullptr, 0);
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(functionCommonJSModuleRecord_compile, (JSGlobalObject * globalObject, CallFrame* callframe))
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionCommonJSModuleRecord_compile, (JSGlobalObject * globalObject, CallFrame* callFrame))
|
||||
{
|
||||
auto* moduleObject = jsDynamicCast<JSCommonJSModule*>(callframe->thisValue());
|
||||
auto* moduleObject = jsDynamicCast<JSCommonJSModule*>(callFrame->thisValue());
|
||||
if (!moduleObject) {
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
@@ -448,42 +461,46 @@ JSC_DEFINE_HOST_FUNCTION(functionCommonJSModuleRecord_compile, (JSGlobalObject *
|
||||
auto& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
String sourceString = callframe->argument(0).toWTFString(globalObject);
|
||||
JSValue sourceValue = callFrame->argument(0);
|
||||
auto sourceWTF = sourceValue.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, JSValue::encode({}));
|
||||
|
||||
String filenameString = callframe->argument(1).toWTFString(globalObject);
|
||||
JSValue filenameValue = callFrame->argument(1);
|
||||
auto filenameWTF = filenameValue.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, JSValue::encode({}));
|
||||
|
||||
auto filename = JSC::jsStringWithCache(vm, filenameWTF);
|
||||
WTF::Vector<JSC::EncodedJSValue, 1> dirnameArgs;
|
||||
dirnameArgs.reserveInitialCapacity(1);
|
||||
dirnameArgs.unsafeAppendWithoutCapacityCheck(JSValue::encode(filenameValue));
|
||||
#if OS(WINDOWS)
|
||||
auto dirname = JSValue::decode(Bun__Path__dirname(globalObject, true, reinterpret_cast<JSC__JSValue*>(dirnameArgs.data()), 1)).toString(globalObject);
|
||||
#else
|
||||
auto dirname = JSValue::decode(Bun__Path__dirname(globalObject, false, reinterpret_cast<JSC__JSValue*>(dirnameArgs.data()), 1)).toString(globalObject);
|
||||
#endif
|
||||
|
||||
String wrappedString = makeString(
|
||||
"(function(exports,require,module,__filename,__dirname){"_s,
|
||||
sourceString,
|
||||
sourceWTF,
|
||||
"\n})"_s);
|
||||
|
||||
SourceCode sourceCode = makeSource(
|
||||
SourceCode sourceCode = JSC::makeSource(
|
||||
WTFMove(wrappedString),
|
||||
SourceOrigin(URL::fileURLWithFileSystemPath(filenameString)),
|
||||
SourceOrigin(URL::fileURLWithFileSystemPath(filenameWTF)),
|
||||
JSC::SourceTaintedOrigin::Untainted,
|
||||
filenameString,
|
||||
filenameWTF,
|
||||
WTF::TextPosition(),
|
||||
JSC::SourceProviderSourceType::Program);
|
||||
JSSourceCode* jsSourceCode = JSSourceCode::create(vm, WTFMove(sourceCode));
|
||||
moduleObject->sourceCode.set(vm, moduleObject, jsSourceCode);
|
||||
|
||||
auto index = filenameString.reverseFind('/', filenameString.length());
|
||||
String dirnameString;
|
||||
if (index != WTF::notFound) {
|
||||
dirnameString = filenameString.substring(0, index);
|
||||
} else {
|
||||
dirnameString = "/"_s;
|
||||
}
|
||||
|
||||
WTF::NakedPtr<JSC::Exception> exception;
|
||||
evaluateCommonJSModuleOnce(
|
||||
vm,
|
||||
jsCast<Zig::GlobalObject*>(globalObject),
|
||||
moduleObject,
|
||||
jsString(vm, dirnameString),
|
||||
jsString(vm, filenameString),
|
||||
dirname,
|
||||
filename,
|
||||
exception);
|
||||
|
||||
if (exception) {
|
||||
@@ -495,15 +512,86 @@ JSC_DEFINE_HOST_FUNCTION(functionCommonJSModuleRecord_compile, (JSGlobalObject *
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
extern "C" JSC::EncodedJSValue jsFunctionResolveSyncPrivate(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
|
||||
{
|
||||
auto* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
auto& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
JSValue moduleName = callFrame->argument(0);
|
||||
JSValue from = callFrame->argument(1);
|
||||
bool isESM = callFrame->argument(2).asBoolean();
|
||||
|
||||
if (moduleName.isUndefinedOrNull()) {
|
||||
JSC::throwTypeError(globalObject, throwScope, "expected module name as a string"_s);
|
||||
throwScope.release();
|
||||
return JSValue::encode(JSValue {});
|
||||
}
|
||||
|
||||
RETURN_IF_EXCEPTION(throwScope, JSValue::encode(JSValue {}));
|
||||
|
||||
if (globalObject->onLoadPlugins.hasVirtualModules()) {
|
||||
if (moduleName.isString()) {
|
||||
auto moduleStr = moduleName.toWTFString(globalObject);
|
||||
auto resolvedString = globalObject->onLoadPlugins.resolveVirtualModule(moduleStr, from.toWTFString(globalObject));
|
||||
if (resolvedString) {
|
||||
if (moduleStr == resolvedString.value())
|
||||
return JSValue::encode(moduleName);
|
||||
return JSValue::encode(jsString(vm, resolvedString.value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isESM) {
|
||||
auto overrideHandler = globalObject->m_nodeModuleOverriddenResolveFilename.get();
|
||||
if (UNLIKELY(overrideHandler)) {
|
||||
ASSERT(overrideHandler->isCallable());
|
||||
auto requireMap = globalObject->requireMap();
|
||||
auto* parentModuleObject = jsDynamicCast<Bun::JSCommonJSModule*>(requireMap->get(globalObject, from));
|
||||
|
||||
JSValue parentID = jsUndefined();
|
||||
if (parentModuleObject) {
|
||||
parentID = parentModuleObject->id();
|
||||
} else {
|
||||
parentID = from;
|
||||
}
|
||||
|
||||
auto parentIdStr = parentID.toWTFString(globalObject);
|
||||
auto bunStr = Bun::toString(parentIdStr);
|
||||
|
||||
MarkedArgumentBuffer args;
|
||||
args.append(moduleName);
|
||||
args.append(parentModuleObject);
|
||||
args.append(jsBoolean(Bun__isBunMain(globalObject, &bunStr)));
|
||||
|
||||
// `Module` will be cached because requesting it is the only way to access `Module._resolveFilename`.
|
||||
auto* ModuleModuleObject = jsCast<Bun::JSCommonJSModule*>(requireMap->get(globalObject, JSC::jsStringWithCache(vm, "module"_s)));
|
||||
auto ModuleExportsObject = ModuleModuleObject->exportsObject();
|
||||
|
||||
return JSValue::encode(JSC::call(globalObject, overrideHandler, JSC::getCallData(overrideHandler), ModuleExportsObject, args));
|
||||
}
|
||||
}
|
||||
|
||||
auto result = Bun__resolveSync(globalObject, JSValue::encode(moduleName), JSValue::encode(from), isESM);
|
||||
|
||||
if (!JSValue::decode(result).isString()) {
|
||||
JSC::throwException(globalObject, throwScope, JSValue::decode(result));
|
||||
return JSValue::encode(JSValue {});
|
||||
}
|
||||
|
||||
throwScope.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct HashTableValue JSCommonJSModulePrototypeTableValues[] = {
|
||||
{ "_compile"_s, static_cast<unsigned>(PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, functionCommonJSModuleRecord_compile, 2 } },
|
||||
{ "_compile"_s, static_cast<unsigned>(PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, jsFunctionCommonJSModuleRecord_compile, 2 } },
|
||||
{ "children"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, createChildren } },
|
||||
{ "filename"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterFilename, setterFilename } },
|
||||
{ "id"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterId, setterId } },
|
||||
{ "loaded"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterLoaded, setterLoaded } },
|
||||
{ "parent"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, getterParent, setterParent } },
|
||||
{ "path"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterPath, setterPath } },
|
||||
{ "paths"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterPaths, setterPaths } },
|
||||
{ "filename"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, filenameGetter, filenameSetter } },
|
||||
{ "id"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, idGetter, idSetter } },
|
||||
{ "loaded"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, loadedGetter, loadedSetter } },
|
||||
{ "parent"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, parentGetter, parentSetter } },
|
||||
{ "path"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, pathGetter, pathSetter } },
|
||||
{ "paths"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, pathsGetter, pathsSetter } },
|
||||
};
|
||||
|
||||
class JSCommonJSModulePrototype final : public JSC::JSNonFinalObject {
|
||||
@@ -522,7 +610,7 @@ public:
|
||||
static JSC::Structure* createStructure(
|
||||
JSC::VM& vm,
|
||||
JSC::JSGlobalObject* globalObject,
|
||||
JSC::JSValue prototype)
|
||||
JSValue prototype)
|
||||
{
|
||||
auto* structure = JSC::Structure::create(vm, globalObject, prototype, TypeInfo(JSC::ObjectType, StructureFlags), info());
|
||||
structure->setMayBePrototype(true);
|
||||
@@ -556,7 +644,7 @@ public:
|
||||
globalObject,
|
||||
clientData(vm)->builtinNames().requirePrivateName(),
|
||||
2,
|
||||
jsFunctionRequireCommonJS, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete);
|
||||
jsFunctionRequirePrivate, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -577,7 +665,6 @@ JSC::Structure* JSCommonJSModule::createStructure(
|
||||
JSC::JSGlobalObject* globalObject)
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
|
||||
auto* prototype = JSCommonJSModulePrototype::create(vm, globalObject, JSCommonJSModulePrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
|
||||
|
||||
// Do not set the number of inline properties on this structure
|
||||
@@ -598,39 +685,41 @@ JSCommonJSModule* JSCommonJSModule::create(
|
||||
return cell;
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionCreateCommonJSModule, (JSGlobalObject * globalObject, CallFrame* callframe))
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionCreateCommonJSModule, (JSGlobalObject * globalObject, CallFrame* callFrame))
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
RELEASE_ASSERT(callframe->argumentCount() == 4);
|
||||
RELEASE_ASSERT(callFrame->argumentCount() == 4);
|
||||
|
||||
auto id = callframe->uncheckedArgument(0).toWTFString(globalObject);
|
||||
JSValue object = callframe->uncheckedArgument(1);
|
||||
JSValue hasEvaluated = callframe->uncheckedArgument(2);
|
||||
auto id = callFrame->uncheckedArgument(0).toString(globalObject);
|
||||
JSValue object = callFrame->uncheckedArgument(1);
|
||||
JSValue hasEvaluated = callFrame->uncheckedArgument(2);
|
||||
ASSERT(hasEvaluated.isBoolean());
|
||||
JSValue parent = callframe->uncheckedArgument(3);
|
||||
JSValue parent = callFrame->uncheckedArgument(3);
|
||||
|
||||
return JSValue::encode(JSCommonJSModule::create(jsCast<Zig::GlobalObject*>(globalObject), id, object, hasEvaluated.isTrue(), parent));
|
||||
}
|
||||
|
||||
JSCommonJSModule* JSCommonJSModule::create(
|
||||
Zig::GlobalObject* globalObject,
|
||||
const WTF::String& key,
|
||||
JSC::JSString* id,
|
||||
JSValue exportsObject,
|
||||
bool hasEvaluated,
|
||||
JSValue parent)
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
JSString* requireMapKey = JSC::jsStringWithCache(vm, key);
|
||||
auto index = key.reverseFind('/', key.length());
|
||||
JSString* dirname = jsEmptyString(vm);
|
||||
if (index != WTF::notFound) {
|
||||
dirname = JSC::jsSubstring(globalObject, requireMapKey, 0, index);
|
||||
}
|
||||
WTF::Vector<JSC::EncodedJSValue, 1> dirnameArgs;
|
||||
dirnameArgs.reserveInitialCapacity(1);
|
||||
dirnameArgs.unsafeAppendWithoutCapacityCheck(JSValue::encode(id));
|
||||
#if OS(WINDOWS)
|
||||
auto dirname = JSValue::decode(Bun__Path__dirname(globalObject, true, reinterpret_cast<JSC__JSValue*>(dirnameArgs.data()), 1)).toString(globalObject);
|
||||
#else
|
||||
auto dirname = JSValue::decode(Bun__Path__dirname(globalObject, false, reinterpret_cast<JSC__JSValue*>(dirnameArgs.data()), 1)).toString(globalObject);
|
||||
#endif
|
||||
|
||||
auto* out = JSCommonJSModule::create(
|
||||
vm,
|
||||
globalObject->CommonJSModuleObjectStructure(),
|
||||
requireMapKey, requireMapKey, dirname, nullptr);
|
||||
id, id, dirname, nullptr);
|
||||
|
||||
out->putDirect(
|
||||
vm,
|
||||
@@ -837,8 +926,6 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject,
|
||||
JSC::MarkedArgumentBuffer& exportValues)
|
||||
{
|
||||
auto result = this->exportsObject();
|
||||
|
||||
auto& vm = globalObject->vm();
|
||||
populateESMExports(globalObject, result, exportNames, exportValues, this->ignoreESModuleAnnotation);
|
||||
}
|
||||
|
||||
@@ -890,23 +977,82 @@ const JSC::ClassInfo JSCommonJSModule::s_info = { "Module"_s, &Base::s_info, nul
|
||||
const JSC::ClassInfo RequireResolveFunctionPrototype::s_info = { "resolve"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RequireResolveFunctionPrototype) };
|
||||
const JSC::ClassInfo RequireFunctionPrototype::s_info = { "require"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(RequireFunctionPrototype) };
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlobalObject, CallFrame* callframe))
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionRequirePrivate, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
|
||||
{
|
||||
auto* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
auto& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(callframe->thisValue());
|
||||
if (!thisObject)
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(callFrame->thisValue());
|
||||
if (!thisObject) {
|
||||
return throwVMTypeError(globalObject, throwScope);
|
||||
}
|
||||
|
||||
JSValue specifierValue = callframe->argument(0);
|
||||
WTF::String specifier = specifierValue.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
|
||||
JSValue specifierValue = callFrame->argument(0);
|
||||
auto specifier = specifierValue.toWTFString(globalObject);
|
||||
auto* moduleObject = jsCast<JSCommonJSModule*>(callFrame->argument(1));
|
||||
|
||||
auto requireUnbound = globalObject->requireFunctionUnbound();
|
||||
auto requireUnboundPrototype = requireUnbound->getPrototype(vm, globalObject);
|
||||
if (requireUnboundPrototype.isObject()) {
|
||||
JSObject* prototype = requireUnboundPrototype.getObject();
|
||||
auto extensionsValue = prototype->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "extensions"_s));
|
||||
if (extensionsValue.isObject()) {
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
auto builtinNames = clientData->builtinNames();
|
||||
JSObject* extensionsObject = extensionsValue.getObject();
|
||||
bool structureChanged = extensionsObject->getDirect(vm, builtinNames.originalStructureIDPrivateName()) != jsNumber(extensionsObject->structureID().bits());
|
||||
if (UNLIKELY(structureChanged)) {
|
||||
WTF::Vector<JSC::EncodedJSValue, 1> basenameArgs;
|
||||
basenameArgs.reserveInitialCapacity(1);
|
||||
basenameArgs.unsafeAppendWithoutCapacityCheck(JSC::JSValue::encode(specifierValue));
|
||||
#if OS(WINDOWS)
|
||||
auto basename = JSValue::decode(Bun__Path__basename(globalObject, true, reinterpret_cast<JSC__JSValue*>(basenameArgs.data()), 1)).toWTFString(globalObject);
|
||||
#else
|
||||
auto basename = JSValue::decode(Bun__Path__basename(globalObject, false, reinterpret_cast<JSC__JSValue*>(basenameArgs.data()), 1)).toWTFString(globalObject);
|
||||
#endif
|
||||
size_t index = 0;
|
||||
uint16_t startIndex = 0;
|
||||
JSFunction* extHandler = nullptr;
|
||||
// Find longest registered extension.
|
||||
while ((index = basename.find("."_s, startIndex)) != WTF::notFound) {
|
||||
if (index == 0) {
|
||||
// Skip dotfiles like .gitignore
|
||||
continue;
|
||||
}
|
||||
auto extStr = basename.substring(index);
|
||||
auto extValue = extensionsObject->get(globalObject, JSC::Identifier::fromString(vm, extStr));
|
||||
if (UNLIKELY(extValue.isCallable())) {
|
||||
extHandler = jsCast<JSFunction*>(extValue);
|
||||
break;
|
||||
}
|
||||
startIndex = index + 1;
|
||||
}
|
||||
// Fallback to ".js".
|
||||
if (LIKELY(!extHandler)) {
|
||||
auto extValue = extensionsObject->get(globalObject, JSC::Identifier::fromString(vm, ".js"_s));
|
||||
if (UNLIKELY(extValue.isCallable())) {
|
||||
extHandler = jsCast<JSFunction*>(extValue);
|
||||
}
|
||||
}
|
||||
if (UNLIKELY(extHandler)) {
|
||||
JSC::CallData callData = JSC::getCallData(extHandler);
|
||||
MarkedArgumentBuffer args;
|
||||
args.append(moduleObject); // module
|
||||
args.append(specifierValue); // id
|
||||
// Call Module._extensions[ext](module, id)
|
||||
JSC::call(globalObject, extHandler, callData, extensionsObject, args);
|
||||
return JSValue::encode(moduleObject->exportsObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Special-case for "process" to just return the process object directly.
|
||||
if (UNLIKELY(specifier == "process"_s || specifier == "node:process"_s)) {
|
||||
jsCast<JSCommonJSModule*>(callframe->argument(1))->putDirect(vm, builtinNames(vm).exportsPublicName(), globalObject->processObject(), 0);
|
||||
moduleObject->putDirect(vm, Bun::builtinNames(vm).exportsPublicName(), globalObject->processObject(), 0);
|
||||
return JSValue::encode(globalObject->processObject());
|
||||
}
|
||||
|
||||
@@ -918,17 +1064,16 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo
|
||||
BunString typeAttributeStr = { BunStringTag::Dead };
|
||||
String typeAttribute = String();
|
||||
|
||||
|
||||
// We need to be able to wire in the "type" import attribute from bundled code..
|
||||
// so we do it via CommonJS require().
|
||||
int32_t previousArgumentCount = callframe->argument(2).asInt32();
|
||||
int32_t previousArgumentCount = callFrame->argument(2).asInt32();
|
||||
// If they called require(id), skip the check for the type attribute
|
||||
if (UNLIKELY(previousArgumentCount == 2)) {
|
||||
JSValue val = callframe->argument(3);
|
||||
if (val.isObject()) {
|
||||
JSObject* obj = val.getObject();
|
||||
JSValue attrValue = callFrame->argument(3);
|
||||
if (attrValue.isObject()) {
|
||||
JSObject* attrObject = attrValue.getObject();
|
||||
// This getter is expensive and rare.
|
||||
if (auto typeValue = obj->getIfPropertyExists(globalObject, vm.propertyNames->type)) {
|
||||
if (auto typeValue = attrObject->getIfPropertyExists(globalObject, vm.propertyNames->type)) {
|
||||
if (typeValue.isString()) {
|
||||
typeAttribute = typeValue.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
@@ -941,7 +1086,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo
|
||||
|
||||
JSValue fetchResult = Bun::fetchCommonJSModule(
|
||||
globalObject,
|
||||
jsCast<JSCommonJSModule*>(callframe->argument(1)),
|
||||
moduleObject,
|
||||
specifierValue,
|
||||
&specifierStr,
|
||||
&referrerStr,
|
||||
@@ -967,15 +1112,16 @@ bool JSCommonJSModule::evaluate(
|
||||
ResolvedSource source,
|
||||
bool isBuiltIn)
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
auto sourceProvider = Zig::SourceProvider::create(jsCast<Zig::GlobalObject*>(globalObject), source, JSC::SourceProviderSourceType::Program, isBuiltIn);
|
||||
this->ignoreESModuleAnnotation = source.tag == ResolvedSourceTagPackageJSONTypeModule;
|
||||
JSC::SourceCode rawInputSource(
|
||||
WTFMove(sourceProvider));
|
||||
|
||||
if (this->hasEvaluated)
|
||||
if (this->hasEvaluated) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto& vm = globalObject->vm();
|
||||
this->sourceCode.set(vm, this, JSC::JSSourceCode::create(vm, WTFMove(rawInputSource)));
|
||||
|
||||
WTF::NakedPtr<JSC::Exception> exception;
|
||||
@@ -1003,10 +1149,10 @@ std::optional<JSC::SourceCode> createCommonJSModule(
|
||||
bool isBuiltIn)
|
||||
{
|
||||
JSCommonJSModule* moduleObject = nullptr;
|
||||
WTF::String sourceURL = source.source_url.toWTFString();
|
||||
|
||||
JSValue specifierValue = Bun::toJS(globalObject, source.specifier);
|
||||
JSValue entry = globalObject->requireMap()->get(globalObject, specifierValue);
|
||||
auto sourceURL = source.source_url.toWTFString();
|
||||
auto sourceURLValue = Bun::toJS(globalObject, source.source_url);
|
||||
auto specifierValue = Bun::toJS(globalObject, source.specifier);
|
||||
auto entry = globalObject->requireMap()->get(globalObject, specifierValue);
|
||||
|
||||
auto sourceProvider = Zig::SourceProvider::create(jsCast<Zig::GlobalObject*>(globalObject), source, JSC::SourceProviderSourceType::Program, isBuiltIn);
|
||||
bool ignoreESModuleAnnotation = source.tag == ResolvedSourceTagPackageJSONTypeModule;
|
||||
@@ -1018,24 +1164,25 @@ std::optional<JSC::SourceCode> createCommonJSModule(
|
||||
|
||||
if (!moduleObject) {
|
||||
auto& vm = globalObject->vm();
|
||||
auto* requireMapKey = jsStringWithCache(vm, sourceURL);
|
||||
auto index = sourceURL.reverseFind('/', sourceURL.length());
|
||||
JSString* dirname = jsEmptyString(vm);
|
||||
JSString* filename = requireMapKey;
|
||||
if (index != WTF::notFound) {
|
||||
dirname = JSC::jsSubstring(globalObject, requireMapKey, 0, index);
|
||||
}
|
||||
|
||||
auto* id = JSC::jsStringWithCache(vm, sourceURL);
|
||||
WTF::Vector<JSC::EncodedJSValue, 1> dirnameArgs;
|
||||
dirnameArgs.reserveInitialCapacity(1);
|
||||
dirnameArgs.unsafeAppendWithoutCapacityCheck(JSValue::encode(specifierValue));
|
||||
#if OS(WINDOWS)
|
||||
auto dirname = JSValue::decode(Bun__Path__dirname(globalObject, true, reinterpret_cast<JSC__JSValue*>(dirnameArgs.data()), 1)).toString(globalObject);
|
||||
#else
|
||||
auto dirname = JSValue::decode(Bun__Path__dirname(globalObject, false, reinterpret_cast<JSC__JSValue*>(dirnameArgs.data()), 1)).toString(globalObject);
|
||||
#endif
|
||||
moduleObject = JSCommonJSModule::create(
|
||||
vm,
|
||||
globalObject->CommonJSModuleObjectStructure(),
|
||||
requireMapKey, filename, dirname, JSC::JSSourceCode::create(vm, SourceCode(WTFMove(sourceProvider))));
|
||||
id, id, dirname, JSC::JSSourceCode::create(vm, SourceCode(WTFMove(sourceProvider))));
|
||||
|
||||
moduleObject->putDirect(vm,
|
||||
WebCore::clientData(vm)->builtinNames().exportsPublicName(),
|
||||
JSC::constructEmptyObject(globalObject, globalObject->objectPrototype()), 0);
|
||||
|
||||
globalObject->requireMap()->set(globalObject, requireMapKey, moduleObject);
|
||||
globalObject->requireMap()->set(globalObject, id, moduleObject);
|
||||
}
|
||||
|
||||
moduleObject->ignoreESModuleAnnotation = ignoreESModuleAnnotation;
|
||||
@@ -1067,8 +1214,8 @@ std::optional<JSC::SourceCode> createCommonJSModule(
|
||||
// so that it can be re-evaluated on the next require.
|
||||
globalObject->requireMap()->remove(globalObject, moduleObject->id());
|
||||
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
throwException(globalObject, scope, exception.get());
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
throwException(globalObject, throwScope, exception.get());
|
||||
exception.clear();
|
||||
return;
|
||||
}
|
||||
@@ -1082,19 +1229,19 @@ std::optional<JSC::SourceCode> createCommonJSModule(
|
||||
sourceURL));
|
||||
}
|
||||
|
||||
JSObject* JSCommonJSModule::createBoundRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString)
|
||||
JSObject* JSCommonJSModule::createBoundRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, JSC::JSString* filename)
|
||||
{
|
||||
ASSERT(!pathString.startsWith("file://"_s));
|
||||
ASSERT(!filename->tryGetValue().startsWith("file://"_s));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
WTF::Vector<JSC::EncodedJSValue, 1> dirnameArgs;
|
||||
dirnameArgs.reserveInitialCapacity(1);
|
||||
dirnameArgs.unsafeAppendWithoutCapacityCheck(JSValue::encode(filename));
|
||||
#if OS(WINDOWS)
|
||||
auto dirname = JSValue::decode(Bun__Path__dirname(globalObject, true, reinterpret_cast<JSC__JSValue*>(dirnameArgs.data()), 1)).toString(globalObject);
|
||||
#else
|
||||
auto dirname = JSValue::decode(Bun__Path__dirname(globalObject, false, reinterpret_cast<JSC__JSValue*>(dirnameArgs.data()), 1)).toString(globalObject);
|
||||
#endif
|
||||
auto moduleObject = Bun::JSCommonJSModule::create(
|
||||
vm,
|
||||
globalObject->CommonJSModuleObjectStructure(),
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include "root.h"
|
||||
#include "headers-handwritten.h"
|
||||
|
||||
extern "C" JSC_DECLARE_HOST_FUNCTION(jsFunctionResolveSyncPrivate);
|
||||
|
||||
namespace Zig {
|
||||
class GlobalObject;
|
||||
}
|
||||
@@ -15,7 +17,7 @@ class AbstractModuleRecord;
|
||||
namespace Bun {
|
||||
|
||||
JSC_DECLARE_HOST_FUNCTION(jsFunctionCreateCommonJSModule);
|
||||
JSC_DECLARE_HOST_FUNCTION(jsFunctionLoadModule);
|
||||
JSC_DECLARE_HOST_FUNCTION(jsFunctionEvaluateCommonJSModule);
|
||||
|
||||
void populateESMExports(
|
||||
JSC::JSGlobalObject* globalObject,
|
||||
@@ -61,15 +63,15 @@ public:
|
||||
|
||||
static JSCommonJSModule* create(
|
||||
Zig::GlobalObject* globalObject,
|
||||
const WTF::String& key,
|
||||
JSC::JSString* id,
|
||||
JSValue exportsObject, bool hasEvaluated, JSValue parent);
|
||||
|
||||
static JSCommonJSModule* create(
|
||||
Zig::GlobalObject* globalObject,
|
||||
const WTF::String& key,
|
||||
JSC::JSString* id,
|
||||
ResolvedSource resolvedSource);
|
||||
|
||||
static JSObject* createBoundRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString);
|
||||
static JSObject* createBoundRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, JSC::JSString* filename);
|
||||
|
||||
void toSyntheticSource(JSC::JSGlobalObject* globalObject,
|
||||
JSC::Identifier moduleKey,
|
||||
@@ -82,7 +84,6 @@ public:
|
||||
DECLARE_INFO;
|
||||
DECLARE_VISIT_CHILDREN;
|
||||
|
||||
|
||||
static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
|
||||
|
||||
template<typename, SubspaceAccess mode>
|
||||
@@ -106,12 +107,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
JSCommonJSModule* createCommonJSModuleWithoutRunning(
|
||||
Zig::GlobalObject* globalObject,
|
||||
Ref<Zig::SourceProvider> sourceProvider,
|
||||
const WTF::String& sourceURL,
|
||||
ResolvedSource source);
|
||||
|
||||
JSC::Structure* createCommonJSModuleStructure(
|
||||
Zig::GlobalObject* globalObject);
|
||||
|
||||
|
||||
@@ -87,84 +87,12 @@ ALWAYS_INLINE bool isAbsolutePath(WTF::String input)
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" JSC__JSValue Bun__Path__dirname(JSC__JSGlobalObject* arg0, bool arg1, JSC__JSValue* arg2, uint16_t arg3);
|
||||
|
||||
namespace Zig {
|
||||
using namespace JSC;
|
||||
using namespace WebCore;
|
||||
|
||||
static JSC::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: {
|
||||
// not "requires" because "require" could be confusing
|
||||
JSC::throwTypeError(globalObject, scope, "require.resolve needs 1 argument (a string)"_s);
|
||||
scope.release();
|
||||
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 {
|
||||
Zig::GlobalObject* zigGlobalObject = jsCast<Zig::GlobalObject*>(globalObject);
|
||||
if (zigGlobalObject->onLoadPlugins.hasVirtualModules()) {
|
||||
if (auto result = zigGlobalObject->onLoadPlugins.resolveVirtualModule(fromStr, String())) {
|
||||
if (fromStr == result.value())
|
||||
return JSC::JSValue::encode(moduleName);
|
||||
|
||||
return JSC::JSValue::encode(jsString(vm, result.value()));
|
||||
}
|
||||
}
|
||||
|
||||
BunString from = Bun::toString(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()) {
|
||||
JSC::throwTypeError(globalObject, scope, "require.resolve expects a string"_s);
|
||||
scope.release();
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
|
||||
if (callFrame->argumentCount() > 1) {
|
||||
JSC::JSValue fromValue = callFrame->argument(1);
|
||||
|
||||
// require.resolve also supports a paths array
|
||||
// we only support a single path
|
||||
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 (fromValue.isString()) {
|
||||
WTF::String str = fromValue.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
return doIt(str);
|
||||
}
|
||||
}
|
||||
|
||||
return doIt(fromStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Zig::ImportMetaObject* Zig::ImportMetaObject::create(JSC::JSGlobalObject* globalObject, JSValue key)
|
||||
{
|
||||
if (WebCore::DOMURL* domURL = WebCoreCast<WebCore::JSDOMURL, WebCore__DOMURL>(JSValue::encode(key))) {
|
||||
@@ -183,33 +111,20 @@ Zig::ImportMetaObject* Zig::ImportMetaObject::create(JSC::JSGlobalObject* global
|
||||
return create(globalObject, keyString);
|
||||
}
|
||||
|
||||
JSC_DECLARE_HOST_FUNCTION(jsFunctionRequireResolve);
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireResolve, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
JSValue thisValue = callFrame->thisValue();
|
||||
WTF::String fromStr;
|
||||
|
||||
if (thisValue.isString()) {
|
||||
fromStr = thisValue.toWTFString(globalObject);
|
||||
}
|
||||
|
||||
return functionRequireResolve(globalObject, callFrame, fromStr);
|
||||
}
|
||||
|
||||
extern "C" JSC::EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionImportMeta_resolveSync, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
auto* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
|
||||
JSValue thisValue = callFrame->thisValue();
|
||||
JSC::JSValue moduleName = callFrame->argument(0);
|
||||
JSC::JSValue fromValue = callFrame->argument(1);
|
||||
JSValue moduleName = callFrame->argument(0);
|
||||
JSValue fromValue = callFrame->argument(1);
|
||||
|
||||
if (moduleName.isUndefinedOrNull()) {
|
||||
JSC::throwTypeError(globalObject, scope, "expects a string"_s);
|
||||
scope.release();
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
JSC::throwTypeError(globalObject, throwScope, "expects a string"_s);
|
||||
throwScope.release();
|
||||
return JSValue::encode(JSValue {});
|
||||
}
|
||||
|
||||
JSC__JSValue from;
|
||||
@@ -218,52 +133,53 @@ extern "C" JSC::EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObje
|
||||
if (callFrame->argumentCount() > 1) {
|
||||
|
||||
if (callFrame->argumentCount() > 2) {
|
||||
JSC::JSValue isESMValue = callFrame->argument(2);
|
||||
JSValue isESMValue = callFrame->argument(2);
|
||||
if (isESMValue.isBoolean()) {
|
||||
isESM = isESMValue.toBoolean(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
RETURN_IF_EXCEPTION(throwScope, JSValue::encode(JSValue {}));
|
||||
}
|
||||
}
|
||||
|
||||
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 {}));
|
||||
RETURN_IF_EXCEPTION(throwScope, JSValue::encode(JSValue {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (fromValue.isBoolean()) {
|
||||
isESM = fromValue.toBoolean(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
RETURN_IF_EXCEPTION(throwScope, JSValue::encode(JSValue {}));
|
||||
fromValue = JSC::jsUndefined();
|
||||
}
|
||||
|
||||
if (fromValue.isString()) {
|
||||
from = JSC::JSValue::encode(fromValue);
|
||||
from = JSValue::encode(fromValue);
|
||||
} else if (thisValue.isString()) {
|
||||
from = JSC::JSValue::encode(thisValue);
|
||||
from = JSValue::encode(thisValue);
|
||||
}
|
||||
|
||||
} else if (thisValue.isString()) {
|
||||
from = JSC::JSValue::encode(thisValue);
|
||||
from = 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 throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
JSC::throwTypeError(globalObject, throwScope, "import.meta.resolveSync must be bound to an import.meta object"_s);
|
||||
return JSValue::encode(JSValue {});
|
||||
}
|
||||
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
JSValue pathProperty = thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().pathPublicName());
|
||||
auto builtinNames = clientData->builtinNames();
|
||||
|
||||
JSValue pathProperty = thisObject->getIfPropertyExists(globalObject, builtinNames.pathPublicName());
|
||||
|
||||
if (pathProperty && pathProperty.isString())
|
||||
from = JSC::JSValue::encode(pathProperty);
|
||||
from = JSValue::encode(pathProperty);
|
||||
}
|
||||
|
||||
if (globalObject->onLoadPlugins.hasVirtualModules()) {
|
||||
@@ -271,131 +187,64 @@ extern "C" JSC::EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObje
|
||||
auto moduleString = moduleName.toWTFString(globalObject);
|
||||
if (auto resolvedString = globalObject->onLoadPlugins.resolveVirtualModule(moduleString, JSValue::decode(from).toWTFString(globalObject))) {
|
||||
if (moduleString == resolvedString.value())
|
||||
return JSC::JSValue::encode(moduleName);
|
||||
return JSC::JSValue::encode(jsString(vm, resolvedString.value()));
|
||||
return JSValue::encode(moduleName);
|
||||
return JSValue::encode(jsString(vm, resolvedString.value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from, isESM);
|
||||
auto result = Bun__resolveSync(globalObject, 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 {});
|
||||
if (!JSValue::decode(result).isString()) {
|
||||
JSC::throwException(globalObject, throwScope, JSValue::decode(result));
|
||||
return JSValue::encode(JSValue {});
|
||||
}
|
||||
|
||||
scope.release();
|
||||
throwScope.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" bool Bun__isBunMain(JSC::JSGlobalObject* global, const BunString*);
|
||||
|
||||
extern "C" JSC::EncodedJSValue functionImportMeta__resolveSyncPrivate(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
|
||||
{
|
||||
JSC::VM& vm = lexicalGlobalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
auto* globalObject = jsDynamicCast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
|
||||
JSC::JSValue moduleName = callFrame->argument(0);
|
||||
JSValue from = callFrame->argument(1);
|
||||
bool isESM = callFrame->argument(2).asBoolean();
|
||||
|
||||
if (moduleName.isUndefinedOrNull()) {
|
||||
JSC::throwTypeError(lexicalGlobalObject, scope, "expected module name as a string"_s);
|
||||
scope.release();
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
|
||||
if (globalObject->onLoadPlugins.hasVirtualModules()) {
|
||||
if (moduleName.isString()) {
|
||||
auto moduleString = moduleName.toWTFString(globalObject);
|
||||
if (auto resolvedString = globalObject->onLoadPlugins.resolveVirtualModule(moduleString, from.toWTFString(globalObject))) {
|
||||
if (moduleString == resolvedString.value())
|
||||
return JSC::JSValue::encode(moduleName);
|
||||
return JSC::JSValue::encode(jsString(vm, resolvedString.value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isESM) {
|
||||
if (LIKELY(globalObject)) {
|
||||
auto overrideHandler = globalObject->m_nodeModuleOverriddenResolveFilename.get();
|
||||
if (UNLIKELY(overrideHandler)) {
|
||||
ASSERT(overrideHandler->isCallable());
|
||||
JSValue parentModuleObject = globalObject->requireMap()->get(globalObject, from);
|
||||
|
||||
JSValue parentID = jsUndefined();
|
||||
if (auto* parent = jsDynamicCast<Bun::JSCommonJSModule*>(parentModuleObject)) {
|
||||
parentID = parent->id();
|
||||
} else {
|
||||
parentID = from;
|
||||
}
|
||||
|
||||
MarkedArgumentBuffer args;
|
||||
args.append(moduleName);
|
||||
args.append(parentModuleObject);
|
||||
auto parentIdStr = parentID.toWTFString(globalObject);
|
||||
auto bunStr = Bun::toString(parentIdStr);
|
||||
args.append(jsBoolean(Bun__isBunMain(lexicalGlobalObject, &bunStr)));
|
||||
|
||||
return JSValue::encode(JSC::call(lexicalGlobalObject, overrideHandler, JSC::getCallData(overrideHandler), parentModuleObject, args));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto result = Bun__resolveSync(lexicalGlobalObject, JSC::JSValue::encode(moduleName), JSValue::encode(from), isESM);
|
||||
|
||||
if (!JSC::JSValue::decode(result).isString()) {
|
||||
JSC::throwException(lexicalGlobalObject, scope, JSC::JSValue::decode(result));
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
|
||||
scope.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve,
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionImportMeta_resolve,
|
||||
(JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
auto* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
|
||||
switch (callFrame->argumentCount()) {
|
||||
case 0: {
|
||||
// not "requires" because "require" could be confusing
|
||||
JSC::throwTypeError(globalObject, scope, "import.meta.resolve needs 1 argument (a string)"_s);
|
||||
scope.release();
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
JSC::throwTypeError(globalObject, throwScope, "import.meta.resolve needs 1 argument (a string)"_s);
|
||||
throwScope.release();
|
||||
return JSValue::encode(JSValue {});
|
||||
}
|
||||
default: {
|
||||
JSC::JSValue moduleName = callFrame->argument(0);
|
||||
JSValue moduleName = callFrame->argument(0);
|
||||
|
||||
if (moduleName.isUndefinedOrNull()) {
|
||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
JSC::throwTypeError(globalObject, scope, "import.meta.resolve expects a string"_s);
|
||||
scope.release();
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
JSC::throwTypeError(globalObject, throwScope, "import.meta.resolve expects a string"_s);
|
||||
throwScope.release();
|
||||
return JSValue::encode(JSValue {});
|
||||
}
|
||||
|
||||
JSC__JSValue from;
|
||||
|
||||
if (callFrame->argumentCount() > 1 && callFrame->argument(1).isString()) {
|
||||
from = JSC::JSValue::encode(callFrame->argument(1));
|
||||
from = JSValue::encode(callFrame->argument(1));
|
||||
} 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.resolve must be bound to an import.meta object"_s);
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
JSC::throwTypeError(globalObject, throwScope, "import.meta.resolve must be bound to an import.meta object"_s);
|
||||
return JSValue::encode(JSValue {});
|
||||
}
|
||||
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
auto builtinNames = clientData->builtinNames();
|
||||
|
||||
from = JSC::JSValue::encode(thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().pathPublicName()));
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
from = JSValue::encode(thisObject->getIfPropertyExists(globalObject, builtinNames.pathPublicName()));
|
||||
RETURN_IF_EXCEPTION(throwScope, JSValue::encode(JSValue {}));
|
||||
}
|
||||
|
||||
if (globalObject->onLoadPlugins.hasVirtualModules()) {
|
||||
@@ -403,13 +252,13 @@ JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve,
|
||||
auto moduleString = moduleName.toWTFString(globalObject);
|
||||
if (auto resolvedString = globalObject->onLoadPlugins.resolveVirtualModule(moduleString, JSValue::decode(from).toWTFString(globalObject))) {
|
||||
if (moduleString == resolvedString.value())
|
||||
return JSC::JSValue::encode(JSPromise::resolvedPromise(globalObject, moduleName));
|
||||
return JSC::JSValue::encode(JSPromise::resolvedPromise(globalObject, jsString(vm, resolvedString.value())));
|
||||
return JSValue::encode(JSPromise::resolvedPromise(globalObject, moduleName));
|
||||
return JSValue::encode(JSPromise::resolvedPromise(globalObject, jsString(vm, resolvedString.value())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Bun__resolve(globalObject, JSC::JSValue::encode(moduleName), from, true);
|
||||
return Bun__resolve(globalObject, JSValue::encode(moduleName), from, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,6 +278,7 @@ Zig::ImportMetaObject* ImportMetaObject::create(JSC::VM& vm, JSC::JSGlobalObject
|
||||
ptr->finishCreation(vm);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Zig::ImportMetaObject* ImportMetaObject::create(JSC::JSGlobalObject* jslobalObject, JSC::JSString* keyString)
|
||||
{
|
||||
auto* globalObject = jsCast<Zig::GlobalObject*>(jslobalObject);
|
||||
@@ -446,6 +296,7 @@ JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_url, (JSGlobalObject * globalO
|
||||
|
||||
return JSValue::encode(thisObject->urlProperty.getInitializedOnMainThread(thisObject));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_dir, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName propertyName))
|
||||
{
|
||||
ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
|
||||
@@ -454,6 +305,7 @@ JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_dir, (JSGlobalObject * globalO
|
||||
|
||||
return JSValue::encode(thisObject->dirProperty.getInitializedOnMainThread(thisObject));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_file, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName propertyName))
|
||||
{
|
||||
ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
|
||||
@@ -462,6 +314,7 @@ JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_file, (JSGlobalObject * global
|
||||
|
||||
return JSValue::encode(thisObject->fileProperty.getInitializedOnMainThread(thisObject));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_path, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName propertyName))
|
||||
{
|
||||
ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
|
||||
@@ -470,6 +323,7 @@ JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_path, (JSGlobalObject * global
|
||||
|
||||
return JSValue::encode(thisObject->pathProperty.getInitializedOnMainThread(thisObject));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_require, (JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, PropertyName propertyName))
|
||||
{
|
||||
ImportMetaObject* thisObject = jsDynamicCast<ImportMetaObject*>(JSValue::decode(thisValue));
|
||||
@@ -478,6 +332,7 @@ JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_require, (JSGlobalObject * glo
|
||||
|
||||
return JSValue::encode(thisObject->requireProperty.getInitializedOnMainThread(thisObject));
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_env, (JSGlobalObject * jsGlobalObject, JSC::EncodedJSValue thisValue, PropertyName propertyName))
|
||||
{
|
||||
auto* globalObject = jsCast<Zig::GlobalObject*>(jsGlobalObject);
|
||||
@@ -485,15 +340,15 @@ JSC_DEFINE_CUSTOM_GETTER(jsImportMetaObjectGetter_env, (JSGlobalObject * jsGloba
|
||||
}
|
||||
|
||||
static const HashTableValue ImportMetaObjectPrototypeValues[] = {
|
||||
{ "env"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_env, 0 } },
|
||||
{ "dir"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_dir, 0 } },
|
||||
{ "dirname"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_dir, 0 } },
|
||||
{ "env"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_env, 0 } },
|
||||
{ "file"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_file, 0 } },
|
||||
{ "filename"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_path, 0 } },
|
||||
{ "path"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_path, 0 } },
|
||||
{ "require"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_require, 0 } },
|
||||
{ "resolve"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, functionImportMeta__resolve, 0 } },
|
||||
{ "resolveSync"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, functionImportMeta__resolveSync, 0 } },
|
||||
{ "resolve"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsFunctionImportMeta_resolve, 0 } },
|
||||
{ "resolveSync"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsFunctionImportMeta_resolveSync, 0 } },
|
||||
{ "url"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, jsImportMetaObjectGetter_url, 0 } },
|
||||
};
|
||||
|
||||
@@ -525,8 +380,8 @@ public:
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
|
||||
auto* clientData = WebCore::clientData(vm);
|
||||
auto& builtinNames = clientData->builtinNames();
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
auto builtinNames = clientData->builtinNames();
|
||||
|
||||
reifyStaticProperties(vm, ImportMetaObject::info(), ImportMetaObjectPrototypeValues, *this);
|
||||
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
|
||||
@@ -558,9 +413,6 @@ JSC::Structure* ImportMetaObject::createStructure(JSC::VM& vm, JSC::JSGlobalObje
|
||||
globalObject,
|
||||
ImportMetaObjectPrototype::createStructure(vm, globalObject));
|
||||
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
auto& builtinNames = clientData->builtinNames();
|
||||
|
||||
return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), ImportMetaObject::info());
|
||||
}
|
||||
|
||||
@@ -570,52 +422,57 @@ void ImportMetaObject::finishCreation(VM& vm)
|
||||
ASSERT(inherits(info()));
|
||||
|
||||
this->requireProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSFunction>::Initializer& init) {
|
||||
ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
|
||||
|
||||
WTF::URL url = isAbsolutePath(meta->url) ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
|
||||
WTF::String path;
|
||||
auto* meta = jsCast<ImportMetaObject*>(init.owner);
|
||||
auto globalObject = meta->globalObject();
|
||||
auto& vm = init.vm;
|
||||
auto url = isAbsolutePath(meta->url) ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
|
||||
|
||||
WTF::String filenameWTF;
|
||||
if (url.isValid()) {
|
||||
|
||||
if (url.protocolIsFile()) {
|
||||
path = url.fileSystemPath();
|
||||
filenameWTF = url.fileSystemPath();
|
||||
} else {
|
||||
path = url.path().toString();
|
||||
filenameWTF = url.path().toString();
|
||||
}
|
||||
} else {
|
||||
path = meta->url;
|
||||
filenameWTF = meta->url;
|
||||
}
|
||||
|
||||
JSFunction* value = jsCast<JSFunction*>(Bun::JSCommonJSModule::createBoundRequireFunction(init.vm, meta->globalObject(), path));
|
||||
auto* filename = JSC::jsStringWithCache(vm, filenameWTF);
|
||||
JSFunction* value = jsCast<JSFunction*>(Bun::JSCommonJSModule::createBoundRequireFunction(vm, globalObject, filename));
|
||||
init.set(value);
|
||||
});
|
||||
this->urlProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSString>::Initializer& init) {
|
||||
ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
|
||||
WTF::URL url = isAbsolutePath(meta->url) ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
|
||||
auto* meta = jsCast<ImportMetaObject*>(init.owner);
|
||||
auto url = isAbsolutePath(meta->url) ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
|
||||
|
||||
init.set(jsString(init.vm, url.string()));
|
||||
});
|
||||
this->dirProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSString>::Initializer& init) {
|
||||
ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
|
||||
|
||||
WTF::URL url = isAbsolutePath(meta->url) ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
|
||||
WTF::String dirname;
|
||||
auto* meta = jsCast<ImportMetaObject*>(init.owner);
|
||||
auto globalObject = meta->globalObject();
|
||||
auto& vm = init.vm;
|
||||
auto url = isAbsolutePath(meta->url) ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
|
||||
|
||||
WTF::String filenameWTF;
|
||||
if (url.isValid()) {
|
||||
if (url.protocolIsFile()) {
|
||||
dirname = url.fileSystemPath();
|
||||
filenameWTF = url.fileSystemPath();
|
||||
} else {
|
||||
dirname = url.path().toString();
|
||||
filenameWTF = url.path().toString();
|
||||
}
|
||||
} else {
|
||||
filenameWTF = meta->url;
|
||||
}
|
||||
|
||||
if (dirname.endsWith(PLATFORM_SEP_s)) {
|
||||
dirname = dirname.substring(0, dirname.length() - 1);
|
||||
} else if (dirname.contains(PLATFORM_SEP)) {
|
||||
dirname = dirname.substring(0, dirname.reverseFind(PLATFORM_SEP));
|
||||
}
|
||||
|
||||
init.set(jsString(init.vm, dirname));
|
||||
auto filename = JSC::jsStringWithCache(vm, filenameWTF);
|
||||
WTF::Vector<JSC::EncodedJSValue, 1> dirnameArgs;
|
||||
dirnameArgs.reserveInitialCapacity(1);
|
||||
dirnameArgs.unsafeAppendWithoutCapacityCheck(JSValue::encode(filename));
|
||||
#if OS(WINDOWS)
|
||||
auto dirname = JSValue::decode(Bun__Path__dirname(globalObject, true, reinterpret_cast<JSC__JSValue*>(dirnameArgs.data()), 1)).toString(globalObject);
|
||||
#else
|
||||
auto dirname = JSValue::decode(Bun__Path__dirname(globalObject, false, reinterpret_cast<JSC__JSValue*>(dirnameArgs.data()), 1)).toString(globalObject);
|
||||
#endif
|
||||
init.set(dirname);
|
||||
});
|
||||
this->fileProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSString>::Initializer& init) {
|
||||
ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
|
||||
|
||||
@@ -8,11 +8,8 @@
|
||||
|
||||
#include "JSDOMWrapperCache.h"
|
||||
|
||||
extern "C" JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolveSync);
|
||||
extern "C" JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolveSyncPrivate);
|
||||
extern "C" JSC::EncodedJSValue Bun__resolve(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, JSC::EncodedJSValue from, bool is_esm);
|
||||
extern "C" JSC::EncodedJSValue Bun__resolveSync(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, JSC::EncodedJSValue from, bool is_esm);
|
||||
extern "C" JSC::EncodedJSValue Bun__resolveSyncWithSource(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, BunString* from, bool is_esm);
|
||||
|
||||
namespace Zig {
|
||||
|
||||
@@ -24,9 +21,6 @@ public:
|
||||
using Base = JSC::JSNonFinalObject;
|
||||
|
||||
static ImportMetaObject* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, const WTF::String& url);
|
||||
|
||||
static JSObject* createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString);
|
||||
|
||||
static ImportMetaObject* create(JSC::JSGlobalObject* globalObject, JSC::JSString* keyString);
|
||||
static ImportMetaObject* create(JSC::JSGlobalObject* globalObject, JSValue keyString);
|
||||
|
||||
|
||||
@@ -3663,21 +3663,19 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
|
||||
// TODO: most/all of these private properties can be made as static globals.
|
||||
// i've noticed doing it as is will work somewhat but getDirect() wont be able to find them
|
||||
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.createFIFOPrivateName(), streamInternalsCreateFIFOCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.createEmptyReadableStreamPrivateName(), readableStreamCreateEmptyReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.createUsedReadableStreamPrivateName(), readableStreamCreateUsedReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.consumeReadableStreamPrivateName(), readableStreamConsumeReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
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.loadCJS2ESMPrivateName(), importMetaObjectLoadCJS2ESMCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.internalRequirePrivateName(), importMetaObjectInternalRequireCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.requireNativeModulePrivateName(), moduleRequireNativeModuleCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.overridableRequirePrivateName(), moduleOverridableRequireCodeGenerator(vm), 0);
|
||||
|
||||
putDirectNativeFunction(vm, this, builtinNames.createUninitializedArrayBufferPrivateName(), 1, functionCreateUninitializedArrayBuffer, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectNativeFunction(vm, this, builtinNames.resolveSyncPrivateName(), 1, functionImportMeta__resolveSyncPrivate, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.createEmptyReadableStreamPrivateName(), readableStreamCreateEmptyReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.createFIFOPrivateName(), streamInternalsCreateFIFOCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectNativeFunction(vm, this, builtinNames.createInternalModuleByIdPrivateName(), 1, InternalModuleRegistry::jsCreateInternalModuleById, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.createNativeReadableStreamPrivateName(), readableStreamCreateNativeReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectNativeFunction(vm, this, builtinNames.createUninitializedArrayBufferPrivateName(), 1, functionCreateUninitializedArrayBuffer, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.createUsedReadableStreamPrivateName(), readableStreamCreateUsedReadableStreamCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.internalRequirePrivateName(), importMetaObjectInternalRequireCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.loadCJS2ESMPrivateName(), importMetaObjectLoadCJS2ESMCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.overridableRequirePrivateName(), moduleOverridableRequireCodeGenerator(vm), 0);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.requireESMPrivateName(), importMetaObjectRequireESMCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectBuiltinFunction(vm, this, builtinNames.requireNativeModulePrivateName(), moduleRequireNativeModuleCodeGenerator(vm), PropertyAttribute::Builtin | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
putDirectNativeFunction(vm, this, builtinNames.resolveSyncPrivateName(), 1, jsFunctionResolveSyncPrivate, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
|
||||
|
||||
putDirectNativeFunction(vm, this,
|
||||
builtinNames.createCommonJSModulePrivateName(),
|
||||
@@ -3689,7 +3687,7 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
|
||||
putDirectNativeFunction(vm, this,
|
||||
builtinNames.evaluateCommonJSModulePrivateName(),
|
||||
2,
|
||||
Bun::jsFunctionLoadModule,
|
||||
Bun::jsFunctionEvaluateCommonJSModule,
|
||||
ImplementationVisibility::Public,
|
||||
NoIntrinsic,
|
||||
PropertyAttribute::ReadOnly | PropertyAttribute::DontDelete | 0);
|
||||
@@ -3793,13 +3791,13 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
|
||||
thisObject->m_builtinInternalFunctions.visit(visitor);
|
||||
thisObject->m_commonStrings.visit<Visitor>(visitor);
|
||||
visitor.append(thisObject->m_assignToStream);
|
||||
visitor.append(thisObject->m_nodeModuleOverriddenResolveFilename);
|
||||
visitor.append(thisObject->m_readableStreamToArrayBuffer);
|
||||
visitor.append(thisObject->m_readableStreamToArrayBufferResolve);
|
||||
visitor.append(thisObject->m_readableStreamToBlob);
|
||||
visitor.append(thisObject->m_readableStreamToJSON);
|
||||
visitor.append(thisObject->m_readableStreamToText);
|
||||
visitor.append(thisObject->m_readableStreamToFormData);
|
||||
visitor.append(thisObject->m_nodeModuleOverriddenResolveFilename);
|
||||
|
||||
visitor.append(thisObject->m_nextTickQueue);
|
||||
visitor.append(thisObject->m_errorConstructorPrepareStackTraceValue);
|
||||
@@ -3841,7 +3839,6 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
|
||||
thisObject->m_emitReadableNextTickFunction.visit(visitor);
|
||||
thisObject->m_JSBufferSubclassStructure.visit(visitor);
|
||||
thisObject->m_JSCryptoKey.visit(visitor);
|
||||
|
||||
thisObject->m_cryptoObject.visit(visitor);
|
||||
thisObject->m_JSDOMFileConstructor.visit(visitor);
|
||||
|
||||
@@ -3857,6 +3854,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
|
||||
thisObject->m_lazyTestModuleObject.visit(visitor);
|
||||
thisObject->m_lazyPreloadTestModuleObject.visit(visitor);
|
||||
thisObject->m_testMatcherUtilsObject.visit(visitor);
|
||||
|
||||
thisObject->m_commonJSModuleObjectStructure.visit(visitor);
|
||||
thisObject->m_JSSQLStatementStructure.visit(visitor);
|
||||
thisObject->m_memoryFootprintStructure.visit(visitor);
|
||||
|
||||
@@ -268,7 +268,7 @@ public:
|
||||
bool hasProcessObject() const { return m_processObject.isInitialized(); }
|
||||
|
||||
RefPtr<WebCore::Performance> performance();
|
||||
|
||||
|
||||
JSC::JSObject* processObject() { return m_processObject.getInitializedOnMainThread(this); }
|
||||
JSC::JSObject* processEnvObject() { return m_processEnvObject.getInitializedOnMainThread(this); }
|
||||
JSC::JSObject* bunObject() { return m_bunObject.getInitializedOnMainThread(this); }
|
||||
@@ -362,8 +362,8 @@ public:
|
||||
mutable WriteBarrier<JSFunction> m_readableStreamToText;
|
||||
mutable WriteBarrier<JSFunction> m_readableStreamToFormData;
|
||||
|
||||
// This is set when doing `require('module')._resolveFilename = ...`
|
||||
// a hack used by Next.js to inject their versions of webpack and react
|
||||
// This is set when overriding `require('module')._resolveFilename = ...`
|
||||
// used by projects like Next.js to inject their versions of webpack and react.
|
||||
mutable WriteBarrier<JSFunction> m_nodeModuleOverriddenResolveFilename;
|
||||
|
||||
mutable WriteBarrier<Unknown> m_nextTickQueue;
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
using namespace Zig;
|
||||
using namespace JSC;
|
||||
|
||||
extern "C" JSC__JSValue Bun__Path__dirname(JSC__JSGlobalObject *arg0, bool arg1,
|
||||
JSC__JSValue *arg2, uint16_t arg3);
|
||||
|
||||
// This is a mix of bun's builtin module names and also the ones reported by
|
||||
// node v20.4.0
|
||||
static constexpr ASCIILiteral builtinModuleNames[] = {
|
||||
@@ -98,10 +101,9 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleModuleConstructor,
|
||||
// In node, this is supposed to be the actual CommonJSModule constructor.
|
||||
// We are cutting a huge corner by not doing all that work.
|
||||
// This code is only to support babel.
|
||||
JSC::VM &vm = globalObject->vm();
|
||||
JSString *idString = JSC::jsString(vm, WTF::String("."_s));
|
||||
|
||||
JSString *dirname = jsEmptyString(vm);
|
||||
auto &vm = globalObject->vm();
|
||||
auto *id = JSC::jsEmptyString(vm);
|
||||
auto *dirname = JSC::jsStringWithCache(vm, "."_s);
|
||||
|
||||
// TODO: handle when JSGlobalObject !== Zig::GlobalObject, such as in node:vm
|
||||
Structure *structure = static_cast<Zig::GlobalObject *>(globalObject)
|
||||
@@ -112,18 +114,29 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleModuleConstructor,
|
||||
JSValue parentValue = callFrame->argument(1);
|
||||
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
if (idValue.isString()) {
|
||||
idString = idValue.toString(globalObject);
|
||||
id = idValue.toString(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined()));
|
||||
|
||||
auto index = idString->tryGetValue().reverseFind('/', idString->length());
|
||||
|
||||
if (index != WTF::notFound) {
|
||||
dirname = JSC::jsSubstring(globalObject, idString, 0, index);
|
||||
}
|
||||
WTF::Vector<JSC::EncodedJSValue, 1> dirnameArgs;
|
||||
dirnameArgs.reserveInitialCapacity(1);
|
||||
dirnameArgs.unsafeAppendWithoutCapacityCheck(JSValue::encode(idValue));
|
||||
#if OS(WINDOWS)
|
||||
dirname = JSValue::decode(
|
||||
Bun__Path__dirname(
|
||||
globalObject, true,
|
||||
reinterpret_cast<JSC__JSValue *>(dirnameArgs.data()), 1))
|
||||
.toString(globalObject);
|
||||
#else
|
||||
dirname = JSValue::decode(
|
||||
Bun__Path__dirname(
|
||||
globalObject, false,
|
||||
reinterpret_cast<JSC__JSValue *>(dirnameArgs.data()), 1))
|
||||
.toString(globalObject);
|
||||
#endif
|
||||
}
|
||||
|
||||
auto *out = Bun::JSCommonJSModule::create(vm, structure, idString, jsNull(),
|
||||
auto *out = Bun::JSCommonJSModule::create(vm, structure, id, jsNull(),
|
||||
dirname, nullptr);
|
||||
|
||||
if (!parentValue.isUndefined())
|
||||
@@ -175,7 +188,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionWrap, (JSC::JSGlobalObject * globalObject,
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleCreateRequire,
|
||||
(JSC::JSGlobalObject * globalObject,
|
||||
JSC::CallFrame *callFrame)) {
|
||||
JSC::VM &vm = globalObject->vm();
|
||||
auto &vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
if (callFrame->argumentCount() < 1) {
|
||||
throwTypeError(globalObject, scope,
|
||||
@@ -183,10 +196,9 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleCreateRequire,
|
||||
RELEASE_AND_RETURN(scope, JSC::JSValue::encode({}));
|
||||
}
|
||||
|
||||
auto val = callFrame->uncheckedArgument(0).toWTFString(globalObject);
|
||||
|
||||
if (val.startsWith("file://"_s)) {
|
||||
WTF::URL url(val);
|
||||
auto filenameWTF = callFrame->uncheckedArgument(0).toWTFString(globalObject);
|
||||
if (filenameWTF.startsWith("file://"_s)) {
|
||||
WTF::URL url(filenameWTF);
|
||||
if (!url.isValid()) {
|
||||
throwTypeError(globalObject, scope,
|
||||
makeString("createRequire() was given an invalid URL '"_s,
|
||||
@@ -199,14 +211,16 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleCreateRequire,
|
||||
"createRequire() does not support non-file URLs"_s);
|
||||
RELEASE_AND_RETURN(scope, JSValue::encode({}));
|
||||
}
|
||||
val = url.fileSystemPath();
|
||||
filenameWTF = url.fileSystemPath();
|
||||
}
|
||||
auto *filename = JSC::jsStringWithCache(vm, filenameWTF);
|
||||
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined()));
|
||||
RELEASE_AND_RETURN(
|
||||
scope, JSValue::encode(Bun::JSCommonJSModule::createBoundRequireFunction(
|
||||
vm, globalObject, val)));
|
||||
vm, globalObject, filename)));
|
||||
}
|
||||
|
||||
extern "C" JSC::EncodedJSValue Resolver__nodeModulePathsForJS(JSGlobalObject *,
|
||||
CallFrame *);
|
||||
|
||||
@@ -332,16 +346,14 @@ JSC_DEFINE_CUSTOM_SETTER(set_resolveFilename,
|
||||
return false;
|
||||
}
|
||||
|
||||
// These two setters are only used if you directly hit
|
||||
// `Module.prototype.require` or `module.require`. When accessing the cjs
|
||||
// require argument, this is a bound version of `require`, which calls into the
|
||||
// overridden one.
|
||||
// These accessors are defined for `Module.prototype.require`.
|
||||
// The cjs `require` argument will also call into the overridden one.
|
||||
//
|
||||
// This require function also intentionally does not have .resolve on it, nor
|
||||
// does it have any of the other properties.
|
||||
//
|
||||
// Note: allowing require to be overridable at all is only needed for Next.js to
|
||||
// work (they do Module.prototype.require = ...)
|
||||
// Note: allowing require to be overridable is needed for projects like Next.js
|
||||
// to work (they do Module.prototype.require = ...)
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(getterRequireFunction,
|
||||
(JSC::JSGlobalObject * globalObject,
|
||||
|
||||
@@ -33,6 +33,7 @@ export const globalsToPrefix = [
|
||||
"ArrayBuffer",
|
||||
"Buffer",
|
||||
"Infinity",
|
||||
"isFinite",
|
||||
"Loader",
|
||||
"Promise",
|
||||
"ReadableByteStreamController",
|
||||
@@ -41,17 +42,15 @@ export const globalsToPrefix = [
|
||||
"ReadableStreamBYOBRequest",
|
||||
"ReadableStreamDefaultController",
|
||||
"ReadableStreamDefaultReader",
|
||||
"RegExp",
|
||||
"String",
|
||||
"TransformStream",
|
||||
"TransformStreamDefaultController",
|
||||
"Uint8Array",
|
||||
"String",
|
||||
"Buffer",
|
||||
"RegExp",
|
||||
"undefined",
|
||||
"WritableStream",
|
||||
"WritableStreamDefaultController",
|
||||
"WritableStreamDefaultWriter",
|
||||
"isFinite",
|
||||
"undefined",
|
||||
];
|
||||
|
||||
// These enums map to $<enum>IdToLabel and $<enum>LabelToId
|
||||
|
||||
7
src/js/builtins.d.ts
vendored
7
src/js/builtins.d.ts
vendored
@@ -407,6 +407,8 @@ declare function $streamErrored(): TODO;
|
||||
declare function $streamReadable(): TODO;
|
||||
declare function $streamWaiting(): TODO;
|
||||
declare function $streamWritable(): TODO;
|
||||
declare function $stringIndexOfInternal(searchString: string, position?: number): number;
|
||||
declare function $stringSubstring(indexStart: number, indexEnd?: number): string;
|
||||
declare function $structuredCloneForStream(): TODO;
|
||||
declare function $syscall(): TODO;
|
||||
declare function $textDecoderStreamDecoder(): TODO;
|
||||
@@ -538,3 +540,8 @@ declare var $Buffer: {
|
||||
declare interface Error {
|
||||
code?: string;
|
||||
}
|
||||
|
||||
declare var $Object: {
|
||||
$create(o: object | null): any;
|
||||
$create(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;
|
||||
};
|
||||
|
||||
@@ -150,6 +150,7 @@ using namespace JSC;
|
||||
macro(once) \
|
||||
macro(options) \
|
||||
macro(origin) \
|
||||
macro(originalStructureID) \
|
||||
macro(overridableRequire) \
|
||||
macro(ownerReadableStream) \
|
||||
macro(parse) \
|
||||
@@ -217,6 +218,7 @@ using namespace JSC;
|
||||
macro(strategySizeAlgorithm) \
|
||||
macro(stream) \
|
||||
macro(structuredCloneForStream) \
|
||||
macro(structureChanged) \
|
||||
macro(syscall) \
|
||||
macro(textDecoderStreamDecoder) \
|
||||
macro(textDecoderStreamTransform) \
|
||||
|
||||
@@ -11,8 +11,12 @@ export function require(this: CommonJSModuleRecord, id: string) {
|
||||
// overridableRequire can be overridden by setting `Module.prototype.require`
|
||||
$overriddenName = "require";
|
||||
$visibility = "Private";
|
||||
export function overridableRequire(this: CommonJSModuleRecord, id: string) {
|
||||
const existing = $requireMap.$get(id) || $requireMap.$get((id = $resolveSync(id, this.path, false)));
|
||||
export function overridableRequire(this: CommonJSModuleRecord, id: string, type?: { type: string }) {
|
||||
let existing = $requireMap.$get(id);
|
||||
if (existing === undefined) {
|
||||
id = $resolveSync(id, this.path, false);
|
||||
existing = $requireMap.$get(id);
|
||||
}
|
||||
if (existing) {
|
||||
// Scenario where this is necessary:
|
||||
//
|
||||
@@ -34,11 +38,9 @@ export function overridableRequire(this: CommonJSModuleRecord, id: string) {
|
||||
$evaluateCommonJSModule(existing);
|
||||
return existing.exports;
|
||||
}
|
||||
|
||||
if (id.endsWith(".node")) {
|
||||
return $internalRequire(id);
|
||||
}
|
||||
|
||||
// To handle import/export cycles, we need to create a module object and put
|
||||
// it into the map before we import it.
|
||||
const mod = $createCommonJSModule(id, {}, false, this);
|
||||
@@ -49,38 +51,38 @@ export function overridableRequire(this: CommonJSModuleRecord, id: string) {
|
||||
//
|
||||
// Note: we do not need to wrap this in a try/catch, if it throws the C++ code will
|
||||
// clear the module from the map.
|
||||
//
|
||||
var out = this.$require(
|
||||
id,
|
||||
mod,
|
||||
// did they pass a { type } object?
|
||||
$argumentCount(),
|
||||
// the object containing a "type" attribute, if they passed one
|
||||
// maybe this will be "paths" in the future too.
|
||||
arguments[1],
|
||||
);
|
||||
|
||||
// -1 means we need to lookup the module from the ESM registry.
|
||||
if (out === -1) {
|
||||
if (
|
||||
this.$require(
|
||||
id,
|
||||
mod,
|
||||
// Did they pass a { type } object?
|
||||
// Use `@argumentCount()` to avoid cloned arguments allocation.
|
||||
$argumentCount(),
|
||||
// The object containing a "type" attribute, if they passed one
|
||||
// maybe this will be "paths" in the future too.
|
||||
type,
|
||||
) === -1
|
||||
) {
|
||||
// -1 means we need to lookup the module from the ESM registry.
|
||||
try {
|
||||
out = $requireESM(id);
|
||||
$requireESM(id);
|
||||
} catch (exception) {
|
||||
// Since the ESM code is mostly JS, we need to handle exceptions here.
|
||||
$requireMap.$delete(id);
|
||||
throw exception;
|
||||
}
|
||||
|
||||
const esm = Loader.registry.$get(id);
|
||||
|
||||
// If we can pull out a ModuleNamespaceObject, let's do it.
|
||||
if (esm?.evaluated && (esm.state ?? 0) >= $ModuleReady) {
|
||||
if (esm && esm.evaluated && (esm.state ?? 0) >= $ModuleReady) {
|
||||
const namespace = Loader.getModuleNamespaceObject(esm!.module);
|
||||
return (mod.exports =
|
||||
// if they choose a module
|
||||
namespace.__esModule ? namespace : Object.create(namespace, { __esModule: { value: true } }));
|
||||
const exports = namespace.__esModule
|
||||
? // If they choose a module.
|
||||
namespace
|
||||
: $Object.$create(namespace, { __esModule: { value: true } });
|
||||
mod.exports = exports;
|
||||
return exports;
|
||||
}
|
||||
}
|
||||
|
||||
$evaluateCommonJSModule(mod);
|
||||
return mod.exports;
|
||||
}
|
||||
@@ -93,7 +95,7 @@ export function requireResolve(this: string | { path: string }, id: string) {
|
||||
$visibility = "Private";
|
||||
export function requireNativeModule(id: string) {
|
||||
let esm = Loader.registry.$get(id);
|
||||
if (esm?.evaluated && (esm.state ?? 0) >= $ModuleReady) {
|
||||
if (esm && esm.evaluated && (esm.state ?? 0) >= $ModuleReady) {
|
||||
const exports = Loader.getModuleNamespaceObject(esm.module);
|
||||
return exports.default;
|
||||
}
|
||||
|
||||
1
test/js/node/module/moduleExtensionsChange-fixture.cjs
generated
Normal file
1
test/js/node/module/moduleExtensionsChange-fixture.cjs
generated
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = "original";
|
||||
51
test/js/node/module/moduleExtensionsChange.cjs
Normal file
51
test/js/node/module/moduleExtensionsChange.cjs
Normal file
@@ -0,0 +1,51 @@
|
||||
const { expect, test } = require("bun:test");
|
||||
const Module = require("node:module");
|
||||
|
||||
test("Module._extensions change", () => {
|
||||
const oldCjs = Module._extensions[".cjs"];
|
||||
const oldJs = Module._extensions[".js"];
|
||||
debugger;
|
||||
// Test default behavior.
|
||||
const defaultResult = require("./moduleExtensionsChange-fixture.cjs");
|
||||
expect(defaultResult).toBe("original");
|
||||
|
||||
// Reset.
|
||||
delete Module._cache[require.resolve("./moduleExtensionsChange-fixture.cjs")];
|
||||
|
||||
// Test .cjs extension override.
|
||||
Module._extensions[".cjs"] = function (mod, filename) {
|
||||
mod._compile(`module.exports = "winner";`, filename);
|
||||
};
|
||||
const changedCjsResult = require("./moduleExtensionsChange-fixture.cjs");
|
||||
expect(changedCjsResult).toBe("winner");
|
||||
|
||||
// Reset.
|
||||
delete Module._cache[require.resolve("./moduleExtensionsChange-fixture.cjs")];
|
||||
if (oldCjs) {
|
||||
Module._extensions['.cjs'] = oldCjs;
|
||||
} else {
|
||||
delete Module._extensions['.cjs'];
|
||||
}
|
||||
|
||||
// Test reverted behavior.
|
||||
const revertedResult = require("./moduleExtensionsChange-fixture.cjs");
|
||||
expect(revertedResult).toBe("original");
|
||||
|
||||
// Reset.
|
||||
delete Module._cache[require.resolve("./moduleExtensionsChange-fixture.cjs")];
|
||||
|
||||
// Test fallback to .js.
|
||||
Module._extensions[".cjs"] = function (mod, filename) {
|
||||
mod._compile(`module.exports = "winner";`, filename);
|
||||
};
|
||||
const changedJsResult = require("./moduleExtensionsChange-fixture.cjs");
|
||||
expect(changedJsResult).toBe("winner");
|
||||
|
||||
// Reset.
|
||||
delete Module._cache[require.resolve("./moduleExtensionsChange-fixture.cjs")];
|
||||
if (oldJs) {
|
||||
Module._extensions['.js'] = oldJs;
|
||||
} else {
|
||||
delete Module._extensions['.js'];
|
||||
}
|
||||
});
|
||||
@@ -1,17 +1,19 @@
|
||||
const { expect, test } = require("bun:test");
|
||||
const Module = require("node:module");
|
||||
|
||||
// This behavior is required for Next.js to work
|
||||
const eql = require("assert").deepStrictEqual;
|
||||
const Module = require("module");
|
||||
|
||||
const old = Module.prototype.require;
|
||||
Module.prototype.require = function (str) {
|
||||
if (str === "hook") return "winner";
|
||||
return {
|
||||
wrap: old.call(this, str),
|
||||
test("Module.prototype.require overwrite", () => {
|
||||
const old = Module.prototype.require;
|
||||
Module.prototype.require = function (id) {
|
||||
if (id === "hook") {
|
||||
return "winner";
|
||||
}
|
||||
return {
|
||||
wrap: old.call(this, id),
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// this context has the new require
|
||||
const result = require("./modulePrototypeOverwrite-fixture.cjs");
|
||||
eql(result, { wrap: "winner" });
|
||||
|
||||
console.log("--pass--");
|
||||
// This context has the new require
|
||||
const result = require("./modulePrototypeOverwrite-fixture.cjs");
|
||||
Module.prototype.require = old;
|
||||
expect(result).toEqual({ wrap: "winner" });
|
||||
});
|
||||
@@ -1,9 +1,8 @@
|
||||
// @known-failing-on-windows: 1 failing
|
||||
import { expect, test } from "bun:test";
|
||||
import { bunEnv, bunExe } from "harness";
|
||||
import { _nodeModulePaths, builtinModules, isBuiltin, wrap } from "module";
|
||||
import Module from "module";
|
||||
import path from "path";
|
||||
import Module, { _nodeModulePaths, builtinModules, isBuiltin, wrap } from "node:module";
|
||||
import path from "node:path";
|
||||
|
||||
test("builtinModules exists", () => {
|
||||
expect(Array.isArray(builtinModules)).toBe(true);
|
||||
|
||||
@@ -1,15 +1,26 @@
|
||||
const { expect, test } = require("bun:test");
|
||||
const Module = require("node:module");
|
||||
const path = require("node:path");
|
||||
|
||||
// This behavior is required for Next.js to work
|
||||
const eql = require("assert").strictEqual;
|
||||
const path = require("path");
|
||||
const Module = require("module");
|
||||
|
||||
const original = Module._resolveFilename;
|
||||
Module._resolveFilename = (specifier, parent, isMain) => {
|
||||
eql(specifier.endsWith("💔"), true);
|
||||
eql(parent.filename, path.join(__dirname, "./resolveFilenameOverwrite.cjs"));
|
||||
return path.join(__dirname, "./resolveFilenameOverwrite-fixture.cjs");
|
||||
};
|
||||
eql(require("overwriting _resolveFilename broke 💔"), "winner");
|
||||
Module._resolveFilename = original;
|
||||
|
||||
console.log("--pass--");
|
||||
test("Module._resolveFilename overwrite", () => {
|
||||
let assertions = 0;
|
||||
const old = Module._resolveFilename;
|
||||
Module._resolveFilename = function (request, parent, isMain) {
|
||||
expect(request.endsWith("💔")).toBe(true);
|
||||
assertions++;
|
||||
expect(parent.filename).toBe(path.join(__dirname, "./resolveFilenameOverwrite.cjs"));
|
||||
assertions++;
|
||||
expect(isMain).toBe(true);
|
||||
assertions++;
|
||||
expect(this).toBe(Module);
|
||||
assertions++;
|
||||
return path.join(__dirname, "./resolveFilenameOverwrite-fixture.cjs");
|
||||
};
|
||||
const result = require("overwriting _resolveFilename broke 💔");
|
||||
Module._resolveFilename = old;
|
||||
expect(result).toBe("winner");
|
||||
assertions++;
|
||||
// TODO: Replace with `expect.assertions(3)` once implemented.
|
||||
expect(assertions).toBe(5);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user