ktap_closure *kp_load(ktap_state *ks, unsigned char *buff) { struct load_state S; ktap_closure *cl; ktap_lclosure *f; int ret, i; S.ks = ks; S.buff = buff; S.pos = 0; ret = load_header(&S); if (ret) return NULL; cl = kp_newlclosure(ks, 1); if (!cl) return cl; /* put closure on the top, prepare to run with this closure */ setcllvalue(ks->top, cl); incr_top(ks); cl->l.p = kp_newproto(ks); if (load_function(&S, cl->l.p)) return NULL; if (cl->l.p->sizeupvalues != 1) { ktap_proto *p = cl->l.p; cl = kp_newlclosure(ks, cl->l.p->sizeupvalues); cl->l.p = p; setcllvalue(ks->top - 1, cl); } f = &cl->l; for (i = 0; i < f->nupvalues; i++) { /* initialize upvalues */ ktap_upval *up = kp_newupval(ks); f->upvals[i] = up; } /* set global table as 1st upvalue of 'f' */ if (f->nupvalues == 1) { ktap_table *reg = hvalue(&G(ks)->registry); const ktap_value *gt = kp_table_getint(reg, KTAP_RIDX_GLOBALS); setobj(f->upvals[0]->v, gt); } verify_code(&S, cl->l.p); return cl; }
/* create a new closure */ static void pushclosure(ktap_state *ks, ktap_proto *p, ktap_upval **encup, StkId base, StkId ra) { int nup = p->sizeupvalues; ktap_upvaldesc *uv = p->upvalues; int i; ktap_closure *ncl = kp_newlclosure(ks, nup); ncl->l.p = p; setcllvalue(ra, ncl); /* anchor new closure in stack */ /* fill in its upvalues */ for (i = 0; i < nup; i++) { if (uv[i].instack) { /* upvalue refers to local variable? */ ncl->l.upvals[i] = findupval(ks, base + uv[i].idx); } else { /* get upvalue from enclosing function */ ncl->l.upvals[i] = encup[uv[i].idx]; } } //p->cache = ncl; /* save it on cache for reuse */ }