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

Commit

Permalink
Better codegen for the clone functions.
Browse files Browse the repository at this point in the history
Previously, we first created the struct with zero's, then assigned
fields from the source one by one.

We now load all the fields from the source onto the stack, then
directly use `struct.new` to allocate the target.

It might not necessarily be more efficient, but it definitely
results is smaller code.
  • Loading branch information
sjrd committed May 21, 2024
1 parent 28a4332 commit 0d82f14
Showing 1 changed file with 16 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -545,26 +545,28 @@ class ClassEmitter(coreSpec: CoreSpec) {

val instrs = fb

val heapType = watpe.HeapType(genTypeID.forClass(className))
val structTypeID = genTypeID.forClass(className)
val structRefType = watpe.RefType(structTypeID)

val from = fb.addLocal("fromTyped", watpe.RefType.nullable(heapType))
val result = fb.addLocal("result", watpe.RefType.nullable(heapType))
val fromTypedLocal = fb.addLocal("fromTyped", structRefType)

// Downcast fromParam to fromTyped
instrs += wa.LocalGet(fromParam)
instrs += wa.RefCast(watpe.RefType(heapType))
instrs += wa.LocalSet(from)
instrs += wa.RefCast(structRefType)
instrs += wa.LocalSet(fromTypedLocal)

instrs += wa.Call(genFunctionID.newDefault(className))
instrs += wa.LocalSet(result)
// Push vtable and itables on the stack (there is at least Cloneable in the itables)
instrs += wa.GlobalGet(genGlobalID.forVTable(className))
instrs += wa.GlobalGet(genGlobalID.forITable(className))

// Push every field of `fromTyped` on the stack
info.allFieldDefs.foreach { field =>
val fieldIdx = genFieldID.forClassInstanceField(field.name.name)
instrs += wa.LocalGet(result)
instrs += wa.LocalGet(from)
instrs += wa.StructGet(genTypeID.forClass(className), fieldIdx)
instrs += wa.StructSet(genTypeID.forClass(className), fieldIdx)
instrs += wa.LocalGet(fromTypedLocal)
instrs += wa.StructGet(structTypeID, genFieldID.forClassInstanceField(field.name.name))
}
instrs += wa.LocalGet(result)
instrs += wa.RefAsNotNull

// Create the result
instrs += wa.StructNew(structTypeID)

fb.buildAndAddToModule()
}
Expand Down

0 comments on commit 0d82f14

Please sign in to comment.