@@ -10,7 +10,25 @@ use crate::pyobject::{
1010use crate :: VirtualMachine ;
1111use num_traits:: ToPrimitive ;
1212use rustpython_bytecode:: bytecode:: CodeFlags ;
13- use rustpython_jit:: { AbiValue , Args , CompiledCode , JitType } ;
13+ use rustpython_jit:: { AbiValue , Args , CompiledCode , JitArgumentError , JitType } ;
14+
15+ #[ derive( Debug , thiserror:: Error ) ]
16+ pub enum ArgsError {
17+ #[ error( "wrong number of arguments passed" ) ]
18+ WrongNumberOfArgs ,
19+ #[ error( "argument passed multiple times" ) ]
20+ ArgPassedMultipleTimes ,
21+ #[ error( "not a keyword argument" ) ]
22+ NotAKeywordArg ,
23+ #[ error( "not all arguments passed" ) ]
24+ NotAllArgsPassed ,
25+ #[ error( "integer can't fit into a machine integer" ) ]
26+ IntOverflow ,
27+ #[ error( "type can't be used in a jit function" ) ]
28+ NonJitType ,
29+ #[ error( "{0}" ) ]
30+ JitError ( #[ from] JitArgumentError ) ,
31+ }
1432
1533impl IntoPyObject for AbiValue {
1634 fn into_pyobject ( self , vm : & VirtualMachine ) -> PyObjectRef {
@@ -85,15 +103,18 @@ pub fn get_jit_arg_types(func: &PyFunctionRef, vm: &VirtualMachine) -> PyResult<
85103 }
86104}
87105
88- fn get_jit_value ( vm : & VirtualMachine , obj : & PyObjectRef ) -> Option < AbiValue > {
106+ fn get_jit_value ( vm : & VirtualMachine , obj : & PyObjectRef ) -> Result < AbiValue , ArgsError > {
89107 // This does exact type checks as subclasses of int/float can't be passed to jitted functions
90108 let cls = obj. lease_class ( ) ;
91109 if cls. is ( & vm. ctx . types . int_type ) {
92- objint:: get_value ( & obj) . to_i64 ( ) . map ( AbiValue :: Int )
110+ objint:: get_value ( & obj)
111+ . to_i64 ( )
112+ . map ( AbiValue :: Int )
113+ . ok_or ( ArgsError :: IntOverflow )
93114 } else if cls. is ( & vm. ctx . types . float_type ) {
94- Some ( AbiValue :: Float ( objfloat:: get_value ( & obj) ) )
115+ Ok ( AbiValue :: Float ( objfloat:: get_value ( & obj) ) )
95116 } else {
96- None
117+ Err ( ArgsError :: NonJitType )
97118 }
98119}
99120
@@ -107,35 +128,35 @@ pub(crate) fn get_jit_args<'a>(
107128 func_args : & PyFuncArgs ,
108129 jitted_code : & ' a CompiledCode ,
109130 vm : & VirtualMachine ,
110- ) -> Option < Args < ' a > > {
131+ ) -> Result < Args < ' a > , ArgsError > {
111132 let mut jit_args = jitted_code. args_builder ( ) ;
112133 let nargs = func_args. args . len ( ) ;
113134
114135 if nargs > func. code . arg_names . len ( ) || nargs < func. code . posonlyarg_count {
115- return None ;
136+ return Err ( ArgsError :: WrongNumberOfArgs ) ;
116137 }
117138
118139 // Add positional arguments
119140 for i in 0 ..nargs {
120- jit_args. set ( i, get_jit_value ( vm, & func_args. args [ i] ) ?) ;
141+ jit_args. set ( i, get_jit_value ( vm, & func_args. args [ i] ) ?) ? ;
121142 }
122143
123144 // Handle keyword arguments
124145 for ( name, value) in & func_args. kwargs {
125146 if let Some ( arg_idx) = func. code . arg_names . iter ( ) . position ( |arg| arg == name) {
126147 if jit_args. is_set ( arg_idx) {
127- return None ;
148+ return Err ( ArgsError :: ArgPassedMultipleTimes ) ;
128149 }
129- jit_args. set ( arg_idx, get_jit_value ( vm, & value) ?) ;
150+ jit_args. set ( arg_idx, get_jit_value ( vm, & value) ?) ? ;
130151 } else if let Some ( kwarg_idx) = func. code . kwonlyarg_names . iter ( ) . position ( |arg| arg == name)
131152 {
132153 let arg_idx = kwarg_idx + func. code . arg_names . len ( ) ;
133154 if jit_args. is_set ( arg_idx) {
134- return None ;
155+ return Err ( ArgsError :: ArgPassedMultipleTimes ) ;
135156 }
136- jit_args. set ( arg_idx, get_jit_value ( vm, & value) ?) ;
157+ jit_args. set ( arg_idx, get_jit_value ( vm, & value) ?) ? ;
137158 } else {
138- return None ;
159+ return Err ( ArgsError :: NotAKeywordArg ) ;
139160 }
140161 }
141162
@@ -145,7 +166,7 @@ pub(crate) fn get_jit_args<'a>(
145166 for ( i, default) in defaults. iter ( ) . enumerate ( ) {
146167 let arg_idx = i + func. code . arg_names . len ( ) - defaults. len ( ) ;
147168 if !jit_args. is_set ( arg_idx) {
148- jit_args. set ( arg_idx, get_jit_value ( vm, default) ?) ;
169+ jit_args. set ( arg_idx, get_jit_value ( vm, default) ?) ? ;
149170 }
150171 }
151172 }
@@ -157,12 +178,12 @@ pub(crate) fn get_jit_args<'a>(
157178 if !jit_args. is_set ( arg_idx) {
158179 let default = kw_only_defaults
159180 . get_item ( name. as_str ( ) , vm)
160- . ok ( )
181+ . map_err ( |_| ArgsError :: NotAllArgsPassed )
161182 . and_then ( |obj| get_jit_value ( vm, & obj) ) ?;
162- jit_args. set ( arg_idx, default) ;
183+ jit_args. set ( arg_idx, default) ? ;
163184 }
164185 }
165186 }
166187
167- jit_args. into_args ( )
188+ jit_args. into_args ( ) . ok_or ( ArgsError :: NotAllArgsPassed )
168189}
0 commit comments