Skip to content

Commit b7a1aff

Browse files
Address major FIXME in Translator
1 parent 4aff9cc commit b7a1aff

File tree

1 file changed

+42
-24
lines changed

1 file changed

+42
-24
lines changed

Sources/WasmKit/Translator.swift

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -696,13 +696,30 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
696696
/// - Parameters:
697697
/// - ref: Label reference to be resolved
698698
/// - make: Factory closure to make an inserting instruction
699-
mutating func emitWithLabel(_ ref: LabelRef, line: UInt = #line, make: @escaping InstructionFactoryWithLabel) {
699+
mutating func emitWithLabel<Immediate: InstructionImmediate>(
700+
_ makeInstruction: @escaping (Immediate) -> Instruction,
701+
_ ref: LabelRef,
702+
line: UInt = #line,
703+
make: @escaping (
704+
ISeqBuilder,
705+
// The position of the next slot of the creating instruction
706+
_ source: MetaProgramCounter,
707+
// The position of the resolved label
708+
_ target: MetaProgramCounter
709+
) -> (Immediate)
710+
) {
700711
let insertAt = insertingPC
701-
// TODO: Skip emitting nop if the label is already pinned
702-
// FIXME: ****THIS IS ABSOLUTELY WRONG. JUST FOR PERF EVALUATION**
703-
// Please change placeholder size based on whether the instruction has any immediate
704-
emit(.br(0)) // Emit dummy instruction to be replaced later
705-
emitWithLabel(ref, insertAt: insertAt, line: line, make: make)
712+
713+
// Emit dummy instruction to be replaced later
714+
emitSlot(0) // dummy opcode
715+
var immediateSlots = 0
716+
Immediate.emit(to: { _ in immediateSlots += 1 })
717+
for _ in 0..<immediateSlots { emitSlot(0) }
718+
719+
// Schedule actual emission
720+
emitWithLabel(ref, insertAt: insertAt, line: line, make: {
721+
makeInstruction(make($0, $1, $2))
722+
})
706723
}
707724

708725
/// Emit an instruction at the specified position with resolved label position
@@ -1097,15 +1114,15 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
10971114
)
10981115
)
10991116
guard let condition = condition else { return }
1100-
iseqBuilder.emitWithLabel(endLabel) { iseqBuilder, selfPC, endPC in
1117+
iseqBuilder.emitWithLabel(Instruction.brIfNot, endLabel) { iseqBuilder, selfPC, endPC in
11011118
let targetPC: MetaProgramCounter
11021119
if let elsePC = iseqBuilder.resolveLabel(elseLabel) {
11031120
targetPC = elsePC
11041121
} else {
11051122
targetPC = endPC
11061123
}
11071124
let elseOrEnd = UInt32(targetPC.offsetFromHead - selfPC.offsetFromHead)
1108-
return .brIfNot(Instruction.BrIfOperand(condition: LVReg(condition), offset: Int32(elseOrEnd)))
1125+
return Instruction.BrIfOperand(condition: LVReg(condition), offset: Int32(elseOrEnd))
11091126
}
11101127
}
11111128

@@ -1117,9 +1134,9 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
11171134
preserveOnStack(depth: valueStack.height - frame.stackHeight)
11181135
try controlStack.resetReachability()
11191136
iseqBuilder.resetLastEmission()
1120-
iseqBuilder.emitWithLabel(endLabel) { _, selfPC, endPC in
1137+
iseqBuilder.emitWithLabel(Instruction.br, endLabel) { _, selfPC, endPC in
11211138
let offset = endPC.offsetFromHead - selfPC.offsetFromHead
1122-
return .br(Int32(offset))
1139+
return Int32(offset)
11231140
}
11241141
try valueStack.truncate(height: frame.stackHeight)
11251142
// Re-push parameters
@@ -1191,9 +1208,10 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
11911208
return popCount
11921209
}
11931210

