1+ use std:: collections:: HashMap ;
12use cranelift:: prelude:: * ;
23use num_traits:: cast:: ToPrimitive ;
3- use rustpython_bytecode:: bytecode:: { Constant , Instruction } ;
4+ use rustpython_bytecode:: bytecode:: { BinaryOperator , Constant , Instruction , NameScope } ;
45
56use super :: JITCompileError ;
67
78pub struct FunctionCompiler < ' a , ' b > {
89 builder : & ' a mut FunctionBuilder < ' b > ,
910 stack : Vec < Value > ,
11+ variables : HashMap < String , Variable >
1012}
1113
1214impl < ' a , ' b > FunctionCompiler < ' a , ' b > {
1315 pub fn new ( builder : & ' a mut FunctionBuilder < ' b > ) -> FunctionCompiler < ' a , ' b > {
1416 FunctionCompiler {
1517 builder,
1618 stack : Vec :: new ( ) ,
19+ variables : HashMap :: new ( )
1720 }
1821 }
1922
2023 pub fn add_instruction ( & mut self , instruction : & Instruction ) -> Result < ( ) , JITCompileError > {
2124 match instruction {
25+ Instruction :: LoadName {
26+ name,
27+ scope : NameScope :: Local
28+ } => {
29+ let var = self . variables . get ( name) . ok_or ( JITCompileError :: BadBytecode ) ?;
30+ self . stack . push ( self . builder . use_var ( * var) ) ;
31+ Ok ( ( ) )
32+ }
33+ Instruction :: StoreName {
34+ name,
35+ scope : NameScope :: Local
36+ } => {
37+ let var = match self . variables . get ( name) {
38+ Some ( var) => * var,
39+ None => {
40+ let var = Variable :: new ( self . variables . len ( ) ) ;
41+ self . variables . insert ( name. clone ( ) , var) ;
42+ self . builder . declare_var ( var, types:: I64 ) ;
43+ var
44+ }
45+ } ;
46+ self . builder . def_var ( var, self . stack . pop ( ) . ok_or ( JITCompileError :: BadBytecode ) ?) ;
47+ Ok ( ( ) )
48+ }
2249 Instruction :: LoadConst {
2350 value : Constant :: Integer { value } ,
2451 } => {
@@ -35,6 +62,28 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
3562 . return_ ( & [ self . stack . pop ( ) . ok_or ( JITCompileError :: BadBytecode ) ?] ) ;
3663 Ok ( ( ) )
3764 }
65+ Instruction :: BinaryOperation {
66+ op,
67+ ..
68+ } => {
69+ let a = self . stack . pop ( ) . ok_or ( JITCompileError :: BadBytecode ) ?;
70+ let b = self . stack . pop ( ) . ok_or ( JITCompileError :: BadBytecode ) ?;
71+ match op {
72+ BinaryOperator :: Add => {
73+ let ( out, carry) = self . builder . ins ( ) . iadd_ifcout ( a, b) ;
74+ self . builder . ins ( ) . trapif ( IntCC :: Overflow , carry, TrapCode :: IntegerOverflow ) ;
75+ self . stack . push ( out) ;
76+ Ok ( ( ) )
77+ }
78+ BinaryOperator :: Subtract => {
79+ let ( out, carry) = self . builder . ins ( ) . isub_ifbout ( a, b) ;
80+ self . builder . ins ( ) . trapif ( IntCC :: Overflow , carry, TrapCode :: IntegerOverflow ) ;
81+ self . stack . push ( out) ;
82+ Ok ( ( ) )
83+ }
84+ _ => Err ( JITCompileError :: NotSupported ) ,
85+ }
86+ }
3887 _ => Err ( JITCompileError :: NotSupported ) ,
3988 }
4089 }
0 commit comments