From 25e69c71e70ac8a0a88f9cf15b4057bd7b2a633a Mon Sep 17 00:00:00 2001 From: dave caruso Date: Fri, 22 Sep 2023 01:09:55 -0400 Subject: Implement module.parent (#5889) * Make module.parent work * yay * oops * yay --- src/bun.js/bindings/CommonJSModuleRecord.cpp | 77 +++++++++++++++++++++------- 1 file changed, 59 insertions(+), 18 deletions(-) (limited to 'src/bun.js/bindings/CommonJSModuleRecord.cpp') 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 #include +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(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(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(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(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createChildren } }, + { "_compile"_s, static_cast(PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, functionCommonJSModuleRecord_compile, 2 } }, + { "children"_s, static_cast(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, createChildren } }, { "filename"_s, static_cast(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterFilename, setterFilename } }, { "id"_s, static_cast(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterId, setterId } }, - { "loaded"_s, static_cast(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createLoaded } }, - { "parent"_s, static_cast(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createParent } }, + { "loaded"_s, static_cast(PropertyAttribute::PropertyCallback), NoIntrinsic, { HashTableValue::LazyPropertyType, createLoaded } }, + { "parent"_s, static_cast(PropertyAttribute::CustomAccessor | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, getterParent, setterParent } }, { "path"_s, static_cast(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterPath, setterPath } }, { "paths"_s, static_cast(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterPaths, setterPaths } }, - { "_compile"_s, static_cast(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(globalObject), - id, - object, callframe->argument(2).isBoolean() && callframe->argument(2).asBoolean())); + return JSValue::encode(JSCommonJSModule::create(jsCast(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; } -- cgit v1.2.3 on-wsl Unnamed repository; edit this file 'description' to name the repository.
aboutsummaryrefslogtreecommitdiff
AgeCommit message (Expand)AuthorFilesLines
2023-07-19fix `make headers`Gravatar Dylan Conway 1-7/+15
2023-07-20Better error for workspace dependency not found (#3678)Gravatar Jarred Sumner 2-21/+85
2023-07-18Fix crash in postMessage that repro'd after ~100,000 messagesGravatar Jarred Sumner 6-21/+57
2023-07-18more progress on fixing gc issueGravatar Jarred Sumner 6-61/+162
2023-07-18add padding bytesGravatar Dylan Conway 1-1/+1
2023-07-18feature(constants) add constants/node:constants module and tests(prisma) use ...Gravatar Ciro Spaciari 16-20/+529
2023-07-18patch checkServerIdentity (#3671)Gravatar Ciro Spaciari 3-3/+9
2023-07-18Update workers.mdGravatar Jarred Sumner 1-2/+2
2023-07-18[jest] execute lifecycle hooks on empty blocks (#3663)Gravatar Alex Lam S.L 2-19/+79
2023-07-18ClarifyGravatar Jarred Sumner 1-0/+2
2023-07-18Fixes #3669Gravatar Jarred Sumner 4-13/+35
2023-07-18zig upgrade (#3667)Gravatar Dylan Conway 154-4894/+4857
2023-07-17Enable postgres prisma testGravatar Jarred Sumner 1-1/+1
2023-07-17Emit writeBarrier in `napi_module_register`Gravatar Jarred Sumner 1-6/+14
2023-07-17Fix potential crash in process.dlopen()Gravatar Jarred Sumner 2-5/+27
2023-07-17Implement `process.{stdout, stderr}.{columns, rows, getWindowSize}`Gravatar Jarred Sumner 4-32/+108
2023-07-17[tls] General compatibility improvements (#3596)Gravatar Ciro Spaciari 23-298/+2907
2023-07-17package json `main` field extension order (#3664)Gravatar Dylan Conway 3-3/+96
2023-07-17[install] handle duplicated workspace declarations gracefully (#3662)Gravatar Alex Lam S.L 2-6/+197
2023-07-17Clean up worker docsGravatar Colin McDonnell 1-65/+69
2023-07-17Tweak test docsGravatar Colin McDonnell 2-4/+3
2023-07-17workaround `readable-stream` compatibility (#3626)Gravatar Alex Lam S.L 3-4/+5
2023-07-17Fix flaky process testGravatar Jarred SUmner 1-2/+2
2023-07-17Fix test with incorrect textGravatar Jarred Sumner 1-3/+3
2023-07-17Fix incorrect nameGravatar Jarred Sumner 2-4/+4
2023-07-17Fix speculative crashes in console.log(formData) and console.log(headers)Gravatar Jarred Sumner 2-30/+24
2023-07-17Fix crash in console.log(urlSearchParams) on a URLSearchParams object with a ...Gravatar Jarred Sumner 2-4/+99
2023-07-17Fix memory leak in `await new Response(latin1String).arrayBuffer()` and `awai...Gravatar Jarred Sumner 16-102/+361
2023-07-1720% faster `deserialize` (#3655)Gravatar Jarred Sumner 2-12/+197
2023-07-16Document `--smol`Gravatar Jarred Sumner 1-70/+59
2023-07-16Add `--smol` to bunfigGravatar Jarred Sumner 1-0/+12
2023-07-16Document serialize/deserializeGravatar Jarred Sumner 1-0/+14