// return to c function static inline int __vm_return_cfunction(struct a2_vm* vm_p){ struct a2_obj* _obj = NULL; int i, ret; // return to c stack for(i=ir_ga(curr_ir); i<ir_ga(curr_ir)+ir_gbx(curr_ir); i++){ _obj = callinfo_sfreg(curr_ci, i); a2_pushstack(vm_p->env_p, _obj); } ret = ir_gbx(curr_ir); a2_closure_return(curr_cls, vm_p->env_p); callinfo_free(vm_p); return ret; }
A2_API inline void a2_len(struct a2_state* state, int idx){ struct a2_obj* obj = a2_getcstack(state->env_p, idx); size_t len =0; struct a2_obj len_obj; switch(obj_t(obj)){ case A2_TMAP: len = a2_map_len(a2_gcobj2map(obj_vX(obj, obj))); break; case A2_TARRAY: len = a2_array_len(a2_gcobj2array(obj_vX(obj, obj))); break; case A2_TSTRING: len = a2_string_len(a2_gcobj2string(obj_vX(obj, obj))); break; default: a2_error(state->env_p, e_run_error, "the type is not map or array at len function."); } len_obj = a2_number2obj((a2_number)len); a2_pushstack(state->env_p, &len_obj); }
A2_API inline void a2_require(struct a2_state* state){ struct a2_obj* k = a2_getcstack(state->env_p, a2_top(state)-1); check_key(k); struct a2_obj* v = a2_get_envreg(state->env_p, k); if(v) // return obj a2_pushstack(state->env_p, v); else{ // load obj const char* name = a2_gcobj2string(obj_vX(k, obj)); int len = strlen(name); char tmp[len+8]; memcpy(tmp, name, len); memcpy(tmp+len, ".a2", 4); int top = a2_top(state); a2_loadfile(state, tmp); if(a2_top(state)>top) a2_pushvalue(state, top); else a2_pushnil(state); a2_set_envreg(state->env_p, k, a2_getcstack(state->env_p, top)); } }
// 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_pushvalue(struct a2_state* state, int idx){ struct a2_obj* _v = a2_getcstack(state->env_p, idx); a2_pushstack(state->env_p, _v); }
A2_API inline void a2_pushfunction(struct a2_state* state, a2_cfunction func){ struct a2_obj obj = a2_cfunction2obj(func); a2_pushstack(state->env_p, &obj); }
A2_API inline void a2_pushbool(struct a2_state* state, int b){ struct a2_obj obj = a2_bool2obj(b); a2_pushstack(state->env_p, &obj); }
A2_API inline void a2_pushstring(struct a2_state* state, char* str){ struct a2_obj obj = a2_env_addstr(state->env_p, str); a2_pushstack(state->env_p, &obj); }
A2_API inline void a2_pushnil(struct a2_state* state){ struct a2_obj obj = a2_nil2obj(); a2_pushstack(state->env_p, &obj); }
A2_API inline void a2_pushnumber(struct a2_state* state, a2_number number){ struct a2_obj obj = a2_number2obj(number); a2_pushstack(state->env_p, &obj); }