// foreachprep static inline void _vm_foreachprep(struct a2_vm* vm_p){ struct a2_obj* _k = callinfo_sfreg(curr_ci, ir_ga(curr_ir)); struct a2_obj* _v = callinfo_sfreg(curr_ci, ir_ga(curr_ir)+1); struct a2_obj* _c = callinfo_sfreg(curr_ci, ir_ga(curr_ir)+2); struct a2_obj* __v = NULL; if(obj_t(_c)!=A2_TMAP && obj_t(_c)!=A2_TARRAY) vm_error("the varable is not map or array."); // set init varable switch(obj_t(_c)){ case A2_TMAP: *_k = a2_nil2obj(); __v = a2_map_next(a2_gcobj2map(obj_vX(_c, obj)), _k); if(__v==NULL) jump(ir_gbx(curr_ir)); else{ *_v = *__v; curr_pc++; } break; case A2_TARRAY: *_k = a2_nil2obj(); __v = a2_array_next(a2_gcobj2array(obj_vX(_c, obj)), _k); if(__v==NULL) // dump is end jump(ir_gbx(curr_ir)); else{ *_v = *__v; curr_pc++; } break; default: assert(0); } }
// mark array static inline void _gc_mark_array(struct a2_gc* gc_p, struct a2_gcobj* gcobj, enum gc_mark m){ assert(gcobj->type == A2_TARRAY); if(mask(gcobj->mark) == mask(m)) return; gcobj->mark = m; struct a2_obj k = a2_nil2obj(); struct a2_obj* vp = NULL; struct a2_array* array_p = a2_gcobj2array(gcobj); while(NULL != (vp=a2_array_next(array_p, &k))){ a2_gc_markit(gc_p, vp, m); } }
// mark map static inline void _gc_mark_map(struct a2_gc* gc_p, struct a2_gcobj* gcobj, enum gc_mark m){ assert(gcobj->type == A2_TMAP); if(mask(gcobj->mark) == mask(m)) return; gcobj->mark = m; struct a2_obj k = a2_nil2obj(); struct a2_obj* vp = NULL; struct a2_map* map_p = a2_gcobj2map(gcobj); while(NULL != (vp = a2_map_next(map_p, &k))){ if(obj_t(&k)==A2_TSTRING){ gcobj->mark = m; } a2_gc_markit(gc_p, vp, m); } }
int a2_vm_pcall(struct a2_vm* vm_p, struct a2_obj* cls_obj, struct a2_obj* args_obj, int args){ assert(obj_t(cls_obj) == A2_TCLOSURE); struct a2_closure* cls = a2_gcobj2closure(obj_vX(cls_obj, obj)); callinfo_new(vm_p, NULL, 0, 0); callinfo_new(vm_p, cls, 0, 0); // set arg int i, j; for(i=0, j=0; i<args && j<curr_ci->reg_stack.len; j++, i++){ *callinfo_sfreg(curr_ci, j) = args_obj[i]; } // set clear for(; j<curr_ci->reg_stack.len; j++){ *callinfo_sfreg(curr_ci, j) = a2_nil2obj(); } int ret = _vm_prun(vm_p); callinfo_free(vm_p); return ret; }
A2_API inline void a2_pushnil(struct a2_state* state){ struct a2_obj obj = a2_nil2obj(); a2_pushstack(state->env_p, &obj); }