Repository navigation
Trace the value an object or data module exports from its JSSourceCode #44466
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,7 +3,7 @@ | |
| * for local mode. Override via `--webkit-version=<hash>` to test a branch. | ||
| * From https://github.com/oven-sh/WebKit releases. | ||
| */ | ||
| export const WEBKIT_VERSION = "fb1167ebf2cb9edc1f6771a2c11771b024693ae0"; | ||
| export const WEBKIT_VERSION = "autobuild-preview-pr-758-47ef27fd"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Every contributor and CI build breaks with a 404 on the WebKit download once oven-sh/WebKit#758 merges or closes, because WEBKIT_VERSION at scripts/build/deps/webkit.ts:6 pins the preview tag "autobuild-preview-pr-758-47ef27fd". GitHub deletes preview releases at that point, as scripts/build/download.ts:320 documents. The PR notes say the pin must move before merge; the code as submitted still carries the preview tag, and nothing enforces that. Fix: before merging, land oven-sh/WebKit#758 and set WEBKIT_VERSION to the merged main commit sha or its autobuild- tag, since src/jsc/modules/ObjectModule.cpp:79 needs createWithPayload from that build. Why this was flaggedAny Verification: scripts/build/deps/webkit.ts:6 now reads
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct. The preview tag is only there so that CI can build and test this change before oven-sh/WebKit#758 merges. When that pull request lands, I set |
||
|
|
||
| /** | ||
| * WebKit (JavaScriptCore) — the JS engine. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,104 +1,95 @@ | ||
| #include "ObjectModule.h" | ||
|
|
||
| namespace Zig { | ||
| JSC::SyntheticSourceProvider::SyntheticSourceGenerator | ||
| generateObjectModuleSourceCode(JSC::JSGlobalObject* globalObject, | ||
| JSC::JSObject* object) | ||
|
|
||
| static void generateObjectModuleSourceCode(JSC::JSGlobalObject* lexicalGlobalObject, | ||
| JSC::Identifier, | ||
| JSC::JSValue payload, | ||
| Vector<JSC::Identifier, 4>& exportNames, | ||
| JSC::MarkedArgumentBuffer& exportValues) | ||
| { | ||
| gcProtectNullTolerant(object); | ||
| return [object](JSC::JSGlobalObject* lexicalGlobalObject, | ||
| JSC::Identifier moduleKey, | ||
| Vector<JSC::Identifier, 4>& exportNames, | ||
| JSC::MarkedArgumentBuffer& exportValues) -> void { | ||
| auto& vm = JSC::getVM(lexicalGlobalObject); | ||
| auto throwScope = DECLARE_THROW_SCOPE(vm); | ||
| GlobalObject* globalObject = defaultGlobalObject(lexicalGlobalObject); | ||
| JSC::EnsureStillAliveScope stillAlive(object); | ||
|
|
||
| PropertyNameArrayBuilder properties(vm, PropertyNameMode::Strings, | ||
| PrivateSymbolMode::Exclude); | ||
| object->methodTable()->getOwnPropertyNames(object, globalObject, properties, DontEnumPropertiesMode::Exclude); | ||
| RETURN_IF_EXCEPTION(throwScope, void()); | ||
| gcUnprotectNullTolerant(object); | ||
| auto& vm = JSC::getVM(lexicalGlobalObject); | ||
| auto throwScope = DECLARE_THROW_SCOPE(vm); | ||
|
robobun marked this conversation as resolved.
|
||
| GlobalObject* globalObject = defaultGlobalObject(lexicalGlobalObject); | ||
| JSC::JSObject* object = payload.getObject(); | ||
| JSC::EnsureStillAliveScope stillAlive(object); | ||
|
|
||
| for (auto& entry : properties.releaseData()->propertyNameVector()) { | ||
| JSValue value = object->get(globalObject, entry); | ||
| RETURN_IF_EXCEPTION(throwScope, void()); | ||
| exportNames.append(entry); | ||
| exportValues.append(value); | ||
| } | ||
| }; | ||
| PropertyNameArrayBuilder properties(vm, PropertyNameMode::Strings, | ||
| PrivateSymbolMode::Exclude); | ||
| object->methodTable()->getOwnPropertyNames(object, globalObject, properties, DontEnumPropertiesMode::Exclude); | ||
| RETURN_IF_EXCEPTION(throwScope, void()); | ||
|
|
||
| for (auto& entry : properties.releaseData()->propertyNameVector()) { | ||
| JSValue value = object->get(globalObject, entry); | ||
| RETURN_IF_EXCEPTION(throwScope, void()); | ||
| exportNames.append(entry); | ||
| exportValues.append(value); | ||
| } | ||
| } | ||
|
|
||
| JSC::SyntheticSourceProvider::SyntheticSourceGenerator | ||
| generateObjectModuleSourceCodeForJSON(JSC::JSGlobalObject* globalObject, | ||
| JSC::JSObject* object) | ||
| static void generateObjectModuleSourceCodeForJSON(JSC::JSGlobalObject* lexicalGlobalObject, | ||
| JSC::Identifier, | ||
| JSC::JSValue payload, | ||
| Vector<JSC::Identifier, 4>& exportNames, | ||
| JSC::MarkedArgumentBuffer& exportValues) | ||
| { | ||
| gcProtectNullTolerant(object); | ||
| return [object](JSC::JSGlobalObject* lexicalGlobalObject, | ||
| JSC::Identifier moduleKey, | ||
| Vector<JSC::Identifier, 4>& exportNames, | ||
| JSC::MarkedArgumentBuffer& exportValues) -> void { | ||
| auto& vm = JSC::getVM(lexicalGlobalObject); | ||
| auto scope = DECLARE_THROW_SCOPE(vm); | ||
| GlobalObject* globalObject = reinterpret_cast<GlobalObject*>(lexicalGlobalObject); | ||
| JSC::EnsureStillAliveScope stillAlive(object); | ||
|
|
||
| PropertyNameArrayBuilder properties(vm, PropertyNameMode::Strings, | ||
| PrivateSymbolMode::Exclude); | ||
| object->getPropertyNames(globalObject, properties, DontEnumPropertiesMode::Exclude); | ||
| RETURN_IF_EXCEPTION(scope, void()); | ||
| gcUnprotectNullTolerant(object); | ||
|
|
||
| exportNames.append(vm.propertyNames->defaultKeyword); | ||
| exportValues.append(object); | ||
| auto& vm = JSC::getVM(lexicalGlobalObject); | ||
| auto scope = DECLARE_THROW_SCOPE(vm); | ||
| GlobalObject* globalObject = reinterpret_cast<GlobalObject*>(lexicalGlobalObject); | ||
| JSC::JSObject* object = payload.getObject(); | ||
| JSC::EnsureStillAliveScope stillAlive(object); | ||
|
|
||
| for (auto& entry : properties.releaseData()->propertyNameVector()) { | ||
| if (entry == vm.propertyNames->defaultKeyword) { | ||
| continue; | ||
| } | ||
| PropertyNameArrayBuilder properties(vm, PropertyNameMode::Strings, | ||
| PrivateSymbolMode::Exclude); | ||
| object->getPropertyNames(globalObject, properties, DontEnumPropertiesMode::Exclude); | ||
| RETURN_IF_EXCEPTION(scope, void()); | ||
|
|
||
| exportNames.append(entry); | ||
| exportNames.append(vm.propertyNames->defaultKeyword); | ||
| exportValues.append(object); | ||
|
|
||
| JSValue value = object->get(globalObject, entry); | ||
| RETURN_IF_EXCEPTION(scope, void()); | ||
| exportValues.append(value); | ||
| for (auto& entry : properties.releaseData()->propertyNameVector()) { | ||
| if (entry == vm.propertyNames->defaultKeyword) { | ||
| continue; | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| JSC::SyntheticSourceProvider::SyntheticSourceGenerator | ||
| generateJSValueModuleSourceCode(JSC::JSGlobalObject* globalObject, | ||
| JSC::JSValue value) | ||
| { | ||
| exportNames.append(entry); | ||
|
|
||
| if (value.isObject() && !JSC::isJSArray(value)) { | ||
| return generateObjectModuleSourceCodeForJSON(globalObject, | ||
| value.getObject()); | ||
| JSValue value = object->get(globalObject, entry); | ||
| RETURN_IF_EXCEPTION(scope, void()); | ||
| exportValues.append(value); | ||
| } | ||
| } | ||
|
|
||
| return generateJSValueExportDefaultObjectSourceCode(globalObject, value); | ||
| static void generateJSValueExportDefaultObjectSourceCode(JSC::JSGlobalObject* lexicalGlobalObject, | ||
| JSC::Identifier, | ||
| JSC::JSValue payload, | ||
| Vector<JSC::Identifier, 4>& exportNames, | ||
| JSC::MarkedArgumentBuffer& exportValues) | ||
| { | ||
| auto& vm = JSC::getVM(lexicalGlobalObject); | ||
| exportNames.append(vm.propertyNames->defaultKeyword); | ||
| exportValues.append(payload); | ||
| const Identifier& esModuleMarker = vm.propertyNames->__esModule; | ||
| exportNames.append(esModuleMarker); | ||
| exportValues.append(jsBoolean(true)); | ||
| } | ||
|
|
||
| JSC::SyntheticSourceProvider::SyntheticSourceGenerator | ||
| generateJSValueExportDefaultObjectSourceCode(JSC::JSGlobalObject* globalObject, | ||
| JSC::JSValue value) | ||
| JSC::JSSourceCode* createObjectModuleSourceCode(JSC::VM& vm, JSC::JSObject* exports, WTF::String&& sourceURL) | ||
| { | ||
| if (value.isCell()) | ||
| gcProtectNullTolerant(value.asCell()); | ||
| return [value](JSC::JSGlobalObject* lexicalGlobalObject, | ||
| JSC::Identifier moduleKey, | ||
| Vector<JSC::Identifier, 4>& exportNames, | ||
| JSC::MarkedArgumentBuffer& exportValues) -> void { | ||
| auto& vm = JSC::getVM(lexicalGlobalObject); | ||
| exportNames.append(vm.propertyNames->defaultKeyword); | ||
| exportValues.append(value); | ||
| const Identifier& esModuleMarker = vm.propertyNames->__esModule; | ||
| exportNames.append(esModuleMarker); | ||
| exportValues.append(jsBoolean(true)); | ||
| return JSC::JSSourceCode::createWithPayload(vm, generateObjectModuleSourceCode, exports, JSC::SourceOrigin(), WTF::move(sourceURL)); | ||
| } | ||
|
|
||
| if (value.isCell()) | ||
| gcUnprotectNullTolerant(value.asCell()); | ||
| }; | ||
| JSC::JSSourceCode* createJSValueModuleSourceCode(JSC::VM& vm, JSC::JSValue value, WTF::String&& sourceURL) | ||
| { | ||
| if (value.isObject() && !JSC::isJSArray(value)) | ||
| return JSC::JSSourceCode::createWithPayload(vm, generateObjectModuleSourceCodeForJSON, value, JSC::SourceOrigin(), WTF::move(sourceURL)); | ||
|
|
||
| return createJSValueExportDefaultObjectSourceCode(vm, value, WTF::move(sourceURL)); | ||
| } | ||
|
|
||
| JSC::JSSourceCode* createJSValueExportDefaultObjectSourceCode(JSC::VM& vm, JSC::JSValue value, WTF::String&& sourceURL) | ||
| { | ||
| return JSC::JSSourceCode::createWithPayload(vm, generateJSValueExportDefaultObjectSourceCode, value, JSC::SourceOrigin(), WTF::move(sourceURL)); | ||
| } | ||
|
|
||
| } // namespace Zig | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Pin the merged WebKit build before merging this PR.
WEBKIT_VERSIONpoints to the preview build foroven-sh/WebKit#758, which is still open as of October 2, 2026. Update this value to the mergedautobuild-<full-sha>tag before merging this PR. (github.com)Based on learnings, keep this dependent PR blocked until the upstream change lands; the PR objective also requires the merged-build pin before merge.
🤖 Prompt for AI Agents
Source: Learnings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, and it is planned.
WEBKIT_VERSIONpoints at the preview build so that CI can build and test this change before oven-sh/WebKit#758 merges. When that pull request lands, the pin moves to its mergedautobuild-<sha>tag. This pull request must not merge before then, and the Notes section of the description says so. I leave this thread open until the pin moves.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robobunThanks for clarifying. The preview pin is intentional for CI testing, and the PR description already documents the merge requirement. This matches the existing guidance for temporary preview pins. Keeping this thread open until the pin moves to the merged build is appropriate.🧠 Learnings used
You are interacting with an AI system.