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

Commit dab625a

Browse files
committed
Directly use FunctionBuilder when we do not need WasmExpressionBuilder.
This way, we use `WasmFunctionContext`+`WasmExpressionContext` only when we need to translate user-defined IR trees. In that case, the `WasmFunctionContext` is responsible for local name management: encoding from IR local names and generation of synthetic local names. Otherwise, when we generate Wasm code independent of IR trees, we directly use `FunctionBuilder`. Local name management is left to the user code.
1 parent 0117e8a commit dab625a

File tree

6 files changed

+242
-334
lines changed

6 files changed

+242
-334
lines changed

Diff for: wasm/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala

+73-65
Original file line numberDiff line numberDiff line change
@@ -149,45 +149,46 @@ class ClassEmitter(coreSpec: CoreSpec) {
149149

150150
implicit val noPos: Position = Position.NoPosition
151151

152-
def build(loadJSClass: (WasmFunctionContext) => Unit): WasmFunctionName = {
153-
implicit val fctx = WasmFunctionContext(
152+
def build(loadJSClass: (FunctionBuilder) => Unit): WasmFunctionName = {
153+
val fb = new FunctionBuilder(
154+
ctx.moduleBuilder,
154155
genFunctionName.isJSClassInstance(clazz.className),
155-
List("x" -> WasmRefType.anyref),
156-
List(WasmInt32)
156+
noPos
157157
)
158+
val xParam = fb.addParam("x", WasmRefType.anyref)
159+
fb.setResultType(WasmInt32)
160+
fb.setFunctionType(ctx.isJSClassInstanceFuncTypeName)
158161

159-
val List(xParam) = fctx.paramIndices
160-
161-
import fctx.instrs
162+
val instrs = fb
162163

163164
if (clazz.kind == ClassKind.JSClass && !clazz.hasInstances) {
164165
/* We need to constant-fold the instance test, to avoid trying to
165166
* call $loadJSClass.className, since it will not exist at all.
166167
*/
167-
fctx.instrs += I32_CONST(0) // false
168+
instrs += I32_CONST(0) // false
168169
} else {
169170
instrs += LOCAL_GET(xParam)
170-
loadJSClass(fctx)
171+
loadJSClass(fb)
171172
instrs += CALL(genFunctionName.jsBinaryOps(IRTrees.JSBinaryOp.instanceof))
172173
instrs += CALL(genFunctionName.unbox(IRTypes.BooleanRef))
173174
}
174175

175-
val func = fctx.buildAndAddToContext(ctx.isJSClassInstanceFuncTypeName)
176+
val func = fb.buildAndAddToModule()
176177
func.name
177178
}
178179

179180
clazz.kind match {
180181
case ClassKind.NativeJSClass =>
181182
clazz.jsNativeLoadSpec.map { jsNativeLoadSpec =>
182-
build { fctx =>
183-
WasmExpressionBuilder.genLoadJSNativeLoadSpec(fctx, jsNativeLoadSpec)
183+
build { fb =>
184+
WasmExpressionBuilder.genLoadJSNativeLoadSpec(fb, jsNativeLoadSpec)
184185
}
185186
}
186187

187188
case ClassKind.JSClass =>
188189
if (clazz.jsClassCaptures.isEmpty) {
189-
val funcName = build { fctx =>
190-
fctx.instrs += CALL(genFunctionName.loadJSClass(clazz.className))
190+
val funcName = build { fb =>
191+
fb += CALL(genFunctionName.loadJSClass(clazz.className))
191192
}
192193
Some(funcName)
193194
} else {
@@ -430,17 +431,18 @@ class ClassEmitter(coreSpec: CoreSpec) {
430431

431432
val classInfo = ctx.getClassInfo(clazz.className)
432433

433-
val fctx = WasmFunctionContext(
434+
val fb = new FunctionBuilder(
435+
ctx.moduleBuilder,
434436
genFunctionName.instanceTest(clazz.name.name),
435-
List("expr" -> WasmRefType.anyref),
436-
List(WasmInt32)
437+
pos
437438
)
438-
val List(exprParam) = fctx.paramIndices
439+
val exprParam = fb.addParam("expr", WasmRefType.anyref)
440+
fb.setResultType(WasmInt32)
439441

440-
import fctx.instrs
442+
val instrs = fb
441443

442-
val itables = fctx.addLocal("itables", WasmRefType.nullable(genTypeName.itables))
443-
val exprNonNullLocal = fctx.addLocal("exprNonNull", WasmRefType.any)
444+
val itables = fb.addLocal("itables", WasmRefType.nullable(genTypeName.itables))
445+
val exprNonNullLocal = fb.addLocal("exprNonNull", WasmRefType.any)
444446

445447
val itableIdx = ctx.getItableIdx(classInfo)
446448
instrs.block(WasmRefType.anyref) { testFail =>
@@ -511,7 +513,7 @@ class ClassEmitter(coreSpec: CoreSpec) {
511513
instrs += I32_CONST(0) // false
512514
}
513515

514-
fctx.buildAndAddToContext()
516+
fb.buildAndAddToModule()
515517
}
516518

517519
private def genNewDefaultFunc(clazz: LinkedClass)(implicit ctx: WasmContext): Unit = {
@@ -522,13 +524,14 @@ class ClassEmitter(coreSpec: CoreSpec) {
522524
assert(clazz.hasDirectInstances)
523525

524526
val structName = genTypeName.forClass(className)
525-
implicit val fctx = WasmFunctionContext(
527+
val fb = new FunctionBuilder(
528+
ctx.moduleBuilder,
526529
genFunctionName.newDefault(className),
527-
Nil,
528-
List(WasmRefType(structName))
530+
pos
529531
)
532+
fb.setResultType(WasmRefType(structName))
530533

531-
import fctx.instrs
534+
val instrs = fb
532535

533536
instrs += GLOBAL_GET(genGlobalName.forVTable(className))
534537

@@ -543,7 +546,7 @@ class ClassEmitter(coreSpec: CoreSpec) {
543546
}
544547
instrs += STRUCT_NEW(structName)
545548

546-
fctx.buildAndAddToContext()
549+
fb.buildAndAddToModule()
547550
}
548551

549552
/** Generate clone function for the given class, if it is concrete and implements the Cloneable
@@ -557,19 +560,21 @@ class ClassEmitter(coreSpec: CoreSpec) {
557560
val className = clazz.className
558561
val info = ctx.getClassInfo(className)
559562

560-
val fctx = WasmFunctionContext(
563+
val fb = new FunctionBuilder(
564+
ctx.moduleBuilder,
561565
genFunctionName.clone(className),
562-
List("from" -> WasmRefType(genTypeName.ObjectStruct)),
563-
List(WasmRefType(genTypeName.ObjectStruct))
566+
pos
564567
)
565-
val List(fromParam) = fctx.paramIndices
568+
val fromParam = fb.addParam("from", WasmRefType(genTypeName.ObjectStruct))
569+
fb.setResultType(WasmRefType(genTypeName.ObjectStruct))
570+
fb.setFunctionType(ctx.cloneFunctionTypeName)
566571

567-
import fctx.instrs
572+
val instrs = fb
568573

569574
val heapType = WasmHeapType(genTypeName.forClass(className))
570575

571-
val from = fctx.addSyntheticLocal(WasmRefType.nullable(heapType))
572-
val result = fctx.addSyntheticLocal(WasmRefType.nullable(heapType))
576+
val from = fb.addLocal("fromTyped", WasmRefType.nullable(heapType))
577+
val result = fb.addLocal("result", WasmRefType.nullable(heapType))
573578

574579
instrs += LOCAL_GET(fromParam)
575580
instrs += REF_CAST(WasmRefType(heapType))
@@ -587,7 +592,7 @@ class ClassEmitter(coreSpec: CoreSpec) {
587592
instrs += LOCAL_GET(result)
588593
instrs += REF_AS_NOT_NULL
589594

590-
fctx.buildAndAddToContext(ctx.cloneFunctionTypeName)
595+
fb.buildAndAddToModule()
591596
}
592597

593598
private def genLoadModuleFunc(clazz: LinkedClass)(implicit ctx: WasmContext): Unit = {
@@ -608,15 +613,16 @@ class ClassEmitter(coreSpec: CoreSpec) {
608613

609614
val resultTyp = WasmRefType(typeName)
610615

611-
implicit val fctx = WasmFunctionContext(
616+
val fb = new FunctionBuilder(
617+
ctx.moduleBuilder,
612618
genFunctionName.loadModule(clazz.className),
613-
Nil,
614-
List(resultTyp)
619+
pos
615620
)
621+
fb.setResultType(resultTyp)
616622

617-
val instanceLocal = fctx.addLocal("instance", resultTyp)
623+
val instanceLocal = fb.addLocal("instance", resultTyp)
618624

619-
import fctx.instrs
625+
val instrs = fb
620626

621627
instrs.block(resultTyp) { nonNullLabel =>
622628
// load global, return if not null
@@ -636,7 +642,7 @@ class ClassEmitter(coreSpec: CoreSpec) {
636642
instrs += LOCAL_GET(instanceLocal)
637643
}
638644

639-
fctx.buildAndAddToContext()
645+
fb.buildAndAddToModule()
640646
}
641647

642648
/** Generate global instance of the class itable. Their init value will be an array of null refs
@@ -1073,15 +1079,14 @@ class ClassEmitter(coreSpec: CoreSpec) {
10731079
)
10741080
ctx.addGlobal(cachedJSClassGlobal)
10751081

1076-
val fctx = WasmFunctionContext(
1077-
Some(clazz.className),
1082+
val fb = new FunctionBuilder(
1083+
ctx.moduleBuilder,
10781084
genFunctionName.loadJSClass(clazz.className),
1079-
None,
1080-
Nil,
1081-
List(WasmRefType.any)
1085+
pos
10821086
)
1087+
fb.setResultType(WasmRefType.any)
10831088

1084-
import fctx.instrs
1089+
val instrs = fb
10851090

10861091
instrs.block(WasmRefType.any) { doneLabel =>
10871092
// Load cached JS class, return if non-null
@@ -1091,7 +1096,7 @@ class ClassEmitter(coreSpec: CoreSpec) {
10911096
instrs += CALL(genFunctionName.createJSClassOf(clazz.className))
10921097
}
10931098

1094-
fctx.buildAndAddToContext()
1099+
fb.buildAndAddToModule()
10951100
}
10961101

10971102
private def genLoadJSModuleFunction(clazz: LinkedClass)(implicit ctx: WasmContext): Unit = {
@@ -1109,13 +1114,14 @@ class ClassEmitter(coreSpec: CoreSpec) {
11091114
)
11101115
)
11111116

1112-
val fctx = WasmFunctionContext(
1117+
val fb = new FunctionBuilder(
1118+
ctx.moduleBuilder,
11131119
genFunctionName.loadModule(className),
1114-
Nil,
1115-
List(WasmRefType.anyref)
1120+
pos
11161121
)
1122+
fb.setResultType(WasmRefType.anyref)
11171123

1118-
import fctx.instrs
1124+
val instrs = fb
11191125

11201126
instrs.block(WasmRefType.anyref) { doneLabel =>
11211127
// Load cached instance; return if non-null
@@ -1132,7 +1138,7 @@ class ClassEmitter(coreSpec: CoreSpec) {
11321138
instrs += GLOBAL_GET(cacheGlobalName)
11331139
}
11341140

1135-
fctx.buildAndAddToContext()
1141+
fb.buildAndAddToModule()
11361142
}
11371143

11381144
private def transformTopLevelMethodExportDef(
@@ -1246,20 +1252,22 @@ class ClassEmitter(coreSpec: CoreSpec) {
12461252
* at least one table.
12471253
*/
12481254

1249-
implicit val fctx = WasmFunctionContext(
1250-
Some(className),
1255+
val fb = new FunctionBuilder(
1256+
ctx.moduleBuilder,
12511257
genFunctionName.forTableEntry(className, methodName),
1252-
Some(WasmRefType.any),
1253-
method.args,
1254-
method.resultType
1258+
pos
12551259
)
1260+
val receiverParam = fb.addParam("<this>", WasmRefType.any)
1261+
val argParams = method.args.map { arg =>
1262+
fb.addParam(arg.name.name.nameString, TypeTransformer.transformType(arg.ptpe))
1263+
}
1264+
fb.setResultTypes(TypeTransformer.transformResultType(method.resultType))
1265+
fb.setFunctionType(ctx.tableFunctionType(methodName))
12561266

1257-
import fctx.instrs
1258-
1259-
val receiverLocal :: paramLocals = fctx.paramIndices: @unchecked
1267+
val instrs = fb
12601268

12611269
// Load and cast down the receiver
1262-
instrs += LOCAL_GET(receiverLocal)
1270+
instrs += LOCAL_GET(receiverParam)
12631271
receiverTyp match {
12641272
case Some(Types.WasmRefType(_, WasmHeapType.Any)) =>
12651273
() // no cast necessary
@@ -1270,13 +1278,13 @@ class ClassEmitter(coreSpec: CoreSpec) {
12701278
}
12711279

12721280
// Load the other parameters
1273-
for (paramLocal <- paramLocals)
1274-
instrs += LOCAL_GET(paramLocal)
1281+
for (argParam <- argParams)
1282+
instrs += LOCAL_GET(argParam)
12751283

12761284
// Call the statically resolved method
12771285
instrs += RETURN_CALL(functionName)
12781286

1279-
fctx.buildAndAddToContext(useFunctionTypeInMainRecType = true)
1287+
fb.buildAndAddToModule()
12801288
}
12811289
}
12821290

0 commit comments

Comments
 (0)