/* * main search function */ const Tvalue *kp_table_get(Table *t, const Tvalue *key) { switch (ttype(key)) { case KTAP_TNIL: return ktap_nilobject; case KTAP_TSHRSTR: return kp_table_getstr(t, rawtsvalue(key)); case KTAP_TNUMBER: { ktap_Number n = nvalue(key); int k = (int)n; if ((ktap_Number)k == nvalue(key)) /* index is int? */ return kp_table_getint(t, k); /* use specialized version */ /* else go through */ } default: { Node *n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ if (rawequalobj(gkey(n), key)) return gval(n); /* that's it */ else n = gnext(n); } while (n); return ktap_nilobject; } } }
static void ktap_init_arguments(ktap_state *ks, int argc, char **argv) { const ktap_value *gt = kp_table_getint(hvalue(&G(ks)->registry), KTAP_RIDX_GLOBALS); ktap_table *global_tbl = hvalue(gt); ktap_table *arg_tbl = kp_table_new(ks); ktap_value arg_tblval; ktap_value arg_tsval; int i; setsvalue(&arg_tsval, kp_tstring_new(ks, "arg")); sethvalue(&arg_tblval, arg_tbl); kp_table_setvalue(ks, global_tbl, &arg_tsval, &arg_tblval); if (!argc) return; kp_table_resize(ks, arg_tbl, 100, 100); for (i = 0; i < argc; i++) { int res; ktap_value val; if (!kstrtoint(argv[i], 10, &res)) { setnvalue(&val, res); } else setsvalue(&val, kp_tstring_new(ks, argv[i])); kp_table_setint(ks, arg_tbl, i, &val); } }
/* function for register library */ void kp_register_lib(ktap_state *ks, const char *libname, const ktap_Reg *funcs) { int i; ktap_table *target_tbl; const ktap_value *gt = kp_table_getint(hvalue(&G(ks)->registry), KTAP_RIDX_GLOBALS); /* lib is null when register baselib function */ if (libname == NULL) target_tbl = hvalue(gt); else { ktap_value key, val; target_tbl = kp_table_new(ks); kp_table_resize(ks, target_tbl, 0, sizeof(*funcs) / sizeof(ktap_Reg)); setsvalue(&key, kp_tstring_new(ks, libname)); sethvalue(&val, target_tbl); kp_table_setvalue(ks, hvalue(gt), &key, &val); } for (i = 0; funcs[i].name != NULL; i++) { ktap_value func_name, cl; setsvalue(&func_name, kp_tstring_new(ks, funcs[i].name)); setfvalue(&cl, funcs[i].func); kp_table_setvalue(ks, target_tbl, &func_name, &cl); cfunction_cache_add(ks, &cl); } }
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; }
void kp_table_setint(ktap_State *ks, Table *t, int key, Tvalue *v) { const Tvalue *p = kp_table_getint(t, key); Tvalue *cell; if (p != ktap_nilobject) cell = (Tvalue *)p; else { Tvalue k; setnvalue(&k, key); cell = table_newkey(ks, t, &k); } setobj(ks, cell, v); }
static int cfunction_cache_getindex(ktap_state *ks, ktap_value *fname) { const ktap_value *gt = kp_table_getint(hvalue(&G(ks)->registry), KTAP_RIDX_GLOBALS); const ktap_value *cfunc; int nr, i; nr = G(ks)->nr_builtin_cfunction; cfunc = kp_table_get(hvalue(gt), fname); for (i = 0; i < nr; i++) { if (rawequalobj(&G(ks)->cfunction_tbl[i], cfunc)) return i; } return -1; }