1194-
private mutating func emitBranch(
1211+
private mutating func emitBranch<Immediate: InstructionImmediate>(
1212+
_ makeInstruction: @escaping (Immediate) -> Instruction,
11951213
relativeDepth: UInt32,
1196-
make: @escaping (_ offset: Int32, _ copyCount: UInt32, _ popCount: UInt32) -> Instruction
1214+
make: @escaping (_ offset: Int32, _ copyCount: UInt32, _ popCount: UInt32) -> Immediate
11971215
) throws {
11981216
let frame = try controlStack.branchTarget(relativeDepth: relativeDepth)
11991217
let copyCount = frame.copyCount
@@ -1202,7 +1220,7 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
12021220
currentFrame: try controlStack.currentFrame(),
12031221
currentHeight: valueStack.height
12041222
)
1205-
iseqBuilder.emitWithLabel(frame.continuation) { _, selfPC, continuation in
1223+
iseqBuilder.emitWithLabel(makeInstruction, frame.continuation) { _, selfPC, continuation in
12061224
let relativeOffset = continuation.offsetFromHead - selfPC.offsetFromHead
12071225
return make(Int32(relativeOffset), UInt32(copyCount), popCount)
12081226
}
@@ -1219,8 +1237,8 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
12191237
// +---[ i32 ]<--+ copy [2]
12201238
// [ i64 ]---+
12211239
try copyOnBranch(targetFrame: frame)
1222-
try emitBranch(relativeDepth: relativeDepth) { offset, copyCount, popCount in
1223-
return .br(offset)
1240+
try emitBranch(Instruction.br, relativeDepth: relativeDepth) { offset, copyCount, popCount in
1241+
return offset
12241242
}
12251243
try markUnreachable()
12261244
}
@@ -1231,11 +1249,11 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
12311249
let frame = try controlStack.branchTarget(relativeDepth: relativeDepth)
12321250
if frame.copyCount == 0 {
12331251
// Optimization where we don't need copying values when the branch taken
1234-
iseqBuilder.emitWithLabel(frame.continuation) { _, selfPC, continuation in
1252+
iseqBuilder.emitWithLabel(Instruction.brIf, frame.continuation) { _, selfPC, continuation in
12351253
let relativeOffset = continuation.offsetFromHead - selfPC.offsetFromHead
1236-
return .brIf(Instruction.BrIfOperand(
1254+
return Instruction.BrIfOperand(
12371255
condition: LVReg(condition), offset: Int32(relativeOffset)
1238-
))
1256+
)
12391257
}
12401258
return
12411259
}
@@ -1262,13 +1280,13 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
12621280
// [0x06] (local.get 1 reg:2) <----|---------+
12631281
// [0x07] ... <-------+
12641282
let onBranchNotTaken = iseqBuilder.allocLabel()
1265-
iseqBuilder.emitWithLabel(onBranchNotTaken) { _, conditionCheckAt, continuation in
1283+
iseqBuilder.emitWithLabel(Instruction.brIfNot, onBranchNotTaken) { _, conditionCheckAt, continuation in
12661284
let relativeOffset = continuation.offsetFromHead - conditionCheckAt.offsetFromHead
1267-
return .brIfNot(Instruction.BrIfOperand(condition: LVReg(condition), offset: Int32(relativeOffset)))
1285+
return Instruction.BrIfOperand(condition: LVReg(condition), offset: Int32(relativeOffset))
12681286
}
12691287
try copyOnBranch(targetFrame: frame)
1270-
try emitBranch(relativeDepth: relativeDepth) { offset, copyCount, popCount in
1271-
return .br(offset)
1288+
try emitBranch(Instruction.br, relativeDepth: relativeDepth) { offset, copyCount, popCount in
1289+
return offset
12721290
}
12731291
try iseqBuilder.pinLabelHere(onBranchNotTaken)
12741292
}
@@ -1328,9 +1346,9 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
13281346
}
13291347
let emittedCopy = try copyOnBranch(targetFrame: frame)
13301348
if emittedCopy {
1331-
iseqBuilder.emitWithLabel(frame.continuation) { _, brAt, continuation in
1349+
iseqBuilder.emitWithLabel(Instruction.br, frame.continuation) { _, brAt, continuation in
13321350
let relativeOffset = continuation.offsetFromHead - brAt.offsetFromHead
1333-
return .br(Int32(relativeOffset))
1351+
return Int32(relativeOffset)
13341352
}
13351353
} else {
13361354
// Optimization: If no value is copied, we can directly jump to the target

0 commit comments

Comments
 (0)