@@ -5,7 +5,7 @@ use rustpython_compiler_core::bytecode::{
5
5
OpArg , OpArgState , UnaryOperator ,
6
6
} ;
7
7
use std:: collections:: HashMap ;
8
-
8
+ use cranelift :: codegen :: ir :: FuncRef ;
9
9
use super :: { JitCompileError , JitSig , JitType } ;
10
10
11
11
#[ repr( u16 ) ]
@@ -27,6 +27,7 @@ enum JitValue {
27
27
Bool ( Value ) ,
28
28
None ,
29
29
Tuple ( Vec < JitValue > ) ,
30
+ FuncRef ( FuncRef ) ,
30
31
}
31
32
32
33
impl JitValue {
@@ -43,14 +44,14 @@ impl JitValue {
43
44
JitValue :: Int ( _) => Some ( JitType :: Int ) ,
44
45
JitValue :: Float ( _) => Some ( JitType :: Float ) ,
45
46
JitValue :: Bool ( _) => Some ( JitType :: Bool ) ,
46
- JitValue :: None | JitValue :: Tuple ( _) => None ,
47
+ JitValue :: None | JitValue :: Tuple ( _) | JitValue :: FuncRef ( _ ) => None ,
47
48
}
48
49
}
49
50
50
51
fn into_value ( self ) -> Option < Value > {
51
52
match self {
52
53
JitValue :: Int ( val) | JitValue :: Float ( val) | JitValue :: Bool ( val) => Some ( val) ,
53
- JitValue :: None | JitValue :: Tuple ( _) => None ,
54
+ JitValue :: None | JitValue :: Tuple ( _) | JitValue :: FuncRef ( _ ) => None ,
54
55
}
55
56
}
56
57
}
@@ -68,6 +69,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
68
69
builder : & ' a mut FunctionBuilder < ' b > ,
69
70
num_variables : usize ,
70
71
arg_types : & [ JitType ] ,
72
+ ret_type : Option < JitType > ,
71
73
entry_block : Block ,
72
74
) -> FunctionCompiler < ' a , ' b > {
73
75
let mut compiler = FunctionCompiler {
@@ -77,7 +79,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
77
79
label_to_block : HashMap :: new ( ) ,
78
80
sig : JitSig {
79
81
args : arg_types. to_vec ( ) ,
80
- ret : None ,
82
+ ret : ret_type ,
81
83
} ,
82
84
} ;
83
85
let params = compiler. builder . func . dfg . block_params ( entry_block) . to_vec ( ) ;
@@ -132,7 +134,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
132
134
}
133
135
JitValue :: Bool ( val) => Ok ( val) ,
134
136
JitValue :: None => Ok ( self . builder . ins ( ) . iconst ( types:: I8 , 0 ) ) ,
135
- JitValue :: Tuple ( _) => Err ( JitCompileError :: NotSupported ) ,
137
+ JitValue :: Tuple ( _) | JitValue :: FuncRef ( _ ) => Err ( JitCompileError :: NotSupported ) ,
136
138
}
137
139
}
138
140
@@ -146,6 +148,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
146
148
147
149
pub fn compile < C : bytecode:: Constant > (
148
150
& mut self ,
151
+ func_ref : FuncRef ,
149
152
bytecode : & CodeObject < C > ,
150
153
) -> Result < ( ) , JitCompileError > {
151
154
// TODO: figure out if this is sufficient -- previously individual labels were associated
@@ -177,7 +180,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
177
180
continue ;
178
181
}
179
182
180
- self . add_instruction ( instruction , arg , & bytecode . constants ) ?;
183
+ self . add_instruction ( func_ref , bytecode , instruction , arg ) ?;
181
184
}
182
185
183
186
Ok ( ( ) )
@@ -229,9 +232,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
229
232
230
233
pub fn add_instruction < C : bytecode:: Constant > (
231
234
& mut self ,
235
+ func_ref : FuncRef ,
236
+ bytecode : & CodeObject < C > ,
232
237
instruction : Instruction ,
233
238
arg : OpArg ,
234
- constants : & [ C ] ,
235
239
) -> Result < ( ) , JitCompileError > {
236
240
match instruction {
237
241
Instruction :: ExtendedArg => Ok ( ( ) ) ,
@@ -282,7 +286,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
282
286
self . store_variable ( idx. get ( arg) , val)
283
287
}
284
288
Instruction :: LoadConst { idx } => {
285
- let val = self . prepare_const ( constants[ idx. get ( arg) as usize ] . borrow_constant ( ) ) ?;
289
+ let val = self . prepare_const ( bytecode . constants [ idx. get ( arg) as usize ] . borrow_constant ( ) ) ?;
286
290
self . stack . push ( val) ;
287
291
Ok ( ( ) )
288
292
}
@@ -311,7 +315,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
311
315
self . return_value ( val)
312
316
}
313
317
Instruction :: ReturnConst { idx } => {
314
- let val = self . prepare_const ( constants[ idx. get ( arg) as usize ] . borrow_constant ( ) ) ?;
318
+ let val = self . prepare_const ( bytecode . constants [ idx. get ( arg) as usize ] . borrow_constant ( ) ) ?;
315
319
self . return_value ( val)
316
320
}
317
321
Instruction :: CompareOperation { op, .. } => {
@@ -508,6 +512,36 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
508
512
// TODO: block support
509
513
Ok ( ( ) )
510
514
}
515
+ Instruction :: LoadGlobal ( idx) => {
516
+ let name = & bytecode. names [ idx. get ( arg) as usize ] ;
517
+
518
+ if name. as_ref ( ) != bytecode. obj_name . as_ref ( ) {
519
+ Err ( JitCompileError :: NotSupported )
520
+ } else {
521
+ self . stack . push ( JitValue :: FuncRef ( func_ref) ) ;
522
+ Ok ( ( ) )
523
+ }
524
+ } ,
525
+ Instruction :: CallFunctionPositional { nargs } => {
526
+ let nargs = nargs. get ( arg) ;
527
+
528
+ let mut args = Vec :: new ( ) ;
529
+ for _ in 0 ..nargs {
530
+ let arg = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
531
+ args. push ( arg. into_value ( ) . unwrap ( ) ) ;
532
+ }
533
+
534
+ match self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ? {
535
+ JitValue :: FuncRef ( reference) => {
536
+ let call = self . builder . ins ( ) . call ( reference, & args) ;
537
+ let returns = self . builder . inst_results ( call) ;
538
+ self . stack . push ( JitValue :: Int ( returns[ 0 ] ) ) ;
539
+
540
+ Ok ( ( ) )
541
+ } ,
542
+ _ => Err ( JitCompileError :: BadBytecode ) ,
543
+ }
544
+ } ,
511
545
_ => Err ( JitCompileError :: NotSupported ) ,
512
546
}
513
547
}
0 commit comments