Skip to content

Commit 1d11e1e

Browse files
committed
WIP computed gotos-ish?
1 parent 7df2163 commit 1d11e1e

File tree

1 file changed

+113
-36
lines changed

1 file changed

+113
-36
lines changed

vm/src/frame.rs

Lines changed: 113 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -367,13 +367,19 @@ impl ExecutingFrame<'_> {
367367
}
368368
}
369369

370+
#[inline(always)]
371+
fn fetch_next_instr(&mut self) -> usize {
372+
let idx = self.lasti() as usize;
373+
self.update_lasti(|i| *i += 1);
374+
idx
375+
}
376+
370377
fn run(&mut self, vm: &VirtualMachine) -> PyResult<ExecutionResult> {
371378
flame_guard!(format!("Frame::run({})", self.code.obj_name));
372379
// Execute until return or exception:
373380
let instrs = &self.code.instructions;
374381
loop {
375-
let idx = self.lasti() as usize;
376-
self.update_lasti(|i| *i += 1);
382+
let idx = self.fetch_next_instr();
377383
let instr = &instrs[idx];
378384
let result = self.execute_instruction(instr, vm);
379385
match result {
@@ -510,35 +516,72 @@ impl ExecutingFrame<'_> {
510516
trace!("=======");
511517
}
512518

513-
macro_rules! fn_dispatch {
514-
(args($dT:ty => $retT:ty ,$arg1:ident: $argT1:ty, $arg2:ident: $argT2:ty), match ($d:expr) { $($p:pat => $body:block)* }) => {{
515-
let f = match $d {
516-
$($p => {
517-
fn match_arm(x: $dT, #[allow(unused)] $arg1: $argT1, #[allow(unused)] $arg2: $argT2) -> $retT {
518-
match x {
519-
$p => $body
520-
_ => unsafe { std::hint::unreachable_unchecked() }
519+
macro_rules! get_instr_fn_ptr {
520+
(fn($insT:ty, $arg1:ident: $arg1T:ty, $arg2:ident: $arg2T:ty$(,)?) -> $retT:ty, match ($ins:expr) { $($p:pat => $body:block)* }) => {{
521+
#[inline(always)]
522+
fn get_fn(ins: $insT) -> fn($insT, $arg1T, $arg2T) -> $retT {
523+
#[allow(unused)]
524+
match ins {
525+
$($p => {
526+
fn match_arm(x: $insT, $arg1: $arg1T, $arg2: $arg2T) -> $retT {
527+
let ret = (|| match x {
528+
$p => $body
529+
_ => unsafe { std::hint::unreachable_unchecked() }
530+
})();
531+
match ret {
532+
Ok(None) => {
533+
drop(ret);
534+
let idx = $arg1.fetch_next_instr();
535+
$arg2.check_signals()?;
536+
let ins = &$arg1.code.instructions[idx];
537+
get_fn(ins)(ins, $arg1, $arg2)
538+
}
539+
x => x
540+
}
521541
}
522-
}
523-
match_arm as fn($dT, $argT1, $argT2) -> $retT
524-
})*
525-
};
526-
f($d, $arg1, $arg2)
542+
match_arm as _
543+
})*
544+
}
545+
}
546+
get_fn($ins)
527547
}}
528548
}
529549

530550
let zelf = self;
531-
fn_dispatch!(args(&bytecode::Instruction => FrameResult, zelf: &mut ExecutingFrame, vm: &VirtualMachine),
532-
match (instruction) {
551+
552+
macro_rules! fn_dispatch {
553+
(match ($ins:expr, &mut *$z:ident, $v:ident).0 { $($p:pat => $body:block)* }) => {{
554+
let f = get_instr_fn_ptr!(
555+
fn(
556+
&bytecode::Instruction,
557+
$z: &mut ExecutingFrame,
558+
$v: &VirtualMachine,
559+
) -> FrameResult,
560+
match ($ins) { $($p => $body)* }
561+
);
562+
f($ins, zelf, vm)
563+
}};
564+
}
565+
// macro_rules! fn_dispatch {
566+
// ($e:expr) => {
567+
// $e
568+
// };
569+
// }
570+
571+
fn_dispatch!(match (instruction, &mut *zelf, vm).0 {
533572
bytecode::Instruction::LoadConst { idx } => {
534573
zelf.push_value(zelf.code.constants[*idx as usize].0.clone());
535574
Ok(None)
536575
}
537576
bytecode::Instruction::ImportName { idx } => {
538577
zelf.import(vm, Some(zelf.code.names[*idx as usize].clone()))
539578
}
540-
bytecode::Instruction::ImportNameless => { zelf.import(vm, None) }
541-
bytecode::Instruction::ImportStar => { zelf.import_star(vm) }
579+
bytecode::Instruction::ImportNameless => {
580+
zelf.import(vm, None)
581+
}
582+
bytecode::Instruction::ImportStar => {
583+
zelf.import_star(vm)
584+
}
542585
bytecode::Instruction::ImportFrom { idx } => {
543586
let obj = zelf.import_from(vm, *idx)?;
544587
zelf.push_value(obj);
@@ -652,9 +695,15 @@ impl ExecutingFrame<'_> {
652695
zelf.push_value(value.into_object());
653696
Ok(None)
654697
}
655-
bytecode::Instruction::Subscript => { zelf.execute_subscript(vm) }
656-
bytecode::Instruction::StoreSubscript => { zelf.execute_store_subscript(vm) }
657-
bytecode::Instruction::DeleteSubscript => { zelf.execute_delete_subscript(vm) }
698+
bytecode::Instruction::Subscript => {
699+
zelf.execute_subscript(vm)
700+
}
701+
bytecode::Instruction::StoreSubscript => {
702+
zelf.execute_store_subscript(vm)
703+
}
704+
bytecode::Instruction::DeleteSubscript => {
705+
zelf.execute_delete_subscript(vm)
706+
}
658707
bytecode::Instruction::Pop => {
659708
// Pop value from stack and ignore.
660709
zelf.pop_value();
@@ -667,7 +716,9 @@ impl ExecutingFrame<'_> {
667716
zelf.push_value(value);
668717
Ok(None)
669718
}
670-
bytecode::Instruction::Rotate { amount } => { zelf.execute_rotate(*amount) }
719+
bytecode::Instruction::Rotate { amount } => {
720+
zelf.execute_rotate(*amount)
721+
}
671722
bytecode::Instruction::BuildString { size } => {
672723
let s = zelf
673724
.pop_multiple(*size as usize)
@@ -712,8 +763,12 @@ impl ExecutingFrame<'_> {
712763
size,
713764
unpack,
714765
for_call,
715-
} => { zelf.execute_build_map(vm, *size, *unpack, *for_call) }
716-
bytecode::Instruction::BuildSlice { step } => { zelf.execute_build_slice(vm, *step) }
766+
} => {
767+
zelf.execute_build_map(vm, *size, *unpack, *for_call)
768+
}
769+
bytecode::Instruction::BuildSlice { step } => {
770+
zelf.execute_build_slice(vm, *step)
771+
}
717772
bytecode::Instruction::ListAppend { i } => {
718773
let list_obj = zelf.nth_value(*i);
719774
let item = zelf.pop_value();
@@ -741,15 +796,27 @@ impl ExecutingFrame<'_> {
741796
PyDictRef::try_from_object(vm, dict_obj)?.set_item(key, value, vm)?;
742797
Ok(None)
743798
}
744-
bytecode::Instruction::BinaryOperation { op } => { zelf.execute_binop(vm, *op) }
799+
bytecode::Instruction::BinaryOperation { op } => {
800+
zelf.execute_binop(vm, *op)
801+
}
745802
bytecode::Instruction::BinaryOperationInplace { op } => {
746803
zelf.execute_binop_inplace(vm, *op)
747804
}
748-
bytecode::Instruction::LoadAttr { idx } => { zelf.load_attr(vm, *idx) }
749-
bytecode::Instruction::StoreAttr { idx } => { zelf.store_attr(vm, *idx) }
750-
bytecode::Instruction::DeleteAttr { idx } => { zelf.delete_attr(vm, *idx) }
751-
bytecode::Instruction::UnaryOperation { ref op } => { zelf.execute_unop(vm, op) }
752-
bytecode::Instruction::CompareOperation { ref op } => { zelf.execute_compare(vm, op) }
805+
bytecode::Instruction::LoadAttr { idx } => {
806+
zelf.load_attr(vm, *idx)
807+
}
808+
bytecode::Instruction::StoreAttr { idx } => {
809+
zelf.store_attr(vm, *idx)
810+
}
811+
bytecode::Instruction::DeleteAttr { idx } => {
812+
zelf.delete_attr(vm, *idx)
813+
}
814+
bytecode::Instruction::UnaryOperation { ref op } => {
815+
zelf.execute_unop(vm, op)
816+
}
817+
bytecode::Instruction::CompareOperation { ref op } => {
818+
zelf.execute_compare(vm, op)
819+
}
753820
bytecode::Instruction::ReturnValue => {
754821
let value = zelf.pop_value();
755822
zelf.unwind_blocks(vm, UnwindReason::Returning { value })
@@ -763,7 +830,9 @@ impl ExecutingFrame<'_> {
763830
};
764831
Ok(Some(ExecutionResult::Yield(value)))
765832
}
766-
bytecode::Instruction::YieldFrom => { zelf.execute_yield_from(vm) }
833+
bytecode::Instruction::YieldFrom => {
834+
zelf.execute_yield_from(vm)
835+
}
767836
bytecode::Instruction::SetupAnnotation => {
768837
if !zelf.locals.contains_key("__annotations__", vm) {
769838
zelf.locals
@@ -930,8 +999,12 @@ impl ExecutingFrame<'_> {
930999
Err(exc.downcast().unwrap())
9311000
}
9321001
}
933-
bytecode::Instruction::ForIter { target } => { zelf.execute_for_iter(vm, *target) }
934-
bytecode::Instruction::MakeFunction(flags) => { zelf.execute_make_function(vm, *flags) }
1002+
bytecode::Instruction::ForIter { target } => {
1003+
zelf.execute_for_iter(vm, *target)
1004+
}
1005+
bytecode::Instruction::MakeFunction(flags) => {
1006+
zelf.execute_make_function(vm, *flags)
1007+
}
9351008
bytecode::Instruction::CallFunctionPositional { nargs } => {
9361009
let args = zelf.collect_positional_args(*nargs);
9371010
zelf.execute_call(args, vm)
@@ -1015,9 +1088,13 @@ impl ExecutingFrame<'_> {
10151088
Ok(None)
10161089
}
10171090

1018-
bytecode::Instruction::Raise { kind } => { zelf.execute_raise(vm, *kind) }
1091+
bytecode::Instruction::Raise { kind } => {
1092+
zelf.execute_raise(vm, *kind)
1093+
}
10191094

1020-
bytecode::Instruction::Break => { zelf.unwind_blocks(vm, UnwindReason::Break) }
1095+
bytecode::Instruction::Break => {
1096+
zelf.unwind_blocks(vm, UnwindReason::Break)
1097+
}
10211098
bytecode::Instruction::Continue { target } => {
10221099
zelf.unwind_blocks(vm, UnwindReason::Continue { target: *target })
10231100
}

0 commit comments

Comments
 (0)