Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Fix top-level exports corner cases. #128

Merged
merged 3 commits into from
May 15, 2024

Conversation

sjrd
Copy link
Collaborator

@sjrd sjrd commented May 14, 2024

No description provided.

This is necessary for exported Scala classes to be instantiable
with `new ExportedClass()`.
@sjrd sjrd requested a review from tanishiking May 14, 2024 13:46
Copy link
Owner

@tanishiking tanishiking left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few questions, but overall it looks good to me 👍
Having some comments (something like commit message on 208202a) at transformTopLevelExport would be helpful

Comment on lines 200 to 201
/* Usually redundant, but necessary if the static field is never
* explicitly set and keeps its default (zero) value instead.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why it's necessary in that case? For initializing JS mirror to be its default (zero)?

Comment on lines -75 to -76
case d: TopLevelJSClassExportDef => genDelayedTopLevelExport(d.exportName)
case d: TopLevelModuleExportDef => genDelayedTopLevelExport(d.exportName)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of defining Global in Wasm, genTopLevelExportSetter eventually generate declaration (and setter) in JS via buildJSFileContent.

case d: TopLevelJSClassExportDef => genDelayedTopLevelExport(d.exportName)
case d: TopLevelModuleExportDef => genDelayedTopLevelExport(d.exportName)
case d: TopLevelMethodExportDef => transformTopLevelMethodExportDef(d)
case d: TopLevelFieldExportDef => transformTopLevelFieldExportDef(d)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, we will have two different global states for TopLevelFieldExportDef

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so that's why we have a mirror, and when global is updated, it also updates the content of JS here in genAssign's case SelectStatic.
https://github.com/tanishiking/scala-wasm/pull/128/files#diff-21791d7e9413ad6e99a12c7089bf6f6ebbb9143ee2ee4c35ca1e831f80531e4eR463-R475

sjrd added 2 commits May 15, 2024 10:28
The previous strategy for top-level export could not lead to any
workable support of mutable vars. We now follow a strategy similar
to what the JS backend uses in its NoModule configuration.

Previously, we compiled top-level exports as Wasm global exports.
We then had a postprocessing step in the loader to extract the
`.value` of the `WAGlobal` instances. This correctly captured the
exported value right after the start function has finished.
However, it could not update the exported value after a mutable
static field was reassigned.

Now, we turn everything everything around. Instead of the JS loader
and wrapper *pulling* values from Wasm, the Wasm code *pushes*
updates to top-level exports to JavaScript. That means we declare
setter functions from JavaScript, and that we (counter-intuitively)
*import* those setters into Wasm. Wasm calls the setters in the
start function for all top-level exports, and again when assigning
static fields that are exported.
@sjrd
Copy link
Collaborator Author

sjrd commented May 15, 2024

I added comments as suggested.

@sjrd sjrd requested a review from tanishiking May 15, 2024 08:29
Copy link
Owner

@tanishiking tanishiking left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the explanations!

/* Usually redundant, but necessary if the static field is never
* explicitly set and keeps its default (zero) value instead. In that
* case this initial call is required to publish that zero value (as
* opposed to the default `undefined` value of the JS `let`).
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@tanishiking tanishiking merged commit 10762f0 into tanishiking:main May 15, 2024
1 check passed
@sjrd sjrd deleted the fix-top-level-exports branch May 15, 2024 08:44
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants