/* perform a shallow clone--just a new struct with the members copied into it */ struct call_info * callinfo_clone(struct call_info *cip) { struct call_info *newcip = callinfo_new(); *newcip = *cip; return newcip; }
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; }
// 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)); } }
// 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++; }
/* Unpack caller's information on the server, or server's information returned to the client */ struct call_info * callinfo_unpack(xmlrpc_env *envP, xmlrpc_value *s) { struct call_info *cip = callinfo_new(); xmlrpc_value *methargs, *files; int i; unpack(envP, s, "clientIP", (char **)&cip->clientIP); unpack(envP, s, "serverURL", &cip->serverURL); unpack(envP, s, "session", &cip->session); unpack(envP, s, "method", &cip->method); unpack(envP, s, "user", &cip->user); unpack(envP, s, "password", &cip->password); unpack(envP, s, "project", &cip->project); unpack(envP, s, "version", &cip->version); xmlrpc_struct_find_value(envP, s, "method-args", &methargs); if (methargs) { cip->nargs = xmlrpc_array_size(envP, methargs); cip->methodargs = malloc((cip->nargs + 1) * sizeof(char *)); for (i = 0; i < cip->nargs; ++i) { xmlrpc_value *v; char *arg; xmlrpc_array_read_item(envP, methargs, i, &v); xmlrpc_read_string(envP, v, (const char **const)&arg); cip->methodargs[i] = arg; fprintf(stderr, "unpacked methodargs[%d] as %s\n", i, arg); } cip->methodargs[cip->nargs] = NULL; } else { cip->nargs = 0; cip->methodargs = NULL; } xmlrpc_struct_find_value(envP, s, "method-data", &files); if (files) { for (i = 0; i < xmlrpc_array_size(envP, files); ++i) { struct file_data *this_file; xmlrpc_value * fstruct; xmlrpc_array_read_item(envP, files, i, &fstruct); this_file = file_unpack(envP, fstruct); if (cip->files == NULL) { cip->files = this_file; cip->files_last = cip->files->next; } else { cip->files_last->next = this_file; cip->files_last = cip->files->next; } } } return cip; }
int a2_vm_load(struct a2_vm* vm_p, struct a2_closure* cls){ assert(vm_p && cls); callinfo_new(vm_p, cls, 0, 0); return _vm_prun(vm_p); }