// new list static inline void _vm_newlist(struct a2_vm* vm_p){ struct a2_obj* _d = _getvalue(vm_p, ir_ga(curr_ir)); struct a2_gcobj* _gcobj = a2_array2gcobj(a2_array_new()); a2_gcadd(vm_p->env_p, _gcobj); obj_setX(_d, A2_TARRAY, obj, _gcobj); curr_pc++; }
// new map static inline void _vm_newmap(struct a2_vm* vm_p){ struct a2_obj* _d = _getvalue(vm_p, ir_ga(curr_ir)); struct a2_gcobj* _gcobj = a2_map2gcobj(a2_map_new()); a2_gcadd(vm_p->env_p, _gcobj); obj_setX(_d, A2_TMAP, obj, _gcobj); curr_pc++; }
// call a2 function static inline void __vm_call_function(struct a2_vm* vm_p, struct a2_obj* _func){ assert(obj_t(_func)==A2_TCLOSURE); struct a2_obj* _obj = NULL; int i, j, params = a2_closure_params(a2_gcobj2closure(obj_vX(_func, obj))); struct a2_array* _args = NULL; struct vm_callinfo* _ci = curr_ci; ir _ir = curr_ir; // new call info int b = ir_ga(curr_ir), n=ir_gc(curr_ir); callinfo_new(vm_p, a2_gcobj2closure(obj_vX(_func, obj)), b, n); // jump call _ci->pc++; // if is mutableargs if(params<0){ params = -1 - params; _obj = callinfo_sfreg(curr_ci, params); if(ir_gb(_ir)>params){ // set _args list _args = a2_array_new(); struct a2_gcobj* _array_gcobj = a2_array2gcobj(_args); a2_gcadd(vm_p->env_p, _array_gcobj); obj_setX(_obj, A2_TARRAY, obj, _array_gcobj); }else{ obj_setX(_obj, A2_TNIL, point, NULL); } } // set params for(i=ir_ga(_ir)+1, j=0; i<=ir_ga(_ir)+ir_gb(_ir) && j<params; j++, i++){ _obj = callinfo_sfreg(curr_ci, j); *_obj = *callinfo_sfreg(_ci, i); } // set clear params for( ;j<params; j++){ _obj = callinfo_sfreg(curr_ci, j); obj_setX(_obj, A2_TNIL, point, NULL); } // if mutable args for(j=0; i<=ir_ga(_ir)+ir_gb(_ir) && _args; i++, j++){ a2_array_add(_args, callinfo_sfreg(_ci, i)); } }
// TODO: closure static inline void _vm_closure(struct a2_vm* vm_p){ struct a2_obj* _d = callinfo_sfreg(curr_ci, ir_ga(curr_ir)); struct a2_closure* _cls = a2_closure_new(curr_ci, ir_gbx(curr_ir)); struct a2_gcobj* _gcobj = a2_closure2gcobj(_cls); obj_setX(_d, A2_TCLOSURE, obj, _gcobj); a2_gcadd(vm_p->env_p, _gcobj); curr_pc++; }
// get global A2_API inline void a2_getglobal(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_envglobal(state->env_p, k); if(v==NULL) obj_setX(k, A2_TNIL, point, NULL); else *k = *v; }
// loadnil static inline void _vm_loadnil(struct a2_vm* vm_p){ int i; struct a2_obj* _obj = NULL; for(i=ir_ga(curr_ir); i<(ir_ga(curr_ir)+ir_gbx(curr_ir)); i++){ _obj = callinfo_sfreg(curr_ci, i); obj_setX(_obj, A2_TNIL, point, NULL); } curr_pc++; }
// get array A2_API inline void a2_getarray(struct a2_state* state){ int top = a2_top(state)-1; struct a2_obj* k = a2_getcstack(state->env_p, top); struct a2_obj* array = a2_getcstack(state->env_p, top-1); struct a2_obj* _v = NULL; check_array(array); check_num(k); _v = a2_array_get(a2_gcobj2array(obj_vX(array, obj)), k); if(_v==NULL) obj_setX(k, A2_TNIL, point, NULL); else *k = *_v; }
// get map A2_API inline void a2_getmap(struct a2_state* state){ int top = a2_top(state)-1; struct a2_obj* k = a2_getcstack(state->env_p, top); struct a2_obj* map = a2_getcstack(state->env_p, top-1); struct a2_obj* v = NULL; check_map(map); check_key(k); v = a2_map_query(a2_gcobj2map(obj_vX(map, obj)), k); if(v==NULL) obj_setX(map, A2_TNIL, point, NULL); else *map = *v; }
// cat static inline void _vm_cat(struct a2_vm* vm_p){ struct a2_obj* _d = _getvalue(vm_p, ir_ga(curr_ir)); struct a2_obj* _lv = _getvalue(vm_p, ir_gb(curr_ir)); struct a2_obj* _rv = _getvalue(vm_p, ir_gc(curr_ir)); char buf[64] = {0}; char buf0[64] = {0}; char* a2_s = a2_string_new(obj2str(_lv, buf, sizeof(buf)-1)); a2_s = a2_string_cat(a2_s, obj2str(_rv, buf0, sizeof(buf0)-1)); obj_setX(_d, A2_TSTRING, obj, a2_env_addstrobj(vm_p->env_p, a2_s)); a2_string_free(a2_s); curr_pc++; }
// 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++; }
// return to a2 function static inline int __vm_return_function(struct a2_vm* vm_p){ struct a2_obj* _obj = NULL; struct vm_callinfo* call_ci = curr_ci->next; int i, j, ret; // set return for(i=ir_ga(curr_ir), j=curr_ci->retbegin; i<ir_ga(curr_ir)+ir_gbx(curr_ir) && j<curr_ci->retbegin+curr_ci->retnumber; j++, i++){ _obj = callinfo_sfreg(call_ci, j); *_obj = *callinfo_sfreg(curr_ci, i); } // set clear for( ; j<curr_ci->retbegin+curr_ci->retnumber; j++){ _obj = callinfo_sfreg(call_ci, j); obj_setX(_obj, A2_TNIL, point, NULL); } ret = curr_ci->retnumber; a2_closure_return(curr_cls, vm_p->env_p); callinfo_free(vm_p); return ret; }
// void* point to obj struct a2_obj a2_point2obj(void* p){ struct a2_obj ret; obj_setX(&ret, A2_TPOINT, point, p); return ret; }
// addr to object struct a2_obj a2_addr2obj(size_t addr){ struct a2_obj ret; obj_setX(&ret, _A2_TADDR, addr, addr); return ret; }
// cfunction to object struct a2_obj a2_cfunction2obj(a2_cfunction func){ assert(func); struct a2_obj ret; obj_setX(&ret, A2_TCFUNCTION, cfunction, func); return ret; }
// nil varable to object struct a2_obj a2_nil2obj(){ struct a2_obj ret; obj_setX(&ret, A2_TNIL, point, NULL); return ret; }
// bool varable to object struct a2_obj a2_bool2obj(int t){ struct a2_obj ret; obj_setX(&ret, A2_TBOOL, uinteger, (!(t==0))); return ret; }
// uint32 v to obj struct a2_obj a2_uinteger2obj(uint32 v){ struct a2_obj ret; obj_setX(&ret, _A2_TUINTEGER, uinteger, v); return ret; }
// a2_string to obj struct a2_obj a2_string2obj(char* a2_s){ assert(a2_s); struct a2_obj ret; obj_setX(&ret, A2_TSTRING, obj, a2_string2gcobj(a2_s)); return ret; }