/* ** if object 'o' has a finalizer, remove it from 'allgc' list (must ** search the list to find it) and link it in 'finobj' list. */ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { global_State *g = G(L); if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ isfinalized(o) || /* ... or is finalized... */ gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ return; /* nothing to be done */ else { /* move 'o' to 'finobj' list */ GCObject **p; GCheader *ho = gch(o); if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ lua_assert(issweepphase(g)); g->sweepgc = sweeptolive(L, g->sweepgc, NULL); } /* search for pointer pointing to 'o' */ for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } *p = ho->next; /* remove 'o' from root list */ ho->next = g->finobj; /* link it in list 'finobj' */ g->finobj = o; l_setbit(ho->marked, SEPARATED); /* mark it as such */ if (!keepinvariantout(g)) /* not keeping invariant? */ makewhite(g, o); /* "sweep" object */ else resetoldbit(o); /* see MOVE OLD rule */ } }
void kp_obj_free_gclist(ktap_state *ks, ktap_gcobject *o) { while (o) { ktap_gcobject *next; next = gch(o)->next; switch (gch(o)->tt) { case KTAP_TYPE_TABLE: kp_tab_free(ks, (ktap_tab *)o); break; case KTAP_TYPE_PROTO: free_proto(ks, (ktap_proto *)o); break; case KTAP_TYPE_UPVAL: kp_freeupval(ks, (ktap_upval *)o); break; case KTAP_TYPE_PTABLE: kp_ptab_free(ks, (ktap_ptab *)o); break; case KTAP_TYPE_RAW: kp_free(ks, ((ktap_rawobj *)o)->v); break; default: kp_free(ks, o); } o = next; } }
/* ** create a new collectable object (with given type and size) and link ** it to 'allgc' list. */ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { global_State *g = G(L); GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz)); gch(o)->marked = luaC_white(g); gch(o)->tt = tt; gch(o)->next = g->allgc; g->allgc = o; return o; }
static GCObject *udata2finalize (global_State *g) { GCObject *o = g->tobefnz; /* get first element */ lua_assert(tofinalize(o)); g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ gch(o)->next = g->allgc; /* return it to 'allgc' list */ g->allgc = o; resetbit(gch(o)->marked, FINALIZEDBIT); /* object is "normal" again */ if (issweepphase(g)) makewhite(g, o); /* "sweep" object */ return o; }
void junk(void) { if (alphanumeric (inbyte ())) while (alphanumeric (ch ())) gch (); else while (alphanumeric (ch ())) { if (ch () == 0) break; gch (); } blanks (); }
static GCObject *udata2finalize (global_State *g) { GCObject *o = g->tobefnz; /* get first element */ lua_assert(isfinalized(o)); g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ gch(o)->next = g->allgc; /* return it to 'allgc' list */ g->allgc = o; resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ lua_assert(!isold(o)); /* see MOVE OLD rule */ if (!keepinvariantout(g)) /* not keeping invariant? */ makewhite(g, o); /* "sweep" object */ return o; }
/* ** create a new collectable object (with given type and size) and link ** it to '*list'. 'offset' tells how many bytes to allocate before the ** object itself (used only by states). */ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, int offset) { global_State *g = G(L); GCObject *o = obj2gco(cast(char *, luaM_newobject(L, tt, sz)) + offset); if (list == NULL) list = &g->allgc; /* standard list for collectable objects */ gch(o)->marked = luaC_white(g); gch(o)->tt = tt; gch(o)->next = *list; *list = o; return o; }
junk () { if (an (inbyte ())) while (an (ch ())) gch (); else while (an (ch ())) { if (ch () == 0) break; gch (); } blanks (); }
/* need to protect allgc field? */ ktap_gcobject *kp_obj_newobject(ktap_state *ks, int type, size_t size, ktap_gcobject **list) { ktap_gcobject *o; o = kp_malloc(ks, size); if (list == NULL) list = &G(ks)->allgc; gch(o)->tt = type; gch(o)->next = *list; *list = o; return o; }
/* need to protect allgc field? */ Gcobject *kp_newobject(ktap_State *ks, int type, size_t size, Gcobject **list) { Gcobject *o; o = kp_malloc(ks, sizeof(Gcobject) + size); if (list == NULL) list = &G(ks)->allgc; gch(o)->tt = type; gch(o)->marked = 0; gch(o)->next = *list; *list = o; return o; }
/** * test if next input string is legal symbol name */ int symname(char *sname) { int k; blanks(); if (!alpha (ch ())) return (0); k = 0; while (alphanumeric(ch ())) if (k < NAMEMAX) sname[k++] = gch (); else gch(); sname[k] = 0; return (1); }
int dolabel() { int savelptr; char sname[NAMESIZE]; SYMBOL* ptr; blanks(); savelptr = lptr; if (symname(sname)) { if (gch() == ':') { if ((ptr = findgoto(sname)) && ptr->ident == ID_GOTOLABEL) { /* Label already goto'd, find some others with * same stack */ debug(DBG_GOTO, "Starting chase %s\n", sname); ChaseGoto(ptr); ptr->type = KIND_PTR; } else { ptr = addgotosym(sname); ptr->type = KIND_PTR; } debug(DBG_GOTO, "Adding label not called %s\n", sname); ptr->offset.i = Zsp; /* Save stack for label */ postlabel(ptr->size = getlabel()); return (1); } } lptr = savelptr; return (0); }
/* ** if object 'o' has a finalizer, remove it from 'allgc' list (must ** search the list to find it) and link it in 'finobj' list. */ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { global_State *g = G(L); if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ isfinalized(o) || /* ... or is finalized... */ gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ return; /* nothing to be done */ else { /* move 'o' to 'finobj' list */ GCObject **p; for (p = &g->allgc; *p != o; p = &gch(*p)->next) ; *p = gch(o)->next; /* remove 'o' from root list */ gch(o)->next = g->finobj; /* link it in list 'finobj' */ g->finobj = o; l_setbit(gch(o)->marked, SEPARATED); /* mark it as such */ resetoldbit(o); /* see MOVE OLD rule */ } }
/* * fixiname - remove "brackets" around include file name */ fixiname () { char c1, c2, *p, *ibp; char buf[20]; FILE *fp; char buf2[100]; ibp = &buf[0]; if ((c1 = gch ()) != '"' && c1 != '<') return (NULL); for (p = line + lptr; *p ;) *ibp++ = *p++; c2 = *(--p); if (c1 == '"' ? (c2 != '"') : (c2 != '>')) { error ("incorrect delimiter"); return (NULL); } *(--ibp) = 0; fp = NULL; if (c1 == '<' || !(fp = fopen(buf, "r"))) { strcpy(buf2, DEFLIB); strcat(buf2, buf); fp = fopen(buf2, "r"); } return(fp); }
/* ** mark all objects in list of being-finalized */ static void markbeingfnz (global_State *g) { GCObject *o; for (o = g->tobefnz; o != NULL; o = gch(o)->next) { makewhite(g, o); reallymarkobject(g, o); } }
static void freeobj (lua_State *L, GCObject *o) { switch (gch(o)->tt) { case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; case LUA_TLCL: { luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); break; } case LUA_TCCL: { luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); break; } case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; case LUA_TTABLE: luaH_free(L, gco2t(o)); break; case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; case LUA_TSHRSTR: G(L)->strt.nuse--; /* go through */ case LUA_TLNGSTR: { luaM_freemem(L, o, sizestring(gco2ts(o))); break; } default: lua_assert(0); } }
/* ** barrier that moves collector backward, that is, mark the black object ** pointing to a white object as gray again. (Current implementation ** only works for tables; access to 'gclist' is not uniform across ** different types.) */ void luaC_barrierback_ (lua_State *L, GCObject *o) { global_State *g = G(L); lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE); black2gray(o); /* make object gray (again) */ gco2t(o)->gclist = g->grayagain; g->grayagain = o; }
/* ** traverse one gray object, turning it to black (except for threads, ** which are always gray). ** Returns number of values traversed. */ static int propagatemark (global_State *g) { GCObject *o = g->gray; lua_assert(isgray(o)); gray2black(o); switch (gch(o)->tt) { case LUA_TTABLE: { Table *h = gco2t(o); g->gray = h->gclist; return traversetable(g, h); } case LUA_TFUNCTION: { Closure *cl = gco2cl(o); g->gray = cl->c.gclist; return traverseclosure(g, cl); } case LUA_TTHREAD: { lua_State *th = gco2th(o); g->gray = th->gclist; th->gclist = g->grayagain; g->grayagain = o; black2gray(o); return traversestack(g, th); } case LUA_TPROTO: { Proto *p = gco2p(o); g->gray = p->gclist; return traverseproto(g, p); } default: lua_assert(0); return 0; } }
/* ** move all unreachable objects (or 'all' objects) that need ** finalization from list 'p' to list 'tobefnz' (to be finalized) */ static void separatetobefnz (global_State *g, int all) { GCObject *curr; GCObject **p = &g->finobj; GCObject **lastnext = findlast(&g->tobefnz); while ((curr = *p) != NULL) { /* traverse all finalizable objects */ lua_assert(tofinalize(curr)); if (!(iswhite(curr) || all)) /* not being collected? */ p = &gch(curr)->next; /* don't bother with it */ else { *p = gch(curr)->next; /* remove 'curr' from "fin" list */ gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ *lastnext = curr; lastnext = &gch(curr)->next; } } }
void term_reinit(int wait) /* fixup after running other progs */ { struct text_info dat; gppconio_init(); gettextinfo(&dat); if (dat.screenheight != screen_h) { _set_screen_lines(screen_h); gettextinfo(&dat); screen_h = dat.screenheight; screen_w = dat.screenwidth; mouse_init(); } set_bright_backgrounds(); if (wait) { clear_keybuf(); gch(); } __djgpp_set_ctrl_c(0); setcbrk(0); }
/* * inchar * Input : nothing * Output : int, (actualy char) * * Returns the current char, making lptr points to the next one * If the buffer if empty, fill it with next line from input * */ int inchar (void ) { if (ch () == 0) readline (); if (feof (input)) return (0); return (gch ()); }
int inbyte (void ) { while (ch () == 0) { if (feof (input)) return (0); preprocess (); } return (gch ()); }
void kp_obj_free_gclist(ktap_state_t *ks, ktap_obj_t *o) { while (o) { ktap_obj_t *next; next = gch(o)->nextgc; switch (gch(o)->gct) { case ~KTAP_TTAB: kp_tab_free(ks, (ktap_tab_t *)o); break; case ~KTAP_TUPVAL: kp_freeupval(ks, (ktap_upval_t *)o); break; default: kp_free(ks, o); } o = next; } }
/* ** mark an object. Userdata, strings, and closed upvalues are visited ** and turned black here. Other objects are marked gray and added ** to appropriate list to be visited (and turned black) later. (Open ** upvalues are already linked in 'headuv' list.) */ static void reallymarkobject (global_State *g, GCObject *o) { lu_mem size; white2gray(o); switch (gch(o)->tt) { case LUA_TSHRSTR: case LUA_TLNGSTR: { size = sizestring(gco2ts(o)); break; /* nothing else to mark; make it black */ } case LUA_TUSERDATA: { Table *mt = gco2u(o)->metatable; markobject(g, mt); markobject(g, gco2u(o)->env); size = sizeudata(gco2u(o)); break; } case LUA_TUPVAL: { UpVal *uv = gco2uv(o); markvalue(g, uv->v); if (uv->v != &uv->u.value) /* open? */ return; /* open upvalues remain gray */ size = sizeof(UpVal); break; } case LUA_TLCL: { gco2lcl(o)->gclist = g->gray; g->gray = o; return; } case LUA_TCCL: { gco2ccl(o)->gclist = g->gray; g->gray = o; return; } case LUA_TTABLE: { linktable(gco2t(o), &g->gray); return; } case LUA_TTHREAD: { gco2th(o)->gclist = g->gray; g->gray = o; return; } case LUA_TPROTO: { gco2p(o)->gclist = g->gray; g->gray = o; return; } default: lua_assert(0); return; } gray2black(o); g->GCmemtrav += size; }
/* ** barrier that moves collector forward, that is, mark the white object ** being pointed by a black object. */ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { global_State *g = G(L); lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); lua_assert(g->gcstate != GCSpause); lua_assert(gch(o)->tt != LUA_TTABLE); if (keepinvariantout(g)) /* must keep invariant? */ reallymarkobject(g, v); /* restore invariant */ else { /* sweep phase */ lua_assert(issweepphase(g)); makewhite(g, o); /* mark main obj. as white to avoid other barriers */ } }
asmfunc () { char c; needbrack ("("); if (!match (quote)) { error ("Missing opening \" in asm call"); return; } do { while (ch () != '"') { if (ch () == 0) break; c = gch(); outbyte (c == '\\' ? spechar() : c); } gch (); } while (match (quote)); needbrack (")"); ns (); }
void kp_free_all_gcobject(ktap_State *ks) { Gcobject *o = G(ks)->allgc; Gcobject *next; while (o) { next = gch(o)->next; switch (gch(o)->tt) { case KTAP_TTABLE: kp_table_free(ks, (Table *)o); break; case KTAP_TPROTO: free_proto(ks, (Proto *)o); break; default: kp_free(ks, o); } o = next; } G(ks)->allgc = NULL; }
KEYPRESS input_char() { KEYPRESS c; /* all keyboard input should come through this function instead of calling gch() directly. This function normally just calls getc(), but will insert codes from the macro buffer instead if a macro is being executed */ if (macro_mode == MACRO_FINISHED) macro_mode = 0; #if (defined TARGET_CURSES) || (defined TARGET_WIN) if (macro_mode) nosleep = TRUE; else nosleep = FALSE; #endif if (macro_mode == MACRO_PLAY) { c = macro[macro_pos++]; if (macro_pos >= macro_size) macro_mode = MACRO_FINISHED; } else { if (unget_count > 0) { int l; c.key = _unget[0]; c.flags = 0; unget_count--; for (l=0; l<unget_count; l++) _unget[l] = _unget[l+1]; } else { c.key = gch(); c.flags = modifiers(); } } if (macro_mode == MACRO_RECORD) { if (macro_size >= MACRO_LENGTH) { macro_mode = 0; clear_keybuf(); alert_box("Macro too long"); } else macro[macro_size++] = c; } return c; }
/** * Test if we have one char enclosed in single quotes * @param value returns the char found * @return 1 if we have, 0 otherwise */ int quoted_char(int *value) { int k; char c; k = 0; if (!match ("'")) return (0); while ((c = gch ()) != '\'') { c = (c == '\\') ? spechar(): c; k = (k & 255) * 256 + (c & 255); } *value = k; return (1); }
/** * Test if we have string enclosed in double quotes. e.g. "abc". * Load the string into literal pool. * @param position returns beginning of the string * @return 1 if such string found, 0 otherwise */ int quoted_string(int *position) { char c; if (!match ("\"")) return (0); *position = litptr; while (ch () != '"') { if (ch () == 0) break; if (litptr >= LITMAX) { error ("string space exhausted"); while (!match ("\"")) if (gch () == 0) break; return (1); } c = gch(); litq[litptr++] = (c == '\\') ? spechar(): c; } gch (); litq[litptr++] = 0; return (1); }