diff options
Diffstat (limited to 'src/bun.js/bindings/CommonJSModuleRecord.cpp')
-rw-r--r-- | src/bun.js/bindings/CommonJSModuleRecord.cpp | 77 |
1 files changed, 59 insertions, 18 deletions
diff --git a/src/bun.js/bindings/CommonJSModuleRecord.cpp b/src/bun.js/bindings/CommonJSModuleRecord.cpp index e4fb1939c..eea3b2a6f 100644 --- a/src/bun.js/bindings/CommonJSModuleRecord.cpp +++ b/src/bun.js/bindings/CommonJSModuleRecord.cpp @@ -71,6 +71,8 @@ #include <JavaScriptCore/JSSourceCode.h> #include <JavaScriptCore/LazyPropertyInlines.h> +extern "C" bool Bun__isBunMain(JSC::JSGlobalObject* global, const char* input_ptr, uint64_t input_len); + namespace Bun { using namespace JSC; @@ -267,6 +269,31 @@ JSC_DEFINE_CUSTOM_GETTER(getterPath, (JSC::JSGlobalObject * globalObject, JSC::E return JSValue::encode(thisObject->m_id.get()); } +JSC_DEFINE_CUSTOM_GETTER(getterParent, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) +{ + JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue)); + if (UNLIKELY(!thisObject)) { + return JSValue::encode(jsUndefined()); + } + auto v = thisObject->m_parent.get(); + if (v) + return JSValue::encode(thisObject->m_parent.get()); + + // initialize parent by checking if it is the main module. we do this lazily because most people + // dont need `module.parent` and creating commonjs module records is done a ton. + auto idValue = thisObject->m_id.get(); + if (idValue) { + auto id = idValue->value(globalObject).utf8(); + if (Bun__isBunMain(globalObject, id.data(), id.length())) { + thisObject->m_parent.set(globalObject->vm(), thisObject, jsNull()); + return JSValue::encode(jsNull()); + } + } + + thisObject->m_parent.set(globalObject->vm(), thisObject, jsUndefined()); + return JSValue::encode(jsUndefined()); +} + JSC_DEFINE_CUSTOM_SETTER(setterPath, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::EncodedJSValue value, JSC::PropertyName propertyName)) @@ -331,16 +358,24 @@ JSC_DEFINE_CUSTOM_SETTER(setterId, 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; +} static JSValue createLoaded(VM& vm, JSObject* object) { JSCommonJSModule* cjs = jsCast<JSCommonJSModule*>(object); return jsBoolean(cjs->hasEvaluated); } -static JSValue createParent(VM& vm, JSObject* object) -{ - return jsUndefined(); -} static JSValue createChildren(VM& vm, JSObject* object) { return constructEmptyArray(object->globalObject(), nullptr, 0); @@ -404,14 +439,14 @@ JSC_DEFINE_HOST_FUNCTION(functionCommonJSModuleRecord_compile, (JSGlobalObject * } static const struct HashTableValue JSCommonJSModulePrototypeTableValues[] = { - { "children"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createChildren } }, + { "_compile"_s, static_cast<unsigned>(PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, functionCommonJSModuleRecord_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::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createLoaded } }, - { "parent"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createParent } }, + { "loaded"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, createLoaded } }, + { "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 } }, - { "_compile"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, functionCommonJSModuleRecord_compile, 2 } }, }; class JSCommonJSModulePrototype final : public JSC::JSNonFinalObject { @@ -499,23 +534,23 @@ JSCommonJSModule* JSCommonJSModule::create( JSC_DEFINE_HOST_FUNCTION(jsFunctionCreateCommonJSModule, (JSGlobalObject * globalObject, CallFrame* callframe)) { auto& vm = globalObject->vm(); + RELEASE_ASSERT(callframe->argumentCount() == 4); - auto id = callframe->argument(0).toWTFString(globalObject); + auto id = callframe->uncheckedArgument(0).toWTFString(globalObject); + JSValue object = callframe->uncheckedArgument(1); + JSValue hasEvaluated = callframe->uncheckedArgument(2); + ASSERT(hasEvaluated.isBoolean()); + JSValue parent = callframe->uncheckedArgument(3); - JSValue object = callframe->argument(1); - - return JSValue::encode( - JSCommonJSModule::create( - jsCast<Zig::GlobalObject*>(globalObject), - id, - object, callframe->argument(2).isBoolean() && callframe->argument(2).asBoolean())); + return JSValue::encode(JSCommonJSModule::create(jsCast<Zig::GlobalObject*>(globalObject), id, object, hasEvaluated.isTrue(), parent)); } JSCommonJSModule* JSCommonJSModule::create( Zig::GlobalObject* globalObject, const WTF::String& key, JSValue exportsObject, - bool hasEvaluated) + bool hasEvaluated, + JSValue parent) { auto& vm = globalObject->vm(); JSString* requireMapKey = JSC::jsStringWithCache(vm, key); @@ -530,8 +565,14 @@ JSCommonJSModule* JSCommonJSModule::create( globalObject->CommonJSModuleObjectStructure(), requireMapKey, requireMapKey, dirname, nullptr); - out->putDirect(vm, WebCore::clientData(vm)->builtinNames().exportsPublicName(), exportsObject, exportsObject.isCell() && exportsObject.isCallable() ? JSC::PropertyAttribute::Function | 0 : 0); + out->putDirect( + vm, + WebCore::clientData(vm)->builtinNames().exportsPublicName(), + exportsObject, + exportsObject.isCallable() ? JSC::PropertyAttribute::Function | 0 : 0); out->hasEvaluated = hasEvaluated; + out->m_parent.set(vm, out, parent); + return out; } |