@@ -16,7 +16,15 @@ pub enum ProcessorError {
1616 InvalidNameIndex ,
1717}
1818
19- fn run_code < EP : EnvProxy > ( envproxy : & mut EP , code : Code , store : & mut ObjectStore ) -> Result < ObjectRef , ProcessorError > {
19+ fn call_function < EP : EnvProxy > ( envproxy : & mut EP , store : & mut ObjectStore , func_ref : & ObjectRef , args : Vec < ObjectRef > , kwags : Vec < ObjectRef > ) -> Result < ObjectRef , ProcessorError > {
20+ let code = match store. deref ( func_ref) . content {
21+ ObjectContent :: Code ( ref code) => code. clone ( ) ,
22+ _ => return Err ( ProcessorError :: NotACodeObject ) ,
23+ } ;
24+ run_code ( envproxy, store, code)
25+ }
26+
27+ fn run_code < EP : EnvProxy > ( envproxy : & mut EP , store : & mut ObjectStore , code : Code ) -> Result < ObjectRef , ProcessorError > {
2028 let bytecode: Vec < u8 > = code. code ;
2129 let instructions: Vec < Instruction > = instructions:: InstructionDecoder :: new ( bytecode. iter ( ) ) . into_iter ( ) . collect ( ) ;
2230 let mut program_counter = 0 as usize ;
@@ -28,16 +36,25 @@ fn run_code<EP: EnvProxy>(envproxy: &mut EP, code: Code, store: &mut ObjectStore
2836 Instruction :: ReturnValue => return Ok ( try!( stack. pop ( ) . ok_or ( ProcessorError :: StackTooSmall ) ) ) ,
2937 Instruction :: LoadConst ( i) => stack. push ( try!( code. names . get ( i) . ok_or ( ProcessorError :: InvalidConstIndex ) ) . clone ( ) ) ,
3038 Instruction :: LoadName ( i) => stack. push ( try!( code. names . get ( i) . ok_or ( ProcessorError :: InvalidNameIndex ) ) . clone ( ) ) ,
39+ Instruction :: CallFunction ( nb_args, nb_kwargs) => {
40+ // See “Call constructs” at:
41+ // http://security.coverity.com/blog/2014/Nov/understanding-python-bytecode.html
42+ let kwargs = try!( stack. pop_many ( nb_kwargs* 2 ) . ok_or ( ProcessorError :: StackTooSmall ) ) ;
43+ let args = try!( stack. pop_many ( nb_args) . ok_or ( ProcessorError :: StackTooSmall ) ) ;
44+ let func = try!( stack. pop ( ) . ok_or ( ProcessorError :: StackTooSmall ) ) ;
45+ let ret_value = call_function ( envproxy, store, & func, args, kwargs) ;
46+ stack. push ( try!( ret_value) )
47+ }
3148 _ => panic ! ( format!( "todo: instruction {:?}" , * instruction) ) ,
3249 }
3350 } ;
3451 panic ! ( "Unreachable" )
3552}
3653
37- pub fn run_code_object < EP : EnvProxy > ( envproxy : & mut EP , module : ObjectRef , store : & mut ObjectStore ) -> Result < ObjectRef , ProcessorError > {
54+ pub fn run_code_object < EP : EnvProxy > ( envproxy : & mut EP , store : & mut ObjectStore , module : ObjectRef ) -> Result < ObjectRef , ProcessorError > {
3855 let code = match store. deref ( & module) . content {
3956 ObjectContent :: Code ( ref code) => code. clone ( ) ,
4057 _ => return Err ( ProcessorError :: NotACodeObject ) ,
4158 } ;
42- run_code ( envproxy, code , store )
59+ run_code ( envproxy, store , code )
4360}
0 commit comments