// call c function static inline void __vm_call_cfunction(struct a2_vm* vm_p, struct a2_obj* _func){ assert(obj_t(_func)==A2_TCFUNCTION); int i, j; struct a2_obj* _obj = NULL; // back bottom int _b = a2_getbottom(vm_p->env_p); int _top = a2_gettop(vm_p->env_p); a2_setbottom(vm_p->env_p, a2_gettop(vm_p->env_p)); // closure arg to cstack for(i=ir_ga(curr_ir)+1; i<=ir_ga(curr_ir)+ir_gb(curr_ir); i++){ _obj = callinfo_sfreg(curr_ci, i); a2_pushstack(vm_p->env_p, _obj); } // call c function callinfo_new(vm_p, NULL, 0, 0); int ret = obj_vX(_func, cfunction)(a2_env2state(vm_p->env_p)); callinfo_free(vm_p); int size = a2_gettop(vm_p->env_p)-a2_getbottom(vm_p->env_p); // set return value for(i=size-ret, j=ir_ga(curr_ir); i<size && j<ir_ga(curr_ir)+ir_gc(curr_ir); j++,i++){ _obj = callinfo_sfreg(curr_ci, j); *_obj = *a2_getcstack(vm_p->env_p, i); } for(; j<ir_ga(curr_ir)+ir_gc(curr_ir); j++){ _obj = callinfo_sfreg(curr_ci, j); obj_setX(_obj, A2_TNIL, point, NULL); } a2_setbottom(vm_p->env_p, _b); a2_settop(vm_p->env_p, _top); curr_pc++; }
A2_API inline void a2_topset(struct a2_state* state, int idx){ a2_settop(state->env_p, a2_getbottom(state->env_p)+idx); }
A2_API inline int a2_top(struct a2_state* state){ return a2_gettop(state->env_p)-a2_getbottom(state->env_p); }
A2_API inline void a2_pop(struct a2_state* state, int count){ int top = a2_gettop(state->env_p); int bottom = a2_getbottom(state->env_p); if(count > 0 && top-count>=bottom) a2_settop(state->env_p, top-count); }