org.scalajs.linker.backend.wasmemitter
CustomJSHelperBuilder
Companion object CustomJSHelperBuilder
class CustomJSHelperBuilder extends AnyRef
Toolkit to build custom JS helpers that take Wasm inputs, while trying to optimize them directly as JavaScript trees.
The usage scenario for this class is as follows:
val builder = new CustomJSHelperBuilder() // Add inputs that will be evaluated on the Wasm call site, and whose // values are then available as `js.Tree`s in the JS helper: val xRef = builder.addWasmInput(watpe.Int32) { // Wasm code evaluated at call site fb += wa.LocalGet(someLocal) } ... // Build the body of the helper using the above inputs val helperID = builder.build(watpe.Int32) { js.Return(js.BinaryOp(JSBinaryOp.+, xRef, js.IntLiteral(5))) } // Call the helper, which consumes the declared inputs and leaves the result on the stack fb += wa.Call(helperID)
The subclass CustomJSHelperBuilder.WithTreeEval provides even richer
capabilities, by allowing to evaluate arbitrary IR Tree
s as inputs. The
builder will optimize the evaluation and transfer from Wasm to JS:
- Evaluate some trees entirely on the JS side instead of on the Wasm side. This is notably the case for string literals, which commonly appear as method names, and global refs/external imports, which commonly appear as method receivers.
- For other trees, evaluate them on the Wasm side, but fuse their boxing operation with the Wasm-to-JS interoperability layer, by choosing the best possible Wasm type for the helper function.
When using the WithTreeEval
subclass, the user must provide a concrete
method to evaluate Tree
s at call site with a given expected type. In the
context of FunctionEmitter
, that directly translates to the genTree
method.
A typical scenario looks like:
val builder = new CustomJSHelperBuilder.WithTreeEval() { protected def evalTreeAtCallSite(tree: Tree, expectedType: Type): Unit = ??? } // Add inputs that will be evaluated on the JS side if possible, otherwise // evaluated on the Wasm call site, and whose values are then available as // `js.Tree`s in the JS helper: val xRef = builder.addInput(someIRTree) ...
In addition to the input management, CustomJSHelperBuilder
provides tools
for local name management, and generation of js.ParamDef
s for inner
functions.
- Alphabetic
- By Inheritance
- CustomJSHelperBuilder
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Instance Constructors
- new CustomJSHelperBuilder()(implicit ctx: WasmContext, pos: Position)
Value Members
-
final
def
!=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
##(): Int
- Definition Classes
- AnyRef → Any
-
final
def
==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
addWasmInput(origName: String, wasmType: Type)(evalValue: ⇒ Unit): VarRef
Adds an input of an arbitrary Wasm type, to be evaluated on the Wasm stack.
Adds an input of an arbitrary Wasm type, to be evaluated on the Wasm stack.
The
evalValue
must add code to the call site context to evaluate the value on the Wasm site. It is passed as by-name parameter to show intent, but is in fact called immediately.- returns
A
js.VarRef
that can be used in the JS helper to read the input.
-
final
def
asInstanceOf[T0]: T0
- Definition Classes
- Any
- def build(resultType: Type)(body: Tree): FunctionID
-
def
clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( ... ) @native()
-
final
def
eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
equals(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( classOf[java.lang.Throwable] )
- def genGlobalRef(name: String): VarRef
- def genJSNativeLoadSpec(jsNativeLoadSpec: JSNativeLoadSpec): Tree
- def genJSParamDef(param: ParamDef): ParamDef
- def genJSParamDefs(params: List[ParamDef], restParam: Option[ParamDef]): (List[ParamDef], Option[ParamDef])
-
final
def
getClass(): Class[_]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
def
hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
final
def
isInstanceOf[T0]: Boolean
- Definition Classes
- Any
-
final
def
ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def newLocalIdent(name: LocalName): DelayedIdent
- def newLocalIdent(origName: String): DelayedIdent
-
final
def
notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
final
def
notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
-
def
toString(): String
- Definition Classes
- AnyRef → Any
-
final
def
wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... ) @native()