--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cgen/templates/FastPyFunctionDerivative Thu Apr 26 11:08:47 2012 -0700 @@ -0,0 +1,66 @@ +<%namespace file="base.impl" import="*"/>\ + + TARGET(FAST_PYFUN_${ arity_str(instr) }) + { + if (oparg != ${ instr.arity() }) goto TARGET_CALL_FUNCTION_SKIP_DISPATCH; + + % for operand,accessor in get_enumerated_args(instr.arity()): + ${operand}= ${accessor}(); + % endfor + + ## deal with ic misses... + % if config.create_inca_guards: + /* guard against inline cache misses */ + if (! (!(PyMethod_Check(v) && PyMethod_GET_SELF(v) != NULL) && PyFunction_Check(v))) { + ${ dbg_inf_ic_miss(instr) } + goto TARGET_CALL_FUNCTION_SKIP_DISPATCH; + } // if + PyCodeObject *code= (PyCodeObject*)PyFunction_GET_CODE(v); + if (code->co_argcount != ${ instr.arity() }) { + ${ dbg_inf_ic_miss(instr) } + goto TARGET_CALL_FUNCTION_SKIP_DISPATCH; + } // if + if (! (code->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))) { + ${ dbg_inf_ic_miss(instr) } + goto TARGET_CALL_FUNCTION_SKIP_DISPATCH; + } // if + % else: + /* guard against inline cache misses OMITTED */ + % endif + ${ dbg_inf_ic_hit(instr) } + + % if instr.arity() > 0: + STACKADJ(-${ instr.arity() }); + % endif + PyObject *globals= PyFunction_GET_GLOBALS(v); + PyThreadState *tstate= PyThreadState_GET(); + PyFrameObject *callee_frame= PyFrame_New( tstate, code, globals, NULL ); + if (callee_frame == NULL) { + SET_TOP((PyObject*)NULL); + break; + } // if + + ## pass arguments... + <% + i= 0 + revargs= get_enumerated_args(instr.arity()) + revargs.reverse() + %>\ + % for operand, accessor in revargs: + % if operand != 'v': + callee_frame->f_localsplus[${i}]= ${ operand }; + <% i+= 1 %>\ + % endif + % endfor + + x= PyEval_EvalFrameEx(callee_frame, 0); + + ++tstate->recursion_depth; + Py_DECREF(callee_frame); + --tstate->recursion_depth; + + ${ push_result() } + ${ dispatch() } + } + +