Skip to content

Commit 2f435f5

Browse files
committed
adjust FuncTranslator for OpEncoder changes
1 parent a56279d commit 2f435f5

File tree

2 files changed

+75
-79
lines changed

2 files changed

+75
-79
lines changed

crates/wasmi/src/engine/translator/func/mod.rs

Lines changed: 66 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ use crate::{
4747
NegateCmpInstr,
4848
TryIntoCmpBranchInstr as _,
4949
TryIntoCmpSelectInstr as _,
50+
UpdateBranchOffset as _,
5051
},
5152
utils::{IntoShiftAmount, ToBits, WasmFloat, WasmInteger},
5253
WasmTranslator,
@@ -55,8 +56,19 @@ use crate::{
5556
CompiledFuncEntity,
5657
TranslationError,
5758
},
58-
ir,
59-
ir::{index, Address, BoundedSlotSpan, FixedSlotSpan, Offset16, Op, Sign, Slot, SlotSpan},
59+
ir::{
60+
self,
61+
index,
62+
Address,
63+
BoundedSlotSpan,
64+
BranchOffset,
65+
FixedSlotSpan,
66+
Offset16,
67+
Op,
68+
Sign,
69+
Slot,
70+
SlotSpan,
71+
},
6072
module::{FuncIdx, FuncTypeIdx, MemoryIdx, ModuleHeader, WasmiValueType},
6173
Engine,
6274
Error,
@@ -98,8 +110,6 @@ pub struct FuncTranslator {
98110
locals: LocalsRegistry,
99111
/// Wasm layout to map stack slots to Wasmi registers.
100112
layout: StackLayout,
101-
/// Slots and pins labels and tracks their users.
102-
labels: LabelRegistry,
103113
/// Constructs and encodes function instructions.
104114
instrs: OpEncoder,
105115
/// Temporary buffer for operands.
@@ -117,8 +127,6 @@ pub struct FuncTranslatorAllocations {
117127
locals: LocalsRegistry,
118128
/// Wasm layout to map stack slots to Wasmi registers.
119129
layout: StackLayout,
120-
/// Slots and pins labels and tracks their users.
121-
labels: LabelRegistry,
122130
/// Constructs and encodes function instructions.
123131
instrs: OpEncoderAllocations,
124132
/// Temporary buffer for operands.
@@ -132,7 +140,6 @@ impl Reset for FuncTranslatorAllocations {
132140
self.stack.reset();
133141
self.locals.reset();
134142
self.layout.reset();
135-
self.labels.reset();
136143
self.instrs.reset();
137144
self.operands.clear();
138145
self.immediates.clear();
@@ -173,7 +180,7 @@ impl WasmTranslator<'_> for FuncTranslator {
173180
let Some(frame_size) = self.frame_size() else {
174181
return Err(Error::from(TranslationError::AllocatedTooManySlots));
175182
};
176-
self.update_branch_offsets()?;
183+
self.instrs.update_branch_offsets()?;
177184
finalize(CompiledFuncEntity::new(
178185
frame_size,
179186
self.instrs.encoded_ops(),
@@ -190,7 +197,6 @@ impl ReusableAllocations for FuncTranslator {
190197
stack: self.stack.into_allocations(),
191198
locals: self.locals,
192199
layout: self.layout,
193-
labels: self.labels,
194200
instrs: self.instrs.into_allocations(),
195201
operands: self.operands,
196202
immediates: self.immediates,
@@ -215,7 +221,6 @@ impl FuncTranslator {
215221
stack,
216222
locals,
217223
layout,
218-
labels,
219224
instrs,
220225
operands,
221226
immediates,
@@ -230,7 +235,6 @@ impl FuncTranslator {
230235
stack,
231236
locals,
232237
layout,
233-
labels,
234238
instrs,
235239
operands,
236240
immediates,
@@ -244,7 +248,7 @@ impl FuncTranslator {
244248
fn init_func_body_block(&mut self) -> Result<(), Error> {
245249
let func_ty = self.module.get_type_of_func(self.func);
246250
let block_ty = BlockType::func_type(func_ty);
247-
let end_label = self.labels.new_label();
251+
let end_label = self.instrs.new_label();
248252
let consume_fuel = self.instrs.encode_consume_fuel()?;
249253
self.stack
250254
.push_func_block(block_ty, end_label, consume_fuel)?;
@@ -280,18 +284,6 @@ impl FuncTranslator {
280284
u16::try_from(frame_size).ok()
281285
}
282286

283-
/// Updates the branch offsets of all branch instructions inplace.
284-
///
285-
/// # Panics
286-
///
287-
/// If this is used before all branching labels have been pinned.
288-
fn update_branch_offsets(&mut self) -> Result<(), Error> {
289-
for (user, offset) in self.labels.resolved_users() {
290-
self.instrs.update_branch_offset(user, offset?)?;
291-
}
292-
Ok(())
293-
}
294-
295287
/// Returns the [`FuncType`] of the function that is currently translated.
296288
fn func_type(&self) -> FuncType {
297289
self.func_type_with(FuncType::clone)
@@ -704,7 +696,7 @@ impl FuncTranslator {
704696

705697
/// Pins the `label` to the next [`OpPos`].
706698
fn pin_label(&mut self, label: LabelRef) {
707-
self.labels.pin_label(label, self.instrs.next_pos());
699+
self.instrs.pin_label(label);
708700
}
709701

710702
/// Convert the [`Operand`] at `depth` into an [`Operand::Temp`] by copying if necessary.
@@ -783,12 +775,9 @@ impl FuncTranslator {
783775
fuel_costs: impl FnOnce(&FuelCostsProvider) -> u64,
784776
) -> Result<(), Error> {
785777
let consume_fuel_instr = self.stack.consume_fuel_instr();
786-
let expected_iidx = self.instrs.next_pos();
787778
let result = self.layout.temp_to_slot(self.stack.push_temp(result_ty)?)?;
788-
let actual_iidx = self
789-
.instrs
779+
self.instrs
790780
.stage(make_instr(result), consume_fuel_instr, fuel_costs)?;
791-
assert_eq!(expected_iidx, actual_iidx);
792781
Ok(())
793782
}
794783

@@ -839,16 +828,15 @@ impl FuncTranslator {
839828
FuelCostsProvider::base,
840829
)?;
841830
// Encode the `br_table` targets:
831+
let fuel_pos = self.stack.consume_fuel_instr();
842832
let targets = &self.immediates[..];
843833
for target in targets {
844834
let Ok(depth) = usize::try_from(u32::from(*target)) else {
845835
panic!("out of bounds `br_table` target does not fit `usize`: {target:?}");
846836
};
847837
let mut frame = self.stack.peek_control_mut(depth).control_frame();
848-
let _offset = self
849-
.labels
850-
.try_resolve_label(frame.label(), self.instrs.next_pos())?;
851-
// self.instrs.push_param(Op::branch(offset)); // TODO: finish encoding impl
838+
self.instrs
839+
.encode_branch(frame.label(), Op::branch, fuel_pos, 0)?;
852840
frame.branch_to();
853841
}
854842
Ok(())
@@ -873,21 +861,23 @@ impl FuncTranslator {
873861
FuelCostsProvider::base,
874862
)?;
875863
// Encode the `br_table` targets:
864+
let fuel_pos = self.stack.consume_fuel_instr();
876865
let targets = &self.immediates[..];
877866
for target in targets {
878867
let Ok(depth) = usize::try_from(u32::from(*target)) else {
879868
panic!("out of bounds `br_table` target does not fit `usize`: {target:?}");
880869
};
881870
let mut frame = self.stack.peek_control_mut(depth).control_frame();
882-
let Some(_results) = Self::frame_results_impl(&frame, &self.engine, &self.layout)?
871+
let Some(results) = Self::frame_results_impl(&frame, &self.engine, &self.layout)?
883872
else {
884873
panic!("must have frame results since `br_table` requires to copy values");
885874
};
886-
let _offset = self
887-
.labels
888-
.try_resolve_label(frame.label(), self.instrs.next_pos())?;
889-
// self.instrs
890-
// .push_param(Op::branch_table_target(results, offset)); // TODO: encode branch table targets properly
875+
self.instrs.encode_branch(
876+
frame.label(),
877+
|offset| ir::BranchTableTarget::new(results, offset),
878+
fuel_pos,
879+
0,
880+
)?;
891881
frame.branch_to();
892882
}
893883
Ok(())
@@ -1015,14 +1005,14 @@ impl FuncTranslator {
10151005
}
10161006
self.push_frame_results(&frame)?;
10171007
}
1018-
self.labels.pin_label(frame.label(), self.instrs.next_pos());
1008+
self.instrs.pin_label(frame.label());
10191009
self.reachable |= frame.is_branched_to();
10201010
if self.reachable && self.stack.is_control_empty() {
10211011
self.encode_return(consume_fuel_instr)?;
10221012
}
10231013
if frame.is_branched_to() {
10241014
// No need to reset `last_instr` if there was no branch to the end of a Wasm `block`.
1025-
self.instrs.try_encode_staged();
1015+
self.instrs.try_encode_staged()?;
10261016
}
10271017
Ok(())
10281018
}
@@ -1053,18 +1043,14 @@ impl FuncTranslator {
10531043
if is_end_of_then_reachable && has_results {
10541044
let consume_fuel_instr = frame.consume_fuel_instr();
10551045
self.copy_branch_params(&frame, consume_fuel_instr)?;
1056-
let end_offset = self
1057-
.labels
1058-
.try_resolve_label(frame.label(), self.instrs.next_pos())
1059-
.unwrap();
1060-
self.instrs.encode(
1061-
Op::branch(end_offset),
1046+
self.instrs.encode_branch(
1047+
frame.label(),
1048+
Op::branch,
10621049
consume_fuel_instr,
10631050
FuelCostsProvider::base,
10641051
)?;
10651052
}
1066-
self.labels
1067-
.pin_label_if_unpinned(else_label, self.instrs.next_pos());
1053+
self.instrs.pin_label_if_unpinned(else_label);
10681054
self.stack.push_else_operands(&frame)?;
10691055
if has_results {
10701056
// We haven't visited the `else` block and thus the `else`
@@ -1076,10 +1062,10 @@ impl FuncTranslator {
10761062
self.copy_branch_params(&frame, consume_fuel_instr)?;
10771063
}
10781064
self.push_frame_results(&frame)?;
1079-
self.labels.pin_label(frame.label(), self.instrs.next_pos());
1065+
self.instrs.pin_label(frame.label());
10801066
self.reachable = true;
10811067
// Need to reset `last_instr` since end of `if` is a control flow boundary.
1082-
self.instrs.try_encode_staged();
1068+
self.instrs.try_encode_staged()?;
10831069
Ok(())
10841070
}
10851071

@@ -1108,10 +1094,10 @@ impl FuncTranslator {
11081094
self.copy_branch_params(&frame, consume_fuel_instr)?;
11091095
}
11101096
self.push_frame_results(&frame)?;
1111-
self.labels.pin_label(frame.label(), self.instrs.next_pos());
1097+
self.instrs.pin_label(frame.label());
11121098
self.reachable = reachable;
11131099
// Need to reset `last_instr` since end of `else` is a control flow boundary.
1114-
self.instrs.try_encode_staged();
1100+
self.instrs.try_encode_staged()?;
11151101
Ok(())
11161102
}
11171103

@@ -1128,12 +1114,12 @@ impl FuncTranslator {
11281114
}
11291115
self.push_frame_results(&frame)?;
11301116
}
1131-
self.labels.pin_label(frame.label(), self.instrs.next_pos());
1117+
self.instrs.pin_label(frame.label());
11321118
self.reachable = end_is_reachable || frame.is_branched_to();
11331119
if frame.is_branched_to() {
11341120
// No need to reset `last_instr` if there was no branch to the
11351121
// end of a Wasm `if` where only `then` or `else` is reachable.
1136-
self.instrs.try_encode_staged();
1122+
self.instrs.try_encode_staged()?;
11371123
}
11381124
Ok(())
11391125
}
@@ -1142,7 +1128,7 @@ impl FuncTranslator {
11421128
fn translate_end_unreachable(&mut self, _frame: ControlFrameKind) -> Result<(), Error> {
11431129
debug_assert!(!self.stack.is_control_empty());
11441130
// We reset `last_instr` out of caution in case there is a control flow boundary.
1145-
self.instrs.try_encode_staged();
1131+
self.instrs.try_encode_staged()?;
11461132
Ok(())
11471133
}
11481134

@@ -1246,10 +1232,11 @@ impl FuncTranslator {
12461232

12471233
/// Encodes an unconditional Wasm `branch` instruction.
12481234
fn encode_br(&mut self, label: LabelRef) -> Result<Pos<Op>, Error> {
1249-
let instr = self.instrs.next_pos();
1250-
let offset = self.labels.try_resolve_label(label, instr)?;
1251-
let br_instr = self.push_instr(Op::branch(offset), FuelCostsProvider::base)?;
1252-
Ok(br_instr)
1235+
let fuel_pos = self.stack.consume_fuel_instr();
1236+
let (br_op, _) =
1237+
self.instrs
1238+
.encode_branch(label, Op::branch, fuel_pos, FuelCostsProvider::base)?;
1239+
Ok(br_op)
12531240
}
12541241

12551242
/// Encodes a `i32.eqz`+`br_if` or `if` conditional branch instruction.
@@ -1291,13 +1278,16 @@ impl FuncTranslator {
12911278
}
12921279
}
12931280
};
1294-
let instr = self.instrs.next_pos();
1295-
let offset = self.labels.try_resolve_label(label, instr)?;
1296-
let instr = match branch_eqz {
1297-
true => Op::branch_i32_eq_si(condition, 0, offset),
1298-
false => Op::branch_i32_not_eq_si(condition, 0, offset),
1299-
};
1300-
self.push_instr(instr, FuelCostsProvider::base)?;
1281+
let fuel_pos = self.stack.consume_fuel_instr();
1282+
self.instrs.encode_branch(
1283+
label,
1284+
|offset| match branch_eqz {
1285+
true => Op::branch_i32_eq_si(condition, 0, offset),
1286+
false => Op::branch_i32_not_eq_si(condition, 0, offset),
1287+
},
1288+
fuel_pos,
1289+
FuelCostsProvider::base,
1290+
)?;
13011291
Ok(())
13021292
}
13031293

@@ -1343,11 +1333,17 @@ impl FuncTranslator {
13431333
}
13441334
},
13451335
};
1346-
let offset = self.labels.try_resolve_label(label, instr)?;
1347-
let Some(fused_cmp_branch) = cmp_op.try_into_cmp_branch_instr(offset) else {
1336+
let Some(fused_cmp_branch) = cmp_op.try_into_cmp_branch_instr(BranchOffset::uninit())
1337+
else {
13481338
return Ok(false);
13491339
};
1350-
self.instrs.replace_staged(fused_cmp_branch)?;
1340+
let (fuel_pos, _) = self.instrs.drop_staged();
1341+
self.instrs.encode_branch(
1342+
label,
1343+
|offset| fused_cmp_branch.with_branch_offset(offset),
1344+
fuel_pos,
1345+
FuelCostsProvider::base,
1346+
)?;
13511347
Ok(true)
13521348
}
13531349

0 commit comments

Comments
 (0)