diff options
Diffstat (limited to '')
| -rw-r--r-- | lapi.c | 45 | ||||
| -rw-r--r-- | lbaselib.c | 10 | ||||
| -rw-r--r-- | lcode.c | 6 | ||||
| -rw-r--r-- | ldblib.c | 16 | ||||
| -rw-r--r-- | lgc.c | 62 | ||||
| -rw-r--r-- | liolib.c | 94 | ||||
| -rw-r--r-- | lobject.h | 34 | ||||
| -rw-r--r-- | lstate.c | 12 | ||||
| -rw-r--r-- | lstate.h | 4 | ||||
| -rw-r--r-- | lstring.c | 72 | ||||
| -rw-r--r-- | lstring.h | 20 | ||||
| -rw-r--r-- | ltable.c | 4 | ||||
| -rw-r--r-- | ltests.c | 38 | ||||
| -rw-r--r-- | ltm.c | 6 | ||||
| -rw-r--r-- | ltm.h | 4 | ||||
| -rw-r--r-- | lua.c | 4 | ||||
| -rw-r--r-- | lua.h | 4 |
17 files changed, 215 insertions, 220 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 1.141 2001/04/23 16:35:45 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.142 2001/06/05 18:17:01 roberto Exp roberto $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -284,8 +284,7 @@ LUA_API void *lua_touserdata (lua_State *L, int index) { | |||
| 284 | void *p; | 284 | void *p; |
| 285 | lua_lock(L); | 285 | lua_lock(L); |
| 286 | o = luaA_indexAcceptable(L, index); | 286 | o = luaA_indexAcceptable(L, index); |
| 287 | p = (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL : | 287 | p = (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL : uvalue(o)->value; |
| 288 | tsvalue(o)->u.d.value; | ||
| 289 | lua_unlock(L); | 288 | lua_unlock(L); |
| 290 | return p; | 289 | return p; |
| 291 | } | 290 | } |
| @@ -360,16 +359,6 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | |||
| 360 | } | 359 | } |
| 361 | 360 | ||
| 362 | 361 | ||
| 363 | LUA_API int lua_pushuserdata (lua_State *L, void *u) { | ||
| 364 | int isnew; | ||
| 365 | lua_lock(L); | ||
| 366 | isnew = luaS_createudata(L, u, L->top); | ||
| 367 | api_incr_top(L); | ||
| 368 | lua_unlock(L); | ||
| 369 | return isnew; | ||
| 370 | } | ||
| 371 | |||
| 372 | |||
| 373 | 362 | ||
| 374 | /* | 363 | /* |
| 375 | ** get functions (Lua -> stack) | 364 | ** get functions (Lua -> stack) |
| @@ -673,7 +662,7 @@ LUA_API void lua_settag (lua_State *L, int tag) { | |||
| 673 | hvalue(L->top-1)->htag = tag; | 662 | hvalue(L->top-1)->htag = tag; |
| 674 | break; | 663 | break; |
| 675 | case LUA_TUSERDATA: | 664 | case LUA_TUSERDATA: |
| 676 | tsvalue(L->top-1)->u.d.tag = tag; | 665 | uvalue(L->top-1)->tag = tag; |
| 677 | break; | 666 | break; |
| 678 | default: | 667 | default: |
| 679 | luaO_verror(L, l_s("cannot change the tag of a %.20s"), | 668 | luaO_verror(L, l_s("cannot change the tag of a %.20s"), |
| @@ -771,20 +760,34 @@ LUA_API void lua_concat (lua_State *L, int n) { | |||
| 771 | } | 760 | } |
| 772 | 761 | ||
| 773 | 762 | ||
| 763 | static Udata *pushnewudata (lua_State *L, size_t size) { | ||
| 764 | Udata *u = luaS_newudata(L, size); | ||
| 765 | setuvalue(L->top, u); | ||
| 766 | api_incr_top(L); | ||
| 767 | return uvalue(L->top-1); | ||
| 768 | } | ||
| 769 | |||
| 770 | |||
| 774 | LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | 771 | LUA_API void *lua_newuserdata (lua_State *L, size_t size) { |
| 775 | TString *ts; | 772 | Udata *u; |
| 776 | void *p; | 773 | void *p; |
| 777 | lua_lock(L); | 774 | lua_lock(L); |
| 778 | if (size == 0) size = 1; | 775 | u = pushnewudata(L, size); |
| 779 | ts = luaS_newudata(L, size, NULL); | 776 | p = u->value; |
| 780 | setuvalue(L->top, ts); | ||
| 781 | api_incr_top(L); | ||
| 782 | p = ts->u.d.value; | ||
| 783 | lua_unlock(L); | 777 | lua_unlock(L); |
| 784 | return p; | 778 | return p; |
| 785 | } | 779 | } |
| 786 | 780 | ||
| 787 | 781 | ||
| 782 | LUA_API void lua_newuserdatabox (lua_State *L, void *p) { | ||
| 783 | Udata *u; | ||
| 784 | lua_lock(L); | ||
| 785 | u = pushnewudata(L, 0); | ||
| 786 | u->value = p; | ||
| 787 | lua_unlock(L); | ||
| 788 | } | ||
| 789 | |||
| 790 | |||
| 788 | LUA_API int lua_getweakmode (lua_State *L, int index) { | 791 | LUA_API int lua_getweakmode (lua_State *L, int index) { |
| 789 | StkId t; | 792 | StkId t; |
| 790 | int mode; | 793 | int mode; |
| @@ -806,6 +809,7 @@ LUA_API void lua_setweakmode (lua_State *L, int mode) { | |||
| 806 | 809 | ||
| 807 | 810 | ||
| 808 | 811 | ||
| 812 | #if 0 | ||
| 809 | /* | 813 | /* |
| 810 | ** deprecated function | 814 | ** deprecated function |
| 811 | */ | 815 | */ |
| @@ -819,3 +823,4 @@ LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) { | |||
| 819 | } | 823 | } |
| 820 | } | 824 | } |
| 821 | } | 825 | } |
| 826 | #endif | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.35 2001/04/23 16:35:45 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.36 2001/06/05 19:41:31 roberto Exp roberto $ |
| 3 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -170,11 +170,11 @@ static int luaB_settag (lua_State *L) { | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | static int luaB_weakmode (lua_State *L) { | 172 | static int luaB_weakmode (lua_State *L) { |
| 173 | const char *mode = luaL_check_string(L, 2); | 173 | const l_char *mode = luaL_check_string(L, 2); |
| 174 | luaL_checktype(L, 1, LUA_TTABLE); | 174 | luaL_checktype(L, 1, LUA_TTABLE); |
| 175 | if (*mode == l_c('?')) { | 175 | if (*mode == l_c('?')) { |
| 176 | char buff[3]; | 176 | l_char buff[3]; |
| 177 | char *s = buff; | 177 | l_char *s = buff; |
| 178 | int imode = lua_getweakmode(L, 1); | 178 | int imode = lua_getweakmode(L, 1); |
| 179 | if (imode & LUA_WEAK_KEY) *s++ = 'k'; | 179 | if (imode & LUA_WEAK_KEY) *s++ = 'k'; |
| 180 | if (imode & LUA_WEAK_VALUE) *s++ = 'v'; | 180 | if (imode & LUA_WEAK_VALUE) *s++ = 'v'; |
| @@ -300,7 +300,7 @@ static int passresults (lua_State *L, int status, int oldtop) { | |||
| 300 | if (nresults > 0) | 300 | if (nresults > 0) |
| 301 | return nresults; /* results are already on the stack */ | 301 | return nresults; /* results are already on the stack */ |
| 302 | else { | 302 | else { |
| 303 | lua_pushuserdata(L, NULL); /* at least one result to signal no errors */ | 303 | lua_newuserdatabox(L, NULL); /* at least one result to signal no errors */ |
| 304 | return 1; | 304 | return 1; |
| 305 | } | 305 | } |
| 306 | } | 306 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.68 2001/04/23 16:35:45 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.69 2001/06/05 18:17:01 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -226,12 +226,12 @@ static int addk (FuncState *fs, TObject *k) { | |||
| 226 | 226 | ||
| 227 | int luaK_stringk (FuncState *fs, TString *s) { | 227 | int luaK_stringk (FuncState *fs, TString *s) { |
| 228 | Proto *f = fs->f; | 228 | Proto *f = fs->f; |
| 229 | int c = s->u.s.constindex; | 229 | int c = s->constindex; |
| 230 | if (c >= fs->nk || ttype(&f->k[c]) != LUA_TSTRING || tsvalue(&f->k[c]) != s) { | 230 | if (c >= fs->nk || ttype(&f->k[c]) != LUA_TSTRING || tsvalue(&f->k[c]) != s) { |
| 231 | TObject o; | 231 | TObject o; |
| 232 | setsvalue(&o, s); | 232 | setsvalue(&o, s); |
| 233 | c = addk(fs, &o); | 233 | c = addk(fs, &o); |
| 234 | s->u.s.constindex = c; /* hint for next time */ | 234 | s->constindex = c; /* hint for next time */ |
| 235 | } | 235 | } |
| 236 | return c; | 236 | return c; |
| 237 | } | 237 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldblib.c,v 1.35 2001/03/07 18:09:25 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.36 2001/03/26 14:31:49 roberto Exp roberto $ |
| 3 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -111,15 +111,13 @@ static int setlocal (lua_State *L) { | |||
| 111 | 111 | ||
| 112 | 112 | ||
| 113 | 113 | ||
| 114 | /* dummy variables (to define unique addresses) */ | 114 | #define KEY_CALLHOOK l_s("luadblibCallhook") |
| 115 | static const l_char key1[] = l_s("ab"); | 115 | #define KEY_LINEHOOK l_s("luadblibLinehook") |
| 116 | #define KEY_CALLHOOK ((void *)key1) | ||
| 117 | #define KEY_LINEHOOK ((void *)(key1+1)) | ||
| 118 | 116 | ||
| 119 | 117 | ||
| 120 | static void hookf (lua_State *L, void *key) { | 118 | static void hookf (lua_State *L, const l_char *key) { |
| 121 | lua_getregistry(L); | 119 | lua_getregistry(L); |
| 122 | lua_pushuserdata(L, key); | 120 | lua_pushstring(L, key); |
| 123 | lua_gettable(L, -2); | 121 | lua_gettable(L, -2); |
| 124 | if (lua_isfunction(L, -1)) { | 122 | if (lua_isfunction(L, -1)) { |
| 125 | lua_pushvalue(L, -3); /* original argument (below table and function) */ | 123 | lua_pushvalue(L, -3); /* original argument (below table and function) */ |
| @@ -143,7 +141,7 @@ static void linef (lua_State *L, lua_Debug *ar) { | |||
| 143 | } | 141 | } |
| 144 | 142 | ||
| 145 | 143 | ||
| 146 | static void sethook (lua_State *L, void *key, lua_Hook hook, | 144 | static void sethook (lua_State *L, const l_char *key, lua_Hook hook, |
| 147 | lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) { | 145 | lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) { |
| 148 | lua_settop(L, 1); | 146 | lua_settop(L, 1); |
| 149 | if (lua_isnil(L, 1)) | 147 | if (lua_isnil(L, 1)) |
| @@ -153,7 +151,7 @@ static void sethook (lua_State *L, void *key, lua_Hook hook, | |||
| 153 | else | 151 | else |
| 154 | luaL_argerror(L, 1, l_s("function expected")); | 152 | luaL_argerror(L, 1, l_s("function expected")); |
| 155 | lua_getregistry(L); | 153 | lua_getregistry(L); |
| 156 | lua_pushuserdata(L, key); | 154 | lua_pushstring(L, key); |
| 157 | lua_pushvalue(L, -1); /* dup key */ | 155 | lua_pushvalue(L, -1); /* dup key */ |
| 158 | lua_gettable(L, -3); /* get old value */ | 156 | lua_gettable(L, -3); /* get old value */ |
| 159 | lua_pushvalue(L, -2); /* key (again) */ | 157 | lua_pushvalue(L, -2); /* key (again) */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.98 2001/06/05 18:17:01 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.99 2001/06/05 19:27:32 roberto Exp roberto $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -82,9 +82,12 @@ static void marktable (GCState *st, Hash *h) { | |||
| 82 | 82 | ||
| 83 | static void markobject (GCState *st, TObject *o) { | 83 | static void markobject (GCState *st, TObject *o) { |
| 84 | switch (ttype(o)) { | 84 | switch (ttype(o)) { |
| 85 | case LUA_TUSERDATA: case LUA_TSTRING: | 85 | case LUA_TSTRING: |
| 86 | strmark(tsvalue(o)); | 86 | strmark(tsvalue(o)); |
| 87 | break; | 87 | break; |
| 88 | case LUA_TUSERDATA: | ||
| 89 | uvalue(o)->marked = 1; | ||
| 90 | break; | ||
| 88 | case LUA_TFUNCTION: | 91 | case LUA_TFUNCTION: |
| 89 | markclosure(st, clvalue(o)); | 92 | markclosure(st, clvalue(o)); |
| 90 | break; | 93 | break; |
| @@ -190,8 +193,10 @@ static void markall (lua_State *L) { | |||
| 190 | 193 | ||
| 191 | static int hasmark (const TObject *o) { | 194 | static int hasmark (const TObject *o) { |
| 192 | switch (ttype(o)) { | 195 | switch (ttype(o)) { |
| 193 | case LUA_TSTRING: case LUA_TUSERDATA: | 196 | case LUA_TSTRING: |
| 194 | return tsvalue(o)->marked; | 197 | return tsvalue(o)->marked; |
| 198 | case LUA_TUSERDATA: | ||
| 199 | return uvalue(o)->marked; | ||
| 195 | case LUA_TTABLE: | 200 | case LUA_TTABLE: |
| 196 | return ismarked(hvalue(o)); | 201 | return ismarked(hvalue(o)); |
| 197 | case LUA_TFUNCTION: | 202 | case LUA_TFUNCTION: |
| @@ -275,9 +280,21 @@ static void collecttable (lua_State *L) { | |||
| 275 | } | 280 | } |
| 276 | 281 | ||
| 277 | 282 | ||
| 278 | static void checktab (lua_State *L, stringtable *tb) { | 283 | static void collectudata (lua_State *L) { |
| 279 | if (tb->nuse < (ls_nstr)(tb->size/4) && tb->size > MINPOWER2) | 284 | Udata **p = &G(L)->rootudata; |
| 280 | luaS_resize(L, tb, tb->size/2); /* table is too big */ | 285 | Udata *next; |
| 286 | while ((next = *p) != NULL) { | ||
| 287 | if (next->marked) { | ||
| 288 | next->marked = 0; /* unmark */ | ||
| 289 | p = &next->next; | ||
| 290 | } | ||
| 291 | else { /* collect */ | ||
| 292 | int tag = next->tag; | ||
| 293 | *p = next->next; | ||
| 294 | next->next = G(L)->TMtable[tag].collected; /* chain udata */ | ||
| 295 | G(L)->TMtable[tag].collected = next; | ||
| 296 | } | ||
| 297 | } | ||
| 281 | } | 298 | } |
| 282 | 299 | ||
| 283 | 300 | ||
| @@ -299,33 +316,12 @@ static void collectstrings (lua_State *L, int all) { | |||
| 299 | } | 316 | } |
| 300 | } | 317 | } |
| 301 | } | 318 | } |
| 302 | checktab(L, &G(L)->strt); | 319 | if (G(L)->strt.nuse < (ls_nstr)(G(L)->strt.size/4) && |
| 320 | G(L)->strt.size > MINPOWER2) | ||
| 321 | luaS_resize(L, G(L)->strt.size/2); /* table is too big */ | ||
| 303 | } | 322 | } |
| 304 | 323 | ||
| 305 | 324 | ||
| 306 | static void collectudata (lua_State *L, int all) { | ||
| 307 | int i; | ||
| 308 | for (i=0; i<G(L)->udt.size; i++) { /* for each list */ | ||
| 309 | TString **p = &G(L)->udt.hash[i]; | ||
| 310 | TString *next; | ||
| 311 | while ((next = *p) != NULL) { | ||
| 312 | lua_assert(next->marked <= 1); | ||
| 313 | if (next->marked && !all) { /* preserve? */ | ||
| 314 | next->marked = 0; | ||
| 315 | p = &next->nexthash; | ||
| 316 | } | ||
| 317 | else { /* collect */ | ||
| 318 | int tag = next->u.d.tag; | ||
| 319 | *p = next->nexthash; | ||
| 320 | next->nexthash = G(L)->TMtable[tag].collected; /* chain udata */ | ||
| 321 | G(L)->TMtable[tag].collected = next; | ||
| 322 | G(L)->udt.nuse--; | ||
| 323 | } | ||
| 324 | } | ||
| 325 | } | ||
| 326 | checktab(L, &G(L)->udt); | ||
| 327 | } | ||
| 328 | |||
| 329 | 325 | ||
| 330 | #define MINBUFFER 256 | 326 | #define MINBUFFER 256 |
| 331 | static void checkMbuffer (lua_State *L) { | 327 | static void checkMbuffer (lua_State *L) { |
| @@ -356,10 +352,10 @@ static void callgcTMudata (lua_State *L) { | |||
| 356 | int tag; | 352 | int tag; |
| 357 | G(L)->GCthreshold = 2*G(L)->nblocks; /* avoid GC during tag methods */ | 353 | G(L)->GCthreshold = 2*G(L)->nblocks; /* avoid GC during tag methods */ |
| 358 | for (tag=G(L)->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */ | 354 | for (tag=G(L)->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */ |
| 359 | TString *udata; | 355 | Udata *udata; |
| 360 | while ((udata = G(L)->TMtable[tag].collected) != NULL) { | 356 | while ((udata = G(L)->TMtable[tag].collected) != NULL) { |
| 361 | TObject obj; | 357 | TObject obj; |
| 362 | G(L)->TMtable[tag].collected = udata->nexthash; /* remove it from list */ | 358 | G(L)->TMtable[tag].collected = udata->next; /* remove it from list */ |
| 363 | setuvalue(&obj, udata); | 359 | setuvalue(&obj, udata); |
| 364 | callgcTM(L, &obj); | 360 | callgcTM(L, &obj); |
| 365 | luaM_free(L, udata, sizeudata(udata->len)); | 361 | luaM_free(L, udata, sizeudata(udata->len)); |
| @@ -370,7 +366,7 @@ static void callgcTMudata (lua_State *L) { | |||
| 370 | 366 | ||
| 371 | void luaC_collect (lua_State *L, int all) { | 367 | void luaC_collect (lua_State *L, int all) { |
| 372 | lua_lockgc(L); | 368 | lua_lockgc(L); |
| 373 | collectudata(L, all); | 369 | collectudata(L); |
| 374 | callgcTMudata(L); | 370 | callgcTMudata(L); |
| 375 | collectstrings(L, all); | 371 | collectstrings(L, all); |
| 376 | collecttable(L); | 372 | collecttable(L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 1.111 2001/03/26 14:31:49 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 1.112 2001/04/23 16:35:45 roberto Exp roberto $ |
| 3 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -48,15 +48,17 @@ int pclose(); */ | |||
| 48 | #define OUTFILE 1 | 48 | #define OUTFILE 1 |
| 49 | #define NOFILE 2 | 49 | #define NOFILE 2 |
| 50 | 50 | ||
| 51 | #define FILEHANDLE l_s("FileHandle") | 51 | #define FILEHANDLE l_s("FileHandle") |
| 52 | #define CLOSEDFILEHANDLE l_s("ClosedFileHandle") | ||
| 52 | 53 | ||
| 53 | 54 | ||
| 54 | static const l_char *const filenames[] = {l_s("_INPUT"), l_s("_OUTPUT")}; | 55 | static const l_char *const filenames[] = {l_s("_INPUT"), l_s("_OUTPUT")}; |
| 56 | static const l_char *const basicfiles[] = {l_s("_STDIN"), l_s("_STDOUT")}; | ||
| 55 | 57 | ||
| 56 | 58 | ||
| 57 | static int pushresult (lua_State *L, int i) { | 59 | static int pushresult (lua_State *L, int i) { |
| 58 | if (i) { | 60 | if (i) { |
| 59 | lua_pushuserdata(L, NULL); | 61 | lua_newuserdatabox(L, NULL); |
| 60 | return 1; | 62 | return 1; |
| 61 | } | 63 | } |
| 62 | else { | 64 | else { |
| @@ -81,16 +83,15 @@ static int pushresult (lua_State *L, int i) { | |||
| 81 | static FILE *getopthandle (lua_State *L, int inout) { | 83 | static FILE *getopthandle (lua_State *L, int inout) { |
| 82 | FILE *p = (FILE *)lua_touserdata(L, 1); | 84 | FILE *p = (FILE *)lua_touserdata(L, 1); |
| 83 | if (p != NULL) { /* is it a userdata ? */ | 85 | if (p != NULL) { /* is it a userdata ? */ |
| 84 | if (!checkfile(L, 1)) { | 86 | if (!checkfile(L, 1)) { /* not a valid file handle? */ |
| 85 | if (strcmp(lua_xtypename(L, 1), l_s("ClosedFileHandle")) == 0) | 87 | if (strcmp(lua_xtypename(L, 1), CLOSEDFILEHANDLE) == 0) |
| 86 | luaL_argerror(L, 1, l_s("file is closed")); | 88 | luaL_argerror(L, 1, l_s("file is closed")); |
| 87 | else | 89 | else |
| 88 | luaL_argerror(L, 1, l_s("(invalid value)")); | 90 | luaL_argerror(L, 1, l_s("(invalid value)")); |
| 89 | } | 91 | } |
| 90 | /* move it to stack top */ | 92 | lua_pushvalue(L, 1); lua_remove(L, 1); /* move it to stack top */ |
| 91 | lua_pushvalue(L, 1); lua_remove(L, 1); | ||
| 92 | } | 93 | } |
| 93 | else if (inout != NOFILE) { /* try global value */ | 94 | else { /* try global value */ |
| 94 | lua_getglobal(L, filenames[inout]); | 95 | lua_getglobal(L, filenames[inout]); |
| 95 | if (!checkfile(L,-1)) | 96 | if (!checkfile(L,-1)) |
| 96 | luaL_verror(L, l_s("global variable `%.10s' is not a valid file handle"), | 97 | luaL_verror(L, l_s("global variable `%.10s' is not a valid file handle"), |
| @@ -101,46 +102,50 @@ static FILE *getopthandle (lua_State *L, int inout) { | |||
| 101 | } | 102 | } |
| 102 | 103 | ||
| 103 | 104 | ||
| 104 | static void pushfile (lua_State *L, FILE *f) { | 105 | static void newfile (lua_State *L, FILE *f) { |
| 105 | lua_pushusertag(L, f, lua_name2tag(L, FILEHANDLE)); | 106 | lua_newuserdatabox(L, f); |
| 107 | lua_settag(L, lua_name2tag(L, FILEHANDLE)); | ||
| 106 | } | 108 | } |
| 107 | 109 | ||
| 108 | 110 | ||
| 109 | static void setfilebyname (lua_State *L, FILE *f, const l_char *name) { | 111 | static void newfilewithname (lua_State *L, FILE *f, const l_char *name) { |
| 110 | pushfile(L, f); | 112 | newfile(L, f); |
| 111 | lua_setglobal(L, name); | 113 | lua_setglobal(L, name); |
| 112 | } | 114 | } |
| 113 | 115 | ||
| 114 | 116 | ||
| 115 | #define setfile(L,f,inout) (setfilebyname(L,f,filenames[inout])) | 117 | static int setnewfile (lua_State *L, FILE *f, int inout) { |
| 116 | |||
| 117 | |||
| 118 | static int setreturn (lua_State *L, FILE *f, int inout) { | ||
| 119 | if (f == NULL) | 118 | if (f == NULL) |
| 120 | return pushresult(L, 0); | 119 | return pushresult(L, 0); |
| 121 | else { | 120 | else { |
| 122 | if (inout != NOFILE) | 121 | newfile(L, f); |
| 123 | setfile(L, f, inout); | 122 | if (inout != NOFILE) { |
| 124 | pushfile(L, f); | 123 | lua_pushvalue(L, -1); |
| 124 | lua_setglobal(L, filenames[inout]); | ||
| 125 | } | ||
| 125 | return 1; | 126 | return 1; |
| 126 | } | 127 | } |
| 127 | } | 128 | } |
| 128 | 129 | ||
| 129 | 130 | ||
| 130 | static int closefile (lua_State *L, FILE *f) { | 131 | static void resetfile (lua_State *L, int inout) { |
| 131 | if (f == stdin || f == stdout || f == stderr) | 132 | lua_getglobal(L, basicfiles[inout]); |
| 132 | return 1; | 133 | lua_setglobal(L, filenames[inout]); |
| 133 | else { | ||
| 134 | lua_pushuserdata(L, f); | ||
| 135 | lua_settag(L, lua_name2tag(L, l_s("ClosedFileHandle"))); | ||
| 136 | return (CLOSEFILE(L, f) == 0); | ||
| 137 | } | ||
| 138 | } | 134 | } |
| 139 | 135 | ||
| 140 | 136 | ||
| 141 | static int io_close (lua_State *L) { | 137 | static int io_close (lua_State *L) { |
| 142 | FILE *f = (FILE *)luaL_check_userdata(L, 1, FILEHANDLE); | 138 | FILE *f; |
| 143 | return pushresult(L, closefile(L, f)); | 139 | int status; |
| 140 | lua_settop(L, 1); | ||
| 141 | f = luaL_check_userdata(L, 1, FILEHANDLE); | ||
| 142 | if (f == stdin || f == stdout || f == stderr) | ||
| 143 | status = 1; | ||
| 144 | else { | ||
| 145 | lua_settag(L, lua_name2tag(L, CLOSEDFILEHANDLE)); | ||
| 146 | status = (CLOSEFILE(L, f) == 0); | ||
| 147 | } | ||
| 148 | return pushresult(L, status); | ||
| 144 | } | 149 | } |
| 145 | 150 | ||
| 146 | 151 | ||
| @@ -154,12 +159,12 @@ static int file_collect (lua_State *L) { | |||
| 154 | 159 | ||
| 155 | static int io_open (lua_State *L) { | 160 | static int io_open (lua_State *L) { |
| 156 | FILE *f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2)); | 161 | FILE *f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2)); |
| 157 | return setreturn(L, f, NOFILE); | 162 | return setnewfile(L, f, NOFILE); |
| 158 | } | 163 | } |
| 159 | 164 | ||
| 160 | 165 | ||
| 161 | static int io_tmpfile (lua_State *L) { | 166 | static int io_tmpfile (lua_State *L) { |
| 162 | return setreturn(L, tmpfile(), NOFILE); | 167 | return setnewfile(L, tmpfile(), NOFILE); |
| 163 | } | 168 | } |
| 164 | 169 | ||
| 165 | 170 | ||
| @@ -167,16 +172,15 @@ static int io_tmpfile (lua_State *L) { | |||
| 167 | static int io_fromto (lua_State *L, int inout, const l_char *mode) { | 172 | static int io_fromto (lua_State *L, int inout, const l_char *mode) { |
| 168 | FILE *current; | 173 | FILE *current; |
| 169 | if (lua_isnull(L, 1)) { | 174 | if (lua_isnull(L, 1)) { |
| 170 | closefile(L, getopthandle(L, inout)); | 175 | getopthandle(L, inout); |
| 171 | current = (inout == 0) ? stdin : stdout; | 176 | resetfile(L, inout); |
| 177 | return io_close(L); | ||
| 172 | } | 178 | } |
| 173 | else if (checkfile(L, 1)) /* deprecated option */ | ||
| 174 | current = (FILE *)lua_touserdata(L, 1); | ||
| 175 | else { | 179 | else { |
| 176 | const l_char *s = luaL_check_string(L, 1); | 180 | const l_char *s = luaL_check_string(L, 1); |
| 177 | current = (*s == l_c('|')) ? popen(s+1, mode) : fopen(s, mode); | 181 | current = (*s == l_c('|')) ? popen(s+1, mode) : fopen(s, mode); |
| 182 | return setnewfile(L, current, inout); | ||
| 178 | } | 183 | } |
| 179 | return setreturn(L, current, inout); | ||
| 180 | } | 184 | } |
| 181 | 185 | ||
| 182 | 186 | ||
| @@ -192,7 +196,7 @@ static int io_writeto (lua_State *L) { | |||
| 192 | 196 | ||
| 193 | static int io_appendto (lua_State *L) { | 197 | static int io_appendto (lua_State *L) { |
| 194 | FILE *current = fopen(luaL_check_string(L, 1), l_s("a")); | 198 | FILE *current = fopen(luaL_check_string(L, 1), l_s("a")); |
| 195 | return setreturn(L, current, OUTFILE); | 199 | return setnewfile(L, current, OUTFILE); |
| 196 | } | 200 | } |
| 197 | 201 | ||
| 198 | 202 | ||
| @@ -388,8 +392,8 @@ static int io_seek (lua_State *L) { | |||
| 388 | 392 | ||
| 389 | 393 | ||
| 390 | static int io_flush (lua_State *L) { | 394 | static int io_flush (lua_State *L) { |
| 391 | FILE *f = getopthandle(L, NOFILE); | 395 | FILE *f = (lua_isnull(L, 1)) ? (FILE *)NULL : |
| 392 | luaL_arg_check(L, f || lua_isnull(L, 1), 1, l_s("invalid file handle")); | 396 | (FILE *)luaL_check_userdata(L, 1, FILEHANDLE); |
| 393 | return pushresult(L, fflush(f) == 0); | 397 | return pushresult(L, fflush(f) == 0); |
| 394 | } | 398 | } |
| 395 | 399 | ||
| @@ -679,14 +683,14 @@ static const luaL_reg iolib[] = { | |||
| 679 | 683 | ||
| 680 | LUALIB_API int lua_iolibopen (lua_State *L) { | 684 | LUALIB_API int lua_iolibopen (lua_State *L) { |
| 681 | int iotag = lua_newxtype(L, FILEHANDLE, LUA_TUSERDATA); | 685 | int iotag = lua_newxtype(L, FILEHANDLE, LUA_TUSERDATA); |
| 682 | lua_newxtype(L, l_s("ClosedFileHandle"), LUA_TUSERDATA); | 686 | lua_newxtype(L, CLOSEDFILEHANDLE, LUA_TUSERDATA); |
| 683 | luaL_openl(L, iolib); | 687 | luaL_openl(L, iolib); |
| 684 | /* predefined file handles */ | 688 | /* predefined file handles */ |
| 685 | setfile(L, stdin, INFILE); | 689 | newfilewithname(L, stdin, basicfiles[INFILE]); |
| 686 | setfile(L, stdout, OUTFILE); | 690 | newfilewithname(L, stdout, basicfiles[OUTFILE]); |
| 687 | setfilebyname(L, stdin, l_s("_STDIN")); | 691 | newfilewithname(L, stderr, l_s("_STDERR")); |
| 688 | setfilebyname(L, stdout, l_s("_STDOUT")); | 692 | resetfile(L, INFILE); |
| 689 | setfilebyname(L, stderr, l_s("_STDERR")); | 693 | resetfile(L, OUTFILE); |
| 690 | /* close files when collected */ | 694 | /* close files when collected */ |
| 691 | lua_pushcfunction(L, file_collect); | 695 | lua_pushcfunction(L, file_collect); |
| 692 | lua_settagmethod(L, iotag, l_s("gc")); | 696 | lua_settagmethod(L, iotag, l_s("gc")); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 1.102 2001/04/11 14:42:41 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.103 2001/06/05 18:17:01 roberto Exp roberto $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -29,6 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | typedef union { | 30 | typedef union { |
| 31 | struct TString *ts; | 31 | struct TString *ts; |
| 32 | struct Udata *u; | ||
| 32 | struct Closure *cl; | 33 | struct Closure *cl; |
| 33 | struct Hash *h; | 34 | struct Hash *h; |
| 34 | lua_Number n; /* LUA_TNUMBER */ | 35 | lua_Number n; /* LUA_TNUMBER */ |
| @@ -45,6 +46,7 @@ typedef struct lua_TObject { | |||
| 45 | #define ttype(o) ((o)->tt) | 46 | #define ttype(o) ((o)->tt) |
| 46 | #define nvalue(o) ((o)->value.n) | 47 | #define nvalue(o) ((o)->value.n) |
| 47 | #define tsvalue(o) ((o)->value.ts) | 48 | #define tsvalue(o) ((o)->value.ts) |
| 49 | #define uvalue(o) ((o)->value.u) | ||
| 48 | #define clvalue(o) ((o)->value.cl) | 50 | #define clvalue(o) ((o)->value.cl) |
| 49 | #define hvalue(o) ((o)->value.h) | 51 | #define hvalue(o) ((o)->value.h) |
| 50 | 52 | ||
| @@ -57,7 +59,7 @@ typedef struct lua_TObject { | |||
| 57 | { TObject *_o=(obj); _o->tt=LUA_TSTRING; _o->value.ts=(x); } | 59 | { TObject *_o=(obj); _o->tt=LUA_TSTRING; _o->value.ts=(x); } |
| 58 | 60 | ||
| 59 | #define setuvalue(obj,x) \ | 61 | #define setuvalue(obj,x) \ |
| 60 | { TObject *_o=(obj); _o->tt=LUA_TUSERDATA; _o->value.ts=(x); } | 62 | { TObject *_o=(obj); _o->tt=LUA_TUSERDATA; _o->value.u=(x); } |
| 61 | 63 | ||
| 62 | #define setclvalue(obj,x) \ | 64 | #define setclvalue(obj,x) \ |
| 63 | { TObject *_o=(obj); _o->tt=LUA_TFUNCTION; _o->value.cl=(x); } | 65 | { TObject *_o=(obj); _o->tt=LUA_TFUNCTION; _o->value.cl=(x); } |
| @@ -78,38 +80,40 @@ typedef TObject *StkId; /* index to stack elements */ | |||
| 78 | /* | 80 | /* |
| 79 | ** String headers for string table | 81 | ** String headers for string table |
| 80 | */ | 82 | */ |
| 81 | |||
| 82 | typedef struct TString { | 83 | typedef struct TString { |
| 83 | union { | 84 | lu_hash hash; |
| 84 | struct { /* for strings */ | 85 | int constindex; /* hint to reuse constants */ |
| 85 | lu_hash hash; | ||
| 86 | int constindex; /* hint to reuse constants */ | ||
| 87 | } s; | ||
| 88 | struct { /* for userdata */ | ||
| 89 | int tag; | ||
| 90 | void *value; | ||
| 91 | } d; | ||
| 92 | } u; | ||
| 93 | size_t len; | 86 | size_t len; |
| 94 | int marked; | 87 | int marked; |
| 95 | struct TString *nexthash; /* chain for hash table */ | 88 | struct TString *nexthash; /* chain for hash table */ |
| 96 | } TString; | 89 | } TString; |
| 97 | 90 | ||
| 98 | 91 | ||
| 92 | |||
| 99 | /* | 93 | /* |
| 100 | ** type equivalent to TString, but with maximum alignment requirements | 94 | ** type equivalent to TString, but with maximum alignment requirements |
| 101 | */ | 95 | */ |
| 102 | union L_UTString { | 96 | union L_UTString { |
| 103 | TString ts; | 97 | TString ts; |
| 104 | union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ | 98 | union L_Umaxalign dummy; /* ensures maximum alignment for strings */ |
| 105 | }; | 99 | }; |
| 106 | 100 | ||
| 107 | 101 | ||
| 108 | |||
| 109 | #define getstr(ts) ((l_char *)((union L_UTString *)(ts) + 1)) | 102 | #define getstr(ts) ((l_char *)((union L_UTString *)(ts) + 1)) |
| 110 | #define svalue(o) getstr(tsvalue(o)) | 103 | #define svalue(o) getstr(tsvalue(o)) |
| 111 | 104 | ||
| 112 | 105 | ||
| 106 | |||
| 107 | typedef struct Udata { | ||
| 108 | int tag; | ||
| 109 | void *value; | ||
| 110 | size_t len; | ||
| 111 | int marked; | ||
| 112 | struct Udata *next; /* chain for list of all udata */ | ||
| 113 | } Udata; | ||
| 114 | |||
| 115 | |||
| 116 | |||
| 113 | /* | 117 | /* |
| 114 | ** Function Prototypes | 118 | ** Function Prototypes |
| 115 | */ | 119 | */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 1.61 2001/03/26 14:31:49 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.62 2001/04/17 17:35:54 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -49,14 +49,15 @@ static void f_luaopen (lua_State *L, void *ud) { | |||
| 49 | } | 49 | } |
| 50 | else { /* create a new global state */ | 50 | else { /* create a new global state */ |
| 51 | L->G = luaM_new(L, global_State); | 51 | L->G = luaM_new(L, global_State); |
| 52 | G(L)->strt.size = G(L)->udt.size = 0; | 52 | G(L)->strt.size = 0; |
| 53 | G(L)->strt.nuse = G(L)->udt.nuse = 0; | 53 | G(L)->strt.nuse = 0; |
| 54 | G(L)->strt.hash = G(L)->udt.hash = NULL; | 54 | G(L)->strt.hash = NULL; |
| 55 | G(L)->Mbuffer = NULL; | 55 | G(L)->Mbuffer = NULL; |
| 56 | G(L)->Mbuffsize = 0; | 56 | G(L)->Mbuffsize = 0; |
| 57 | G(L)->rootproto = NULL; | 57 | G(L)->rootproto = NULL; |
| 58 | G(L)->rootcl = NULL; | 58 | G(L)->rootcl = NULL; |
| 59 | G(L)->roottable = NULL; | 59 | G(L)->roottable = NULL; |
| 60 | G(L)->rootudata = NULL; | ||
| 60 | G(L)->TMtable = NULL; | 61 | G(L)->TMtable = NULL; |
| 61 | G(L)->sizeTM = 0; | 62 | G(L)->sizeTM = 0; |
| 62 | G(L)->ntag = 0; | 63 | G(L)->ntag = 0; |
| @@ -67,7 +68,7 @@ static void f_luaopen (lua_State *L, void *ud) { | |||
| 67 | G(L)->registry = luaH_new(L, 0); | 68 | G(L)->registry = luaH_new(L, 0); |
| 68 | G(L)->weakregistry = luaH_new(L, 0); | 69 | G(L)->weakregistry = luaH_new(L, 0); |
| 69 | G(L)->weakregistry->weakmode = LUA_WEAK_VALUE; /* make weakregistry weak */ | 70 | G(L)->weakregistry->weakmode = LUA_WEAK_VALUE; /* make weakregistry weak */ |
| 70 | luaS_init(L); | 71 | luaS_resize(L, MINPOWER2); |
| 71 | luaX_init(L); | 72 | luaX_init(L); |
| 72 | luaT_init(L); | 73 | luaT_init(L); |
| 73 | G(L)->GCthreshold = 4*G(L)->nblocks; | 74 | G(L)->GCthreshold = 4*G(L)->nblocks; |
| @@ -115,6 +116,7 @@ static void close_state (lua_State *L, lua_State *OL) { | |||
| 115 | lua_assert(G(L)->rootproto == NULL); | 116 | lua_assert(G(L)->rootproto == NULL); |
| 116 | lua_assert(G(L)->rootcl == NULL); | 117 | lua_assert(G(L)->rootcl == NULL); |
| 117 | lua_assert(G(L)->roottable == NULL); | 118 | lua_assert(G(L)->roottable == NULL); |
| 119 | lua_assert(G(L)->rootudata == NULL); | ||
| 118 | luaS_freeall(L); | 120 | luaS_freeall(L); |
| 119 | luaM_freearray(L, G(L)->TMtable, G(L)->sizeTM, struct TM); | 121 | luaM_freearray(L, G(L)->TMtable, G(L)->sizeTM, struct TM); |
| 120 | luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, l_char); | 122 | luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, l_char); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 1.55 2001/03/07 18:09:25 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.56 2001/04/17 17:35:54 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -53,8 +53,8 @@ typedef struct global_State { | |||
| 53 | Proto *rootproto; /* list of all prototypes */ | 53 | Proto *rootproto; /* list of all prototypes */ |
| 54 | Closure *rootcl; /* list of all closures */ | 54 | Closure *rootcl; /* list of all closures */ |
| 55 | Hash *roottable; /* list of all tables */ | 55 | Hash *roottable; /* list of all tables */ |
| 56 | Udata *rootudata; /* list of all userdata */ | ||
| 56 | stringtable strt; /* hash table for strings */ | 57 | stringtable strt; /* hash table for strings */ |
| 57 | stringtable udt; /* hash table for udata */ | ||
| 58 | Hash *type2tag; /* hash table from type names to tags */ | 58 | Hash *type2tag; /* hash table from type names to tags */ |
| 59 | Hash *registry; /* (strong) registry table */ | 59 | Hash *registry; /* (strong) registry table */ |
| 60 | Hash *weakregistry; /* weakregistry table */ | 60 | Hash *weakregistry; /* weakregistry table */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 1.61 2001/02/23 17:17:25 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.62 2001/03/26 14:31:49 roberto Exp roberto $ |
| 3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -17,22 +17,15 @@ | |||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | void luaS_init (lua_State *L) { | ||
| 21 | luaS_resize(L, &G(L)->strt, MINPOWER2); | ||
| 22 | luaS_resize(L, &G(L)->udt, MINPOWER2); | ||
| 23 | } | ||
| 24 | |||
| 25 | |||
| 26 | void luaS_freeall (lua_State *L) { | 20 | void luaS_freeall (lua_State *L) { |
| 27 | lua_assert(G(L)->strt.nuse==0); | 21 | lua_assert(G(L)->strt.nuse==0); |
| 28 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); | 22 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); |
| 29 | lua_assert(G(L)->udt.nuse==0); | ||
| 30 | luaM_freearray(L, G(L)->udt.hash, G(L)->udt.size, TString *); | ||
| 31 | } | 23 | } |
| 32 | 24 | ||
| 33 | 25 | ||
| 34 | void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | 26 | void luaS_resize (lua_State *L, int newsize) { |
| 35 | TString **newhash = luaM_newvector(L, newsize, TString *); | 27 | TString **newhash = luaM_newvector(L, newsize, TString *); |
| 28 | stringtable *tb = &G(L)->strt; | ||
| 36 | int i; | 29 | int i; |
| 37 | for (i=0; i<newsize; i++) newhash[i] = NULL; | 30 | for (i=0; i<newsize; i++) newhash[i] = NULL; |
| 38 | /* rehash */ | 31 | /* rehash */ |
| @@ -40,7 +33,7 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | |||
| 40 | TString *p = tb->hash[i]; | 33 | TString *p = tb->hash[i]; |
| 41 | while (p) { /* for each node in the list */ | 34 | while (p) { /* for each node in the list */ |
| 42 | TString *next = p->nexthash; /* save next */ | 35 | TString *next = p->nexthash; /* save next */ |
| 43 | lu_hash h = (tb == &G(L)->strt) ? p->u.s.hash : IntPoint(p->u.d.value); | 36 | lu_hash h = p->hash; |
| 44 | int h1 = lmod(h, newsize); /* new position */ | 37 | int h1 = lmod(h, newsize); /* new position */ |
| 45 | lua_assert((int)(h%newsize) == lmod(h, newsize)); | 38 | lua_assert((int)(h%newsize) == lmod(h, newsize)); |
| 46 | p->nexthash = newhash[h1]; /* chain it in new position */ | 39 | p->nexthash = newhash[h1]; /* chain it in new position */ |
| @@ -54,16 +47,6 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { | |||
| 54 | } | 47 | } |
| 55 | 48 | ||
| 56 | 49 | ||
| 57 | static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) { | ||
| 58 | ts->nexthash = tb->hash[h]; /* chain new entry */ | ||
| 59 | tb->hash[h] = ts; | ||
| 60 | tb->nuse++; | ||
| 61 | if (tb->nuse > (ls_nstr)tb->size && tb->size <= MAX_INT/2) /* too crowded? */ | ||
| 62 | luaS_resize(L, tb, tb->size*2); | ||
| 63 | } | ||
| 64 | |||
| 65 | |||
| 66 | |||
| 67 | TString *luaS_newlstr (lua_State *L, const l_char *str, size_t l) { | 50 | TString *luaS_newlstr (lua_State *L, const l_char *str, size_t l) { |
| 68 | TString *ts; | 51 | TString *ts; |
| 69 | lu_hash h = l; /* seed */ | 52 | lu_hash h = l; /* seed */ |
| @@ -80,39 +63,30 @@ TString *luaS_newlstr (lua_State *L, const l_char *str, size_t l) { | |||
| 80 | ts->marked = 0; | 63 | ts->marked = 0; |
| 81 | ts->nexthash = NULL; | 64 | ts->nexthash = NULL; |
| 82 | ts->len = l; | 65 | ts->len = l; |
| 83 | ts->u.s.hash = h; | 66 | ts->hash = h; |
| 84 | ts->u.s.constindex = 0; | 67 | ts->constindex = 0; |
| 85 | memcpy(getstr(ts), str, l*sizeof(l_char)); | 68 | memcpy(getstr(ts), str, l*sizeof(l_char)); |
| 86 | getstr(ts)[l] = 0; /* ending 0 */ | 69 | getstr(ts)[l] = 0; /* ending 0 */ |
| 87 | newentry(L, &G(L)->strt, ts, lmod(h, G(L)->strt.size)); /* insert it */ | 70 | h = lmod(h, G(L)->strt.size); |
| 71 | ts->nexthash = G(L)->strt.hash[h]; /* chain new entry */ | ||
| 72 | G(L)->strt.hash[h] = ts; | ||
| 73 | G(L)->strt.nuse++; | ||
| 74 | if (G(L)->strt.nuse > (ls_nstr)G(L)->strt.size && | ||
| 75 | G(L)->strt.size <= MAX_INT/2) | ||
| 76 | luaS_resize(L, G(L)->strt.size*2); /* too crowded */ | ||
| 88 | return ts; | 77 | return ts; |
| 89 | } | 78 | } |
| 90 | 79 | ||
| 91 | 80 | ||
| 92 | TString *luaS_newudata (lua_State *L, size_t s, void *udata) { | 81 | Udata *luaS_newudata (lua_State *L, size_t s) { |
| 93 | TString *ts = (TString *)luaM_malloc(L, sizeudata(s)); | 82 | Udata *u = (Udata *)luaM_malloc(L, sizeudata(s)); |
| 94 | ts->marked = 0; | 83 | u->marked = 0; |
| 95 | ts->nexthash = NULL; | 84 | u->len = s; |
| 96 | ts->len = s; | 85 | u->tag = 0; |
| 97 | ts->u.d.tag = 0; | 86 | u->value = ((union L_UUdata *)(u) + 1); |
| 98 | ts->u.d.value = (s > 0) ? getstr(ts) : udata; | 87 | /* chain it on udata list */ |
| 99 | /* insert it on table */ | 88 | u->next = G(L)->rootudata; |
| 100 | newentry(L, &G(L)->udt, ts, lmod(IntPoint(ts->u.d.value), G(L)->udt.size)); | 89 | G(L)->rootudata = u; |
| 101 | return ts; | 90 | return u; |
| 102 | } | ||
| 103 | |||
| 104 | |||
| 105 | int luaS_createudata (lua_State *L, void *udata, TObject *o) { | ||
| 106 | int h1 = lmod(IntPoint(udata), G(L)->udt.size); | ||
| 107 | TString *ts; | ||
| 108 | for (ts = G(L)->udt.hash[h1]; ts; ts = ts->nexthash) { | ||
| 109 | if (udata == ts->u.d.value) { | ||
| 110 | setuvalue(o, ts); | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | /* not found */ | ||
| 115 | setuvalue(o, luaS_newudata(L, 0, udata)); | ||
| 116 | return 1; | ||
| 117 | } | 91 | } |
| 118 | 92 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.h,v 1.30 2001/02/20 18:15:33 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.31 2001/02/23 17:17:25 roberto Exp roberto $ |
| 3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -14,6 +14,16 @@ | |||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | /* | 16 | /* |
| 17 | ** type equivalent to Udata, but with maximum alignment requirements | ||
| 18 | */ | ||
| 19 | union L_UUdata { | ||
| 20 | Udata u; | ||
| 21 | union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ | ||
| 22 | }; | ||
| 23 | |||
| 24 | |||
| 25 | |||
| 26 | /* | ||
| 17 | ** any TString with mark>=FIXMARK is never collected. | 27 | ** any TString with mark>=FIXMARK is never collected. |
| 18 | ** Marks>=RESERVEDMARK are used to identify reserved words. | 28 | ** Marks>=RESERVEDMARK are used to identify reserved words. |
| 19 | */ | 29 | */ |
| @@ -24,16 +34,14 @@ | |||
| 24 | #define sizestring(l) ((lu_mem)sizeof(union L_UTString)+ \ | 34 | #define sizestring(l) ((lu_mem)sizeof(union L_UTString)+ \ |
| 25 | ((lu_mem)(l)+1)*sizeof(l_char)) | 35 | ((lu_mem)(l)+1)*sizeof(l_char)) |
| 26 | 36 | ||
| 27 | #define sizeudata(l) ((lu_mem)sizeof(union L_UTString)+(l)) | 37 | #define sizeudata(l) ((lu_mem)sizeof(union L_UUdata)+(l)) |
| 28 | 38 | ||
| 29 | #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) | 39 | #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) |
| 30 | #define luaS_newliteral(L, s) (luaS_newlstr(L, l_s("") s, \ | 40 | #define luaS_newliteral(L, s) (luaS_newlstr(L, l_s("") s, \ |
| 31 | (sizeof(s)/sizeof(l_char))-1)) | 41 | (sizeof(s)/sizeof(l_char))-1)) |
| 32 | 42 | ||
| 33 | void luaS_init (lua_State *L); | 43 | void luaS_resize (lua_State *L, int newsize); |
| 34 | void luaS_resize (lua_State *L, stringtable *tb, int newsize); | 44 | Udata *luaS_newudata (lua_State *L, size_t s); |
| 35 | TString *luaS_newudata (lua_State *L, size_t s, void *udata); | ||
| 36 | int luaS_createudata (lua_State *L, void *udata, TObject *o); | ||
| 37 | void luaS_freeall (lua_State *L); | 45 | void luaS_freeall (lua_State *L); |
| 38 | TString *luaS_newlstr (lua_State *L, const l_char *str, size_t l); | 46 | TString *luaS_newlstr (lua_State *L, const l_char *str, size_t l); |
| 39 | 47 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 1.78 2001/03/26 14:31:49 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.79 2001/04/11 14:42:41 roberto Exp roberto $ |
| 3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -33,7 +33,7 @@ | |||
| 33 | 33 | ||
| 34 | 34 | ||
| 35 | #define hashnum(t,n) (&t->node[lmod((lu_hash)(ls_hash)(n), t->size)]) | 35 | #define hashnum(t,n) (&t->node[lmod((lu_hash)(ls_hash)(n), t->size)]) |
| 36 | #define hashstr(t,str) (&t->node[lmod((str)->u.s.hash, t->size)]) | 36 | #define hashstr(t,str) (&t->node[lmod((str)->hash, t->size)]) |
| 37 | #define hashpointer(t,p) (&t->node[lmod(IntPoint(p), t->size)]) | 37 | #define hashpointer(t,p) (&t->node[lmod(IntPoint(p), t->size)]) |
| 38 | 38 | ||
| 39 | 39 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 1.80 2001/04/23 16:35:45 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.81 2001/06/05 18:17:01 roberto Exp roberto $ |
| 3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -290,7 +290,7 @@ static int mem_query (lua_State *L) { | |||
| 290 | static int hash_query (lua_State *L) { | 290 | static int hash_query (lua_State *L) { |
| 291 | if (lua_isnull(L, 2)) { | 291 | if (lua_isnull(L, 2)) { |
| 292 | luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, l_s("string expected")); | 292 | luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, l_s("string expected")); |
| 293 | lua_pushnumber(L, tsvalue(luaA_index(L, 1))->u.s.hash); | 293 | lua_pushnumber(L, tsvalue(luaA_index(L, 1))->hash); |
| 294 | } | 294 | } |
| 295 | else { | 295 | else { |
| 296 | Hash *t; | 296 | Hash *t; |
| @@ -339,8 +339,7 @@ static int table_query (lua_State *L) { | |||
| 339 | 339 | ||
| 340 | 340 | ||
| 341 | static int string_query (lua_State *L) { | 341 | static int string_query (lua_State *L) { |
| 342 | stringtable *tb = (*luaL_check_string(L, 1) == l_c('s')) ? &G(L)->strt : | 342 | stringtable *tb = &G(L)->strt; |
| 343 | &G(L)->udt; | ||
| 344 | int s = luaL_opt_int(L, 2, 0) - 1; | 343 | int s = luaL_opt_int(L, 2, 0) - 1; |
| 345 | if (s==-1) { | 344 | if (s==-1) { |
| 346 | lua_pushnumber(L ,tb->nuse); | 345 | lua_pushnumber(L ,tb->nuse); |
| @@ -390,19 +389,22 @@ static int unref (lua_State *L) { | |||
| 390 | } | 389 | } |
| 391 | 390 | ||
| 392 | static int newuserdata (lua_State *L) { | 391 | static int newuserdata (lua_State *L) { |
| 393 | if (lua_isnumber(L, 2)) { | 392 | size_t size = luaL_check_int(L, 1); |
| 394 | int tag = luaL_check_int(L, 2); | 393 | l_char *p = (l_char *)lua_newuserdata(L, size); |
| 395 | int res = lua_pushuserdata(L, (void *)luaL_check_int(L, 1)); | 394 | while (size--) *p++ = l_c('\0'); |
| 396 | if (tag) lua_settag(L, tag); | 395 | return 1; |
| 397 | pushbool(L, res); | 396 | } |
| 398 | return 2; | 397 | |
| 399 | } | 398 | static int newuserdatabox (lua_State *L) { |
| 400 | else { | 399 | lua_newuserdatabox(L, (void *)luaL_check_int(L, 1)); |
| 401 | size_t size = luaL_check_int(L, 1); | 400 | return 1; |
| 402 | l_char *p = (l_char *)lua_newuserdata(L, size); | 401 | } |
| 403 | while (size--) *p++ = l_c('\0'); | 402 | |
| 404 | return 1; | 403 | static int settag (lua_State *L) { |
| 405 | } | 404 | luaL_checkany(L, 1); |
| 405 | lua_pushvalue(L, 1); /* push value */ | ||
| 406 | lua_settag(L, luaL_check_int(L, 2)); | ||
| 407 | return 1; /* return value */ | ||
| 406 | } | 408 | } |
| 407 | 409 | ||
| 408 | static int udataval (lua_State *L) { | 410 | static int udataval (lua_State *L) { |
| @@ -691,6 +693,8 @@ static const struct luaL_reg tests_funcs[] = { | |||
| 691 | {l_s("d2s"), d2s}, | 693 | {l_s("d2s"), d2s}, |
| 692 | {l_s("s2d"), s2d}, | 694 | {l_s("s2d"), s2d}, |
| 693 | {l_s("newuserdata"), newuserdata}, | 695 | {l_s("newuserdata"), newuserdata}, |
| 696 | {l_s("newuserdatabox"), newuserdatabox}, | ||
| 697 | {l_s("settag"), settag}, | ||
| 694 | {l_s("udataval"), udataval}, | 698 | {l_s("udataval"), udataval}, |
| 695 | {l_s("newtag"), newtag}, | 699 | {l_s("newtag"), newtag}, |
| 696 | {l_s("doonnewstack"), doonnewstack}, | 700 | {l_s("doonnewstack"), doonnewstack}, |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 1.70 2001/03/02 17:27:50 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 1.71 2001/03/26 14:31:49 roberto Exp roberto $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -127,7 +127,7 @@ LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) { | |||
| 127 | int luaT_tag (const TObject *o) { | 127 | int luaT_tag (const TObject *o) { |
| 128 | int t = ttype(o); | 128 | int t = ttype(o); |
| 129 | switch (t) { | 129 | switch (t) { |
| 130 | case LUA_TUSERDATA: return tsvalue(o)->u.d.tag; | 130 | case LUA_TUSERDATA: return uvalue(o)->tag; |
| 131 | case LUA_TTABLE: return hvalue(o)->htag; | 131 | case LUA_TTABLE: return hvalue(o)->htag; |
| 132 | default: return t; | 132 | default: return t; |
| 133 | } | 133 | } |
| @@ -140,7 +140,7 @@ const l_char *luaT_typename (global_State *G, const TObject *o) { | |||
| 140 | TString *ts; | 140 | TString *ts; |
| 141 | switch (t) { | 141 | switch (t) { |
| 142 | case LUA_TUSERDATA: | 142 | case LUA_TUSERDATA: |
| 143 | tag = tsvalue(o)->u.d.tag; | 143 | tag = uvalue(o)->tag; |
| 144 | break; | 144 | break; |
| 145 | case LUA_TTABLE: | 145 | case LUA_TTABLE: |
| 146 | tag = hvalue(o)->htag; | 146 | tag = hvalue(o)->htag; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.h,v 1.23 2001/02/09 20:22:29 roberto Exp roberto $ | 2 | ** $Id: ltm.h,v 1.24 2001/02/23 17:17:25 roberto Exp roberto $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -53,7 +53,7 @@ typedef enum { | |||
| 53 | 53 | ||
| 54 | struct TM { | 54 | struct TM { |
| 55 | Closure *method[TM_N]; | 55 | Closure *method[TM_N]; |
| 56 | TString *collected; /* list of garbage-collected udata with this tag */ | 56 | Udata *collected; /* list of garbage-collected udata with this tag */ |
| 57 | TString *name; /* type name */ | 57 | TString *name; /* type name */ |
| 58 | int basictype; | 58 | int basictype; |
| 59 | }; | 59 | }; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.c,v 1.65 2001/03/09 18:05:05 roberto Exp roberto $ | 2 | ** $Id: lua.c,v 1.66 2001/03/26 14:31:49 roberto Exp roberto $ |
| 3 | ** Lua stand-alone interpreter | 3 | ** Lua stand-alone interpreter |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -308,7 +308,7 @@ static void getstacksize (int argc, l_char *argv[], struct Options *opt) { | |||
| 308 | 308 | ||
| 309 | 309 | ||
| 310 | static void register_getargs (l_char *argv[]) { | 310 | static void register_getargs (l_char *argv[]) { |
| 311 | lua_pushuserdata(L, argv); | 311 | lua_newuserdatabox(L, argv); |
| 312 | lua_pushcclosure(L, l_getargs, 1); | 312 | lua_pushcclosure(L, l_getargs, 1); |
| 313 | lua_setglobal(L, l_s("getargs")); | 313 | lua_setglobal(L, l_s("getargs")); |
| 314 | } | 314 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.96 2001/04/17 17:35:54 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.97 2001/04/23 16:35:45 roberto Exp roberto $ |
| 3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
| 4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil | 4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil |
| 5 | ** e-mail: info@lua.org | 5 | ** e-mail: info@lua.org |
| @@ -150,7 +150,6 @@ LUA_API void lua_pushnumber (lua_State *L, lua_Number n); | |||
| 150 | LUA_API void lua_pushlstring (lua_State *L, const lua_char *s, size_t len); | 150 | LUA_API void lua_pushlstring (lua_State *L, const lua_char *s, size_t len); |
| 151 | LUA_API void lua_pushstring (lua_State *L, const lua_char *s); | 151 | LUA_API void lua_pushstring (lua_State *L, const lua_char *s); |
| 152 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); | 152 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); |
| 153 | LUA_API int lua_pushuserdata (lua_State *L, void *u); | ||
| 154 | 153 | ||
| 155 | 154 | ||
| 156 | /* | 155 | /* |
| @@ -218,6 +217,7 @@ LUA_API int lua_getn (lua_State *L, int index); | |||
| 218 | LUA_API void lua_concat (lua_State *L, int n); | 217 | LUA_API void lua_concat (lua_State *L, int n); |
| 219 | 218 | ||
| 220 | LUA_API void *lua_newuserdata (lua_State *L, size_t size); | 219 | LUA_API void *lua_newuserdata (lua_State *L, size_t size); |
| 220 | LUA_API void lua_newuserdatabox (lua_State *L, void *u); | ||
| 221 | 221 | ||
| 222 | LUA_API void lua_setweakmode (lua_State *L, int mode); | 222 | LUA_API void lua_setweakmode (lua_State *L, int mode); |
| 223 | LUA_API int lua_getweakmode (lua_State *L, int index); | 223 | LUA_API int lua_getweakmode (lua_State *L, int index); |
