-
Notifications
You must be signed in to change notification settings - Fork 3
Merge WasmExpressionBuilder and WasmFunctionContext into FunctionEmitter. #125
Conversation
`SWasmGen` has the same role as `SJSGen` in the JS backend: producing Wasm fragments that are specific to the linker encoding, but used across several other components (notably, `ClassEmitter` and `WasmExpressionBuilder`).
This removes one more use of synthetic IR trees in `ClassEmitter`.
Rebased. |
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.
one question, but overall LGTM 🎉
@@ -210,22 +214,38 @@ const scalaJSHelpers = { | |||
|
|||
// Non-native JS class support | |||
newSymbol: Symbol, | |||
createJSClass: (data, superClass, preSuperStats, superArgs, postSuperStats) => { | |||
createJSClass: (data, superClass, preSuperStats, superArgs, postSuperStats, fields) => { |
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.
[note]
fields
is the array that, even index (including 0) contains the field name, and odd index contains the initial value
instrs ++= ctx.getConstantStringInstr(value) | ||
|
||
case IRTrees.VarRef(IRTrees.LocalIdent(localName)) | ||
if classCaptureParamsOfTypeAny.contains(localName) => |
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.
Why we need this condition in this case?
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.
Because in theory we could have a reference to a class capture of a type different than Any
. In that case, we would need adapt
to fix up the type, and that means we need a full expression builder/function emitter.
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.
we would need adapt to fix up the type,
Ah, right, thanks!
Instead of including it in `postSuperStats`. With this change, the `nameTree` of fields is evaluated in the same context as all the other `nameTree`s. This will make it easier to extract name evaluation.
In general, they can contain local variable definitions. These must not be defined in the same scope as the `createJSClass` function body, since they could clash with each other and/or with the class captures. Instead, in the general case, we extract them in separate functions, which we immediately call. For the common cases of string literals and direct reference to a class capture, we avoid the extra function. This treatment is similar to what the JS backend does, except the latter defines the "separate functions" inline, as immediatly invoked function expressions (IIFEs).
Now that we got rid of all the uses of the expression builder inside it, we can directly use a `FunctionBuilder`. This was the last place where we mixed IR-derived local names and codegen-chosen local names, as evidenced by the removal of the last public method `addLocal` in `WasmFunctionContext`.
The previous entry points `generateIRBody` and `generateBlockStats` are now private. Instead, `WasmExpressionBuilder` exposes `emitFunction` (the main entry point) and `emitJSConstructionFunctions` (a special alternative for the 3 functions that make up a JS constructor def). These entry points instantiate their own `WasmFunctionContext`, which is never used anywhere else anymore.
…ter. The combined class has the same responsibilities as the `FunctionEmitter` in the JS backend.
The combined class has the same responsibilities as the
FunctionEmitter
in the JS backend.Based on #124, but otherwise ready to review.