Skip to content

Commit 2c37b04

Browse files
committed
chore(interpreter): refactor lowerer to accomodate for PlaceTy
1 parent cfc43e1 commit 2c37b04

2 files changed

Lines changed: 125 additions & 89 deletions

File tree

interpreter/src/ir/lower.rs

Lines changed: 55 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ use crate::{
1919
CodeRange,
2020
ir::{
2121
Instruction, IxWidth, Label, NonLocal, PlaceTy, Reg, RegWidth,
22-
lower::utils::{CallConv, LinearRegRange, Operand, RegAlloc, RtType, TypedArg, var_index},
22+
lower::utils::{
23+
CallConv, LinearRegRange, Operand, RegAlloc, RtType, TypedArg, TypedPlace, var_index,
24+
},
2325
},
2426
vm::{Consts, Function, SymbolTable, types::Value},
2527
};
@@ -114,7 +116,7 @@ impl<'a> CodeGen<'a> {
114116
self.lower_body(actions);
115117
} else {
116118
self.scoped_reg(|this, reg| {
117-
let (arg, ty) = TypedArg::new_imm(0).into();
119+
let (arg, ty) = TypedArg::new_imm(0).into_arg();
118120
this.emit(Instruction::Record { dest: reg, arg, ty });
119121

120122
this.emit(Instruction::OutputCall {
@@ -327,14 +329,14 @@ impl<'a> CodeGen<'a> {
327329
this.scoped_reg(|this, dest| {
328330
this.lower_expr_into(expr, dest);
329331

330-
let (arg, ty) = TypedArg::new_reg(dest).into();
332+
let (arg, ty) = TypedArg::new_reg(dest).into_arg();
331333
this.emit(Instruction::Exit { arg, ty });
332334
});
333335
});
334336
}
335337
Statement::Exit(None, metadata) => {
336338
self.with_metadata(*metadata, |this| {
337-
let (arg, ty) = TypedArg::new_imm(0).into();
339+
let (arg, ty) = TypedArg::new_imm(0).into_arg();
338340
this.emit(Instruction::Exit { arg, ty });
339341
});
340342
}
@@ -343,7 +345,7 @@ impl<'a> CodeGen<'a> {
343345
this.scoped_reg(|this, dest| {
344346
this.lower_expr_into(expr, dest);
345347

346-
let (arg, ty) = TypedArg::new_reg(dest).into();
348+
let (arg, ty) = TypedArg::new_reg(dest).into_arg();
347349
this.emit(Instruction::Return { arg, ty });
348350
});
349351
});
@@ -424,17 +426,17 @@ impl<'a> CodeGen<'a> {
424426
case: &Atom<'_>,
425427
case_ix: usize,
426428
) -> (Label, usize) {
427-
let (lhs, tyl) = TypedArg::new_reg(scr).into();
429+
let (lhs, tyl) = TypedArg::new_reg(scr).into_arg();
428430

429431
match case {
430432
Atom::Regex(r) | Atom::TypedRegex(r) => {
431433
let buf = &*self.arena.alloc_slice_copy(r.as_ref());
432-
let (rhs, tyr) = TypedArg::new_cnt(self, Value::Regex(buf.into())).into();
434+
let (rhs, tyr) = TypedArg::new_cnt(self, Value::Regex(buf.into())).into_arg();
433435
self.emit(Instruction::Matches { dest: cmp, lhs, rhs, tyl, tyr });
434436
}
435437
atom => {
436438
let case_val = self.lower_atom(atom);
437-
let (rhs, tyr) = case_val.to_arg().into();
439+
let (rhs, tyr) = case_val.to_arg().into_arg();
438440
self.emit(Instruction::Eq { dest: cmp, lhs, rhs, tyl, tyr });
439441
case_val.free(self);
440442
}
@@ -497,8 +499,8 @@ impl<'a> CodeGen<'a> {
497499
}
498500
Atom::Regex(r) => {
499501
let buf = &*self.arena.alloc_slice_copy(r.as_ref());
500-
let (rhs, tyr) = TypedArg::new_cnt(self, Value::Regex(buf.into())).into();
501-
let (lhs, tyl) = TypedArg::new_imm(0).into();
502+
let (rhs, tyr) = TypedArg::new_cnt(self, Value::Regex(buf.into())).into_arg();
503+
let (lhs, tyl) = TypedArg::new_imm(0).into_arg();
502504
self.emit(Instruction::Matches { dest, rhs, lhs, tyr, tyl });
503505
TypedArg::new_reg(dest)
504506
}
@@ -508,7 +510,7 @@ impl<'a> CodeGen<'a> {
508510

509511
fn lower_atom_into(&mut self, atom: &Atom, dest: Reg) {
510512
let t_arg = self.lower_atom_arg(atom, dest);
511-
let (arg, ty) = t_arg.into();
513+
let (arg, ty) = t_arg.into_arg();
512514

513515
if t_arg.as_reg().is_none_or(|reg| reg != dest) {
514516
self.emit(Instruction::CopyP { dest, arg, ty });
@@ -565,7 +567,7 @@ impl<'a> CodeGen<'a> {
565567
};
566568

567569
this.scoped_reg(|this, lhs_reg| {
568-
let lhs = this.load_place(lhs_reg, place);
570+
let lhs = this.load_place(lhs_reg, place).into();
569571
let rhs = val.to_arg();
570572

571573
this.emit(Instruction::from_binary(bin_op, dest, lhs, rhs));
@@ -578,8 +580,7 @@ impl<'a> CodeGen<'a> {
578580
ExprNode::UnaryPlaceOperation(op, place)
579581
if matches!(place, Place::Record(_) | Place::Variable(_)) =>
580582
{
581-
let (arg, ty) = this.load_place(dest, place).into();
582-
let ty = ty.try_into().unwrap();
583+
let (arg, ty) = this.load_place(dest, place).into_place();
583584
match op {
584585
UnaryPlaceOperator::IncrementL => {
585586
this.emit(Instruction::IncrementPre { dest, arg, ty });
@@ -598,7 +599,7 @@ impl<'a> CodeGen<'a> {
598599
// Unoptimized path for values in arrays.
599600
ExprNode::UnaryPlaceOperation(op, place) => {
600601
// Note: val may alias with dest.
601-
let lhs = this.load_place(dest, place);
602+
let lhs = this.load_place(dest, place).into();
602603
let one = TypedArg::new_imm(1);
603604

604605
match op {
@@ -663,16 +664,18 @@ impl<'a> CodeGen<'a> {
663664
&ExprNode::IndirectCall(place, ref args) => {
664665
let range = this.gen_call_convention(RtType::Any, args);
665666
let (start, end) = range.as_range();
666-
let (name, ty) = this.load_place(dest, &Place::Variable(place)).into();
667+
let (name, ty) =
668+
this.load_place(dest, &Place::Variable(place)).into_arg();
667669
this.emit(Instruction::IndirectCall { dest, start, end, name, ty });
668670
this.regs.free_many(range);
669671
}
670672
&ExprNode::ChainedIndex(var, ref indices) => {
671-
let (mut arg, ty) = match &var {
672-
Variable::User(ident) => TypedArg::new_ua(this, ident).into(),
673-
var => TypedArg::new_ia(var).into(),
673+
let (mut arg, mut ty) = match &var {
674+
Variable::User(ident) => {
675+
TypedPlace::new_ua(this, ident).into_place()
676+
}
677+
var => TypedPlace::new_ia(var).into_place(),
674678
};
675-
let mut ty = ty.try_into().unwrap();
676679

677680
for (i, index) in indices.iter().enumerate() {
678681
let range = this.gen_call_convention(RtType::Scalar, index);
@@ -683,8 +686,7 @@ impl<'a> CodeGen<'a> {
683686
Instruction::LoadM { dest, arg, start, end, ty }
684687
};
685688
this.emit(instr);
686-
let (arg_n, ty_n) = TypedArg::new_reg(dest).into();
687-
(arg, ty) = (arg_n, ty_n.try_into().unwrap());
689+
(arg, ty) = TypedPlace::new_reg(dest).into_place();
688690
this.regs.free_many(range);
689691
}
690692
}
@@ -695,48 +697,45 @@ impl<'a> CodeGen<'a> {
695697
}
696698
}
697699

698-
fn load_place(&mut self, dest: Reg, place: &Place<'_>) -> TypedArg {
700+
fn load_place(&mut self, dest: Reg, place: &Place<'_>) -> TypedPlace {
699701
match place {
700702
Place::Record(_) => {
701703
todo!()
702704
}
703-
Place::Variable(Variable::User(ident)) => TypedArg::new_us(self, ident),
704-
Place::Variable(var) => TypedArg::new_is(var),
705+
Place::Variable(Variable::User(ident)) => TypedPlace::new_us(self, ident),
706+
Place::Variable(var) => TypedPlace::new_is(var),
705707
Place::Index(var, index) => self.load_index(dest, var, index),
706708
Place::ChainedIndex(_, _) => todo!(),
707709
}
708710
}
709711

710-
fn load_index(&mut self, dest: Reg, var: &Variable<'_>, index: &[Expr<'_>]) -> TypedArg {
712+
fn load_index(&mut self, dest: Reg, var: &Variable<'_>, index: &[Expr<'_>]) -> TypedPlace {
711713
let range = self.gen_call_convention(RtType::Scalar, index);
712714
let (start, end) = range.as_range();
713715
if let Variable::User(ident) = var {
714-
let (arg, ty) = TypedArg::new_ua(self, ident).into();
715-
let ty = ty.try_into().unwrap();
716+
let (arg, ty) = TypedPlace::new_ua(self, ident).into_place();
716717
self.emit(Instruction::LoadA { dest, arg, ty, start, end });
717718
} else {
718-
let (arg, ty) = TypedArg::new_ia(var).into();
719-
let ty = ty.try_into().unwrap();
719+
let (arg, ty) = TypedPlace::new_ia(var).into_place();
720720
self.emit(Instruction::LoadA { dest, arg, ty, start, end });
721721
}
722722
self.regs.free_many(range);
723723
// Element value was written to `dest`; subsequent ops must use the register.
724-
TypedArg::new_reg(dest)
724+
TypedPlace::new_reg(dest)
725725
}
726726

727727
fn store_place(&mut self, place: &Place<'_>, dest: Reg, src: TypedArg) {
728-
let (arg, ty) = src.into();
728+
let (arg, ty) = src.into_arg();
729729
match place {
730730
Place::Record(expr) => {
731731
let rec = self.lower_expr(expr);
732-
let (src, tys) = rec.to_arg().into();
732+
let (src, tys) = rec.to_arg().into_arg();
733733
self.emit(Instruction::StoreR { dest, src, tys, arg, ty });
734734
rec.free(self);
735735
}
736736
Place::Variable(Variable::User(ident)) => {
737-
let t_arg = TypedArg::new_us(self, ident);
738-
let (var, ty_place) = t_arg.into();
739-
let ty_place = ty_place.try_into().unwrap();
737+
let t_arg = TypedPlace::new_us(self, ident);
738+
let (var, ty_place) = t_arg.into_place();
740739

741740
if t_arg.as_reg().is_some_and(|reg| reg == dest) {
742741
return; // Value already on destination.
@@ -756,45 +755,40 @@ impl<'a> CodeGen<'a> {
756755
self.emit(Instruction::StoreS { dest, ty_place: PlaceTy::IsVal, var, arg, ty });
757756
}
758757
Place::Index(Variable::User(ident), index) => {
759-
let (lhs, tyl) = TypedArg::new_ua(self, ident).into();
760-
let tyl = tyl.try_into().unwrap();
761-
let (rhs, tyr) = src.into();
758+
let (lhs, tyl) = TypedPlace::new_ua(self, ident).into_place();
759+
let (rhs, tyr) = src.into_arg();
762760
let range = self.gen_call_convention(RtType::Scalar, index);
763761
let (start, end) = range.as_range();
764762
self.emit(Instruction::StoreA { dest, lhs, rhs, start, end, tyl, tyr });
765763
self.regs.free_many(range);
766764
}
767765
Place::Index(var, index) => {
768-
let (lhs, tyl) = TypedArg::new_ia(var).into();
769-
let tyl = tyl.try_into().unwrap();
770-
let (rhs, tyr) = src.into();
766+
let (lhs, tyl) = TypedPlace::new_ia(var).into_place();
767+
let (rhs, tyr) = src.into_arg();
771768
let range = self.gen_call_convention(RtType::Scalar, index);
772769
let (start, end) = range.as_range();
773770
self.emit(Instruction::StoreA { dest, lhs, rhs, start, end, tyl, tyr });
774771
self.regs.free_many(range);
775772
}
776773
&Place::ChainedIndex(var, ref indices) => {
777-
let (mut arg, ty) = match &var {
778-
Variable::User(ident) => TypedArg::new_ua(self, ident).into(),
779-
var => TypedArg::new_ia(var).into(),
774+
let (mut arg, mut ty) = match &var {
775+
Variable::User(ident) => TypedPlace::new_ua(self, ident).into_place(),
776+
var => TypedPlace::new_ia(var).into_place(),
780777
};
781-
let mut ty = ty.try_into().unwrap();
782778
let last = indices.len() - 1;
783779

784780
for index in &indices[..last] {
785781
let range = self.gen_call_convention(RtType::Scalar, index);
786782
let (start, end) = range.as_range();
787783
self.emit(Instruction::LoadM { dest, arg, start, end, ty });
788-
let (arg_n, ty_n) = TypedArg::new_reg(dest).into();
789-
(arg, ty) = (arg_n, ty_n.try_into().unwrap());
784+
(arg, ty) = TypedPlace::new_reg(dest).into_place();
790785
self.regs.free_many(range);
791786
}
792787

793788
let range = self.gen_call_convention(RtType::Scalar, &indices[last]);
794789
let (start, end) = range.as_range();
795-
let (lhs, tyl) = TypedArg::new_reg(dest).into();
796-
let (rhs, tyr) = src.into();
797-
let tyl = tyl.try_into().unwrap();
790+
let (lhs, tyl) = TypedPlace::new_reg(dest).into_place();
791+
let (rhs, tyr) = src.into_arg();
798792
self.emit(Instruction::StoreA { dest, lhs, rhs, start, end, tyl, tyr });
799793
self.regs.free_many(range);
800794
}
@@ -810,14 +804,14 @@ impl<'a> CodeGen<'a> {
810804
});
811805
self.bc.nth(if_label).push_end_label();
812806
self.emit_jump(|this| {
813-
let (arg, ty) = TypedArg::new_imm(0).into();
807+
let (arg, ty) = TypedArg::new_imm(0).into_arg();
814808
this.emit(Instruction::CopyP { dest, arg, ty });
815809
});
816810
}
817811

818812
fn lower_or_into(&mut self, lhs: &Expr<'_>, rhs: &Expr<'_>, dest: Reg) {
819813
let (if_label, _) = self.emit_branch(lhs, |this| {
820-
let (arg, ty) = TypedArg::new_imm(1).into();
814+
let (arg, ty) = TypedArg::new_imm(1).into_arg();
821815
this.emit(Instruction::CopyP { dest, arg, ty });
822816
});
823817
self.bc.nth(if_label).push_end_label();
@@ -831,10 +825,10 @@ impl<'a> CodeGen<'a> {
831825

832826
/// Coerce `src` to an integer truth value (0 or 1), as gawk does via `mkbool()`.
833827
fn truthify(&mut self, dest: Reg, src: Reg) {
834-
let (arg, ty) = TypedArg::new_reg(src).into();
828+
let (arg, ty) = TypedArg::new_reg(src).into_arg();
835829
self.emit(Instruction::Negation { dest, arg, ty });
836830

837-
let (arg, ty) = TypedArg::new_reg(dest).into();
831+
let (arg, ty) = TypedArg::new_reg(dest).into_arg();
838832
self.emit(Instruction::Negation { dest, arg, ty });
839833
}
840834

@@ -886,13 +880,11 @@ impl<'a> CodeGen<'a> {
886880
// Bypass Copy instruction for variables here, so we do not get
887881
// scalar context shenanigans in the VM.
888882
if let &Expr::Leaf(Atom::Variable(var), _) = arg {
889-
let (arg, ty) = this.load_place(dest, &Place::Variable(var)).into();
883+
let (arg, ty) = this.load_place(dest, &Place::Variable(var)).into_place();
890884
let instr = match rt_ty {
891-
RtType::Scalar => Instruction::CopyS { dest, arg, ty },
892-
RtType::Array => {
893-
Instruction::CopyA { dest, arg, ty: ty.try_into().unwrap() }
894-
}
895-
RtType::Any => Instruction::CopyP { dest, arg, ty },
885+
RtType::Scalar => Instruction::CopyS { dest, arg, ty: *ty },
886+
RtType::Array => Instruction::CopyA { dest, arg, ty },
887+
RtType::Any => Instruction::CopyP { dest, arg, ty: *ty },
896888
};
897889
this.emit(instr);
898890
} else {
@@ -1015,7 +1007,7 @@ impl<'a> Bytecode<'a> {
10151007

10161008
impl Instruction {
10171009
pub(super) fn from_unary(op: UnaryOperator, dest: Reg, arg: TypedArg) -> Self {
1018-
let (arg, ty) = arg.into();
1010+
let (arg, ty) = arg.into_arg();
10191011
match op {
10201012
UnaryOperator::Record => Self::Record { dest, arg, ty },
10211013
UnaryOperator::Negation => Self::Negation { dest, arg, ty },
@@ -1025,7 +1017,7 @@ impl Instruction {
10251017
}
10261018

10271019
pub(super) fn from_binary(op: BinaryOperator, dest: Reg, lhs: TypedArg, rhs: TypedArg) -> Self {
1028-
let ((lhs, tyl), (rhs, tyr)) = (lhs.into(), rhs.into());
1020+
let ((lhs, tyl), (rhs, tyr)) = (lhs.into_arg(), rhs.into_arg());
10291021
match op {
10301022
BinaryOperator::Concat => Self::Concat { dest, lhs, rhs, tyl, tyr },
10311023
BinaryOperator::Eq => Self::Eq { dest, lhs, rhs, tyl, tyr },

0 commit comments

Comments
 (0